import jwt from "jsonwebtoken";
import { pool } from "../config/db.js";
import { EXECUTOR_VERIFIER_ROLE_ID, ROLE_IDS } from "../constants/hseRoles.js";
import { ApiError } from "../utils/ApiError.js";

function normalizeRole(roleName) {
  return String(roleName || "")
    .trim()
    .toLowerCase()
    .replace(/\s*\/\s*/g, "/");
}

function getSecretForRole(normalizedRole) {
  const userRole = normalizeRole(process.env.JWT_USER_ROLE || "user");
  const adminRole = normalizeRole(process.env.JWT_ADMIN_ROLE || "admin");
  const executorRole = normalizeRole(
    process.env.JWT_EXECUTOR_ROLE || "executer/varifier"
  );
  const supportRole = normalizeRole(process.env.JWT_SUPPORT_ROLE || "support");

  if (normalizedRole === userRole) {
    return {
      secret: process.env.JWT_USER_SECRET,
      envName: "JWT_USER_SECRET"
    };
  }

  if (normalizedRole === adminRole) {
    return {
      secret: process.env.JWT_ADMIN_SECRET,
      envName: "JWT_ADMIN_SECRET"
    };
  }

  if (normalizedRole === executorRole) {
    return {
      secret: process.env.JWT_EXECUTOR_SECRET,
      envName: "JWT_EXECUTOR_SECRET"
    };
  }

  if (normalizedRole === supportRole) {
    return {
      secret: process.env.JWT_USER_SECRET,
      envName: "JWT_USER_SECRET"
    };
  }

  return null;
}

export async function login(req, res, next) {
  try {
    const email = String(req.body?.email ?? "").trim();
    const password = String(req.body?.password ?? "");

    if (!email || !password) {
      throw new ApiError(400, "Email and password are required");
    }

    const [rows] = await pool.query(
      `SELECT
         u.user_id,
         u.employee_name,
         u.email_id,
         u.password,
         r.role_id,
         r.role_name
       FROM users u
       LEFT JOIN user_role ur ON ur.user_id = u.user_id
       LEFT JOIN roles r ON r.role_id = ur.role_id
       WHERE LOWER(TRIM(u.email_id)) = LOWER(?)
       ORDER BY CASE
         WHEN r.role_id = ${ROLE_IDS.ADMIN} THEN 0
         WHEN r.role_id = ${EXECUTOR_VERIFIER_ROLE_ID} THEN 1
         WHEN r.role_id = ${ROLE_IDS.USER} THEN 2
         WHEN r.role_id = ${ROLE_IDS.SUPPORT} THEN 3
         ELSE 4
       END,
                r.role_id ASC
       LIMIT 1`,
      [email]
    );

    if (!rows.length) {
      throw new ApiError(401, "Invalid email or password");
    }

    const user = rows[0];
    const storedPassword = String(user.password ?? "").trim();
    if (!storedPassword || storedPassword !== password) {
      throw new ApiError(401, "Invalid email or password");
    }

    const normalizedRole = normalizeRole(user.role_name);
    const roleSecretConfig = getSecretForRole(normalizedRole);

    if (!roleSecretConfig) {
      throw new ApiError(403, "Role is not allowed to sign in");
    }

    if (!roleSecretConfig.secret) {
      throw new ApiError(500, `${roleSecretConfig.envName} is not configured`);
    }

    const tokenPayload = {
      user_id: user.user_id,
      email: user.email_id,
      name: user.employee_name,
      role: user.role_name,
      role_id: user.role_id
    };

    const token = jwt.sign(tokenPayload, roleSecretConfig.secret, {
      expiresIn: process.env.JWT_EXPIRES_IN || "1d",
      issuer: process.env.JWT_ISSUER || "orac-risk-api"
    });

    res.json({
      token,
      tokenType: "Bearer",
      role: normalizedRole,
      user: {
        user_id: user.user_id,
        employee_name: user.employee_name,
        email_id: user.email_id,
        role_id: user.role_id,
        role_name: user.role_name
      }
    });
  } catch (err) {
    next(err);
  }
}
