const { pool } = require("../../config/db");

/* ===========================
   ✅ CREATE ROLE
=========================== */
const createRole = async (req, res) => {
  try {
    const org_id = req.session.user.orgId;
    const userId = req.session.user.id;

    const { role_name, description, permissions } = req.body;

    if (!role_name) {
      return res.status(400).json({
        success: false,
        message: "Role name is required",
      });
    }

    // Check duplicate
    const existing = await pool.query(
      `SELECT id FROM roles WHERE role_name = $1 AND org_id = $2 AND is_deleted = false`,
      [role_name.trim(), org_id]
    );

    if (existing.rows.length > 0) {
      return res.status(409).json({
        success: false,
        message: "Role with this name already exists",
      });
    }

    const result = await pool.query(
      `INSERT INTO roles (role_name, description, permissions, org_id, created_by)
       VALUES ($1, $2, $3, $4, $5)
       RETURNING *`,
      [
        role_name.trim(),
        description || null,
        JSON.stringify(permissions || []),
        org_id,
        userId,
      ]
    );

    res.status(201).json({
      success: true,
      message: "Role created successfully",
      data: result.rows[0],
    });
  } catch (err) {
    console.error("CREATE ROLE ERROR:", err);
    res.status(500).json({ success: false, message: err.message });
  }
};

/* ===========================
   ✅ GET ALL ROLES
=========================== */
const getAllRoles = async (req, res) => {
  try {
    const org_id = req.session.user.orgId;

    const result = await pool.query(
      `SELECT 
         r.*,
         CONCAT(u.first_name, ' ', u.last_name) AS created_by_name
       FROM roles r
       LEFT JOIN users u ON u.id = r.created_by
       WHERE r.org_id = $1 AND r.is_deleted = false
       ORDER BY r.created_at DESC`,
      [org_id]
    );

    res.json({
      success: true,
      data: result.rows,
      totalRecords: result.rows.length,
    });
  } catch (err) {
    console.error("GET ALL ROLES ERROR:", err);
    res.status(500).json({ success: false, message: err.message });
  }
};

/* ===========================
   ✅ GET ROLE BY ID
=========================== */
const getRoleById = async (req, res) => {
  try {
    const { id } = req.params;
    const org_id = req.session.user.orgId;

    const result = await pool.query(
      `SELECT 
         r.*,
         CONCAT(u.first_name, ' ', u.last_name) AS created_by_name
       FROM roles r
       LEFT JOIN users u ON u.id = r.created_by
       WHERE r.id = $1 AND r.org_id = $2 AND r.is_deleted = false`,
      [id, org_id]
    );

    if (!result.rows.length) {
      return res.status(404).json({
        success: false,
        message: "Role not found",
      });
    }

    res.json({ success: true, data: result.rows[0] });
  } catch (err) {
    console.error("GET ROLE BY ID ERROR:", err);
    res.status(500).json({ success: false, message: err.message });
  }
};

/* ===========================
   ✅ UPDATE ROLE
=========================== */
const updateRole = async (req, res) => {
  try {
    const { id } = req.params;
    const org_id = req.session.user.orgId;
    const userId = req.session.user.id;

    const { role_name, description, permissions, is_active } = req.body;

    // Check duplicate name (exclude current)
    if (role_name) {
      const existing = await pool.query(
        `SELECT id FROM roles 
         WHERE role_name = $1 AND org_id = $2 AND is_deleted = false AND id != $3`,
        [role_name.trim(), org_id, id]
      );
      if (existing.rows.length > 0) {
        return res.status(409).json({
          success: false,
          message: "Another role with this name already exists",
        });
      }
    }

    const result = await pool.query(
      `UPDATE roles
       SET
         role_name   = COALESCE($1, role_name),
         description = COALESCE($2, description),
         permissions = COALESCE($3, permissions),
         is_active   = COALESCE($4, is_active),
         updated_by  = $5,
         updated_at  = NOW()
       WHERE id = $6 AND org_id = $7 AND is_deleted = false
       RETURNING *`,
      [
        role_name ? role_name.trim() : null,
        description ?? null,
        permissions ? JSON.stringify(permissions) : null,
        is_active ?? null,
        userId,
        id,
        org_id,
      ]
    );

    if (!result.rows.length) {
      return res.status(404).json({
        success: false,
        message: "Role not found",
      });
    }

    res.json({
      success: true,
      message: "Role updated successfully",
      data: result.rows[0],
    });
  } catch (err) {
    console.error("UPDATE ROLE ERROR:", err);
    res.status(500).json({ success: false, message: err.message });
  }
};

/* ===========================
   ✅ DELETE ROLE (SOFT)
=========================== */
const deleteRole = async (req, res) => {
  try {
    const { id } = req.params;
    const org_id = req.session.user.orgId;
    const userId = req.session.user.id;

    // Check if role is assigned to any active user
    const inUse = await pool.query(
      `SELECT COUNT(*) FROM users 
       WHERE role = (SELECT role_name FROM roles WHERE id = $1)
         AND org_id = $2 
         AND is_deleted = false`,
      [id, org_id]
    );

    if (parseInt(inUse.rows[0].count) > 0) {
      return res.status(400).json({
        success: false,
        message: `Cannot delete — this role is assigned to ${inUse.rows[0].count} active user(s)`,
      });
    }

    const result = await pool.query(
      `UPDATE roles
       SET is_deleted = true, updated_by = $1, updated_at = NOW()
       WHERE id = $2 AND org_id = $3 AND is_deleted = false
       RETURNING id`,
      [userId, id, org_id]
    );

    if (!result.rows.length) {
      return res.status(404).json({
        success: false,
        message: "Role not found",
      });
    }

    res.json({ success: true, message: "Role deleted successfully" });
  } catch (err) {
    console.error("DELETE ROLE ERROR:", err);
    res.status(500).json({ success: false, message: err.message });
  }
};

/* ===========================
   ✅ TOGGLE ROLE STATUS
=========================== */
const toggleRoleStatus = async (req, res) => {
  try {
    const { id } = req.params;
    const org_id = req.session.user.orgId;
    const userId = req.session.user.id;

    const result = await pool.query(
      `UPDATE roles
       SET is_active = NOT is_active, updated_by = $1, updated_at = NOW()
       WHERE id = $2 AND org_id = $3 AND is_deleted = false
       RETURNING id, role_name, is_active`,
      [userId, id, org_id]
    );

    if (!result.rows.length) {
      return res.status(404).json({
        success: false,
        message: "Role not found",
      });
    }

    res.json({
      success: true,
      message: `Role ${result.rows[0].is_active ? "activated" : "deactivated"} successfully`,
      data: result.rows[0],
    });
  } catch (err) {
    console.error("TOGGLE ROLE STATUS ERROR:", err);
    res.status(500).json({ success: false, message: err.message });
  }
};

module.exports = {
  createRole,
  getAllRoles,
  getRoleById,
  updateRole,
  deleteRole,
  toggleRoleStatus,
};