import bcrypt from "bcryptjs";
import { getDb } from "../config/db.js";
import { logAction } from "../utils/audit.helper.js";
import { applicationStatus, roles } from "../utils/constants.js";

export const listApplications = async (_req, res) => {
  const db = getDb();
  const [rows] = await db.execute(
    `SELECT id, name, region, district, category, applicant_name, applicant_email, applicant_phone, license_file, status, created_at, issued_username, registration_type, issued_date, expired_date
     FROM notary_applications
     ORDER BY created_at DESC`
  );
  res.json(rows);
};

export const createApplication = async (req, res) => {
  const db = getDb();
  const { name, region, district, category, applicant_name, applicant_email, applicant_phone, license_file, registration_type, issued_date, expired_date } = req.body;

  const [result] = await db.execute(
    `INSERT INTO notary_applications (name, region, district, category, applicant_name, applicant_email, applicant_phone, license_file, registration_type, issued_date, expired_date, status)
     VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
    [name, region, district, category, applicant_name, applicant_email, applicant_phone, license_file, registration_type, issued_date, expired_date, applicationStatus.PENDING]
  );

  res.status(201).json({ 
    id: result.insertId, 
    name, region, district, category, applicant_name, applicant_email, applicant_phone, license_file, 
    registration_type, issued_date, expired_date,
    status: applicationStatus.PENDING 
  });
};

export const reviewApplication = async (req, res) => {
  const db = getDb();
  const applicationId = Number(req.params.id);
  const { status } = req.body;

  const [rows] = await db.execute(
    `SELECT * FROM notary_applications WHERE id = ?`,
    [applicationId]
  );
  const application = rows[0];

  if (!application) {
    return res.status(404).json({ message: "Application not found" });
  }

  // Update application status
  await db.execute(`UPDATE notary_applications SET status = ? WHERE id = ?`, [status, applicationId]);

  await logAction(req.user.id, status === 'active' ? "APPROVE_APPLICATION" : "REJECT_APPLICATION", `${status === 'active' ? 'Approved' : 'Rejected'} application for ${application.name} (ID: ${applicationId})`);

  let credentials = null;

  if (status === applicationStatus.ACTIVE && application.status !== applicationStatus.ACTIVE) {
    // 1. Create the notary record
    const [notaryResult] = await db.execute(
      `INSERT INTO notaries (name, region, district, category, registration_type, issued_date, expired_date, status)
       VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
      [application.name, application.region, application.district, application.category, application.registration_type, application.issued_date, application.expired_date, applicationStatus.ACTIVE]
    );
    const notaryId = notaryResult.insertId;

    // 2. Create the owner user
    const tempPassword = Math.random().toString(36).slice(-8);
    const passwordHash = await bcrypt.hash(tempPassword, 10);
    
    // Generate staff ID code for the owner
    const [[maxRow]] = await db.execute("SELECT MAX(id) as maxId FROM users");
    const nextId = (maxRow.maxId || 0) + 1;
    const staffIdCode = `NESOS-${new Date().getFullYear()}-${String(nextId).padStart(4, '0')}`;

    const [userResult] = await db.execute(
      `INSERT INTO users (notary_id, name, email, password_hash, role, staff_id_code, password_must_change)
       VALUES (?, ?, ?, ?, ?, ?, 1)`,
      [notaryId, application.applicant_name, application.applicant_email, passwordHash, roles.OWNER, staffIdCode]
    );
    const userId = userResult.insertId;

    // 3. Link owner to notary
    await db.execute(`UPDATE notaries SET owner_user_id = ? WHERE id = ?`, [userId, notaryId]);

    // 4. Update application with issued username
    await db.execute(`UPDATE notary_applications SET issued_username = ? WHERE id = ?`, [application.applicant_email, applicationId]);

    credentials = {
      owner_name: application.applicant_name,
      username: application.applicant_email,
      temporary_password: tempPassword
    };
  }

  return res.json({ 
    ...application, 
    status, 
    credentials 
  });
};
