import { pool } from "../config/db.js";
import { hashPassword } from "../middleware/auth.js";

const ROLE_ALIASES = {
  administrador: "admin",
  gerente: "manager",
  cajero: "cashier",
  usuario: "user"
};

const VALID_ROLES = new Set(["admin", "manager", "cashier", "user"]);

function normalizeRole(role, fallback = "user") {
  const normalized = ROLE_ALIASES[String(role || "").toLowerCase()] || String(role || fallback).toLowerCase();
  return VALID_ROLES.has(normalized) ? normalized : fallback;
}

function mapUser(row) {
  return {
    id: row.id,
    username: row.username,
    role: row.role,
    fullName: row.full_name,
    email: row.email,
    phone: row.phone,
    status: row.status,
    createdAt: row.created_at,
    updatedAt: row.updated_at
  };
}

export async function getUsers(req, res, next) {
  try {
    const { search = "" } = req.query;
    let query = "SELECT * FROM users";
    const params = [];

    if (search.trim()) {
      query += " WHERE username LIKE ? OR full_name LIKE ? OR email LIKE ?";
      const searchWild = `%${search.trim()}%`;
      params.push(searchWild, searchWild, searchWild);
    }

    query += " ORDER BY id DESC";
    const [rows] = await pool.query(query, params);

    res.json({
      success: true,
      data: rows.map(mapUser)
    });
  } catch (err) {
    next(err);
  }
}

export async function getUserById(req, res, next) {
  try {
    const { id } = req.params;
    const [rows] = await pool.query("SELECT * FROM users WHERE id = ?", [id]);

    if (!rows.length) {
      return res.status(404).json({
        success: false,
        message: "Usuario no encontrado"
      });
    }

    res.json({
      success: true,
      data: mapUser(rows[0])
    });
  } catch (err) {
    next(err);
  }
}

export async function createUser(req, res, next) {
  try {
    const { username, password, role, fullName, email, phone, status = "active" } = req.body;
    const normalizedRole = normalizeRole(role);

    if (!username || !password || !role) {
      return res.status(400).json({
        success: false,
        message: "Usuario, contraseña y rol son requeridos"
      });
    }

    // Check if username exists
    const [existing] = await pool.query("SELECT id FROM users WHERE username = ?", [username.trim()]);
    if (existing.length > 0) {
      return res.status(400).json({
        success: false,
        message: "El nombre de usuario ya está registrado"
      });
    }

    const hashedPassword = hashPassword(password);
    
    // Insert new user
    const [result] = await pool.query(
      `
      INSERT INTO users (username, password, role, full_name, email, phone, status, created_at, updated_at)
      VALUES (?, ?, ?, ?, ?, ?, ?, NOW(), NOW())
      `,
      [username.trim(), hashedPassword, normalizedRole, fullName || null, email || null, phone || null, status]
    );

    res.status(201).json({
      success: true,
      message: "Usuario creado correctamente",
      data: {
        id: result.insertId,
        username,
        role: normalizedRole
      }
    });
  } catch (err) {
    next(err);
  }
}

export async function updateUser(req, res, next) {
  try {
    const { id } = req.params;
    const { username, password, role, fullName, email, phone, status } = req.body;

    // Check if user exists
    const [existing] = await pool.query("SELECT * FROM users WHERE id = ?", [id]);
    if (!existing.length) {
      return res.status(404).json({
        success: false,
        message: "Usuario no encontrado"
      });
    }

    // Check username conflict if changed
    if (username && username.trim() !== existing[0].username) {
      const [conflict] = await pool.query("SELECT id FROM users WHERE username = ? AND id != ?", [username.trim(), id]);
      if (conflict.length > 0) {
        return res.status(400).json({
          success: false,
          message: "El nombre de usuario ya está registrado por otra cuenta"
        });
      }
    }

    let query = `
      UPDATE users
      SET username = ?,
          role = ?,
          full_name = ?,
          email = ?,
          phone = ?,
          status = ?,
          updated_at = NOW()
    `;
    const params = [
      username ? username.trim() : existing[0].username,
      role ? normalizeRole(role, existing[0].role) : existing[0].role,
      fullName !== undefined ? fullName : existing[0].full_name,
      email !== undefined ? email : existing[0].email,
      phone !== undefined ? phone : existing[0].phone,
      status || existing[0].status
    ];

    if (password) {
      query += ", password = ?";
      params.push(hashPassword(password));
    }

    query += " WHERE id = ?";
    params.push(id);

    await pool.query(query, params);
    const [updated] = await pool.query("SELECT * FROM users WHERE id = ?", [id]);

    res.json({
      success: true,
      message: "Usuario actualizado correctamente",
      data: updated.length ? mapUser(updated[0]) : null
    });
  } catch (err) {
    next(err);
  }
}

export async function deleteUser(req, res, next) {
  try {
    const { id } = req.params;

    // Cannot delete yourself
    if (Number(req.user.id) === Number(id)) {
      return res.status(400).json({
        success: false,
        message: "No puedes eliminar tu propio usuario en sesión"
      });
    }

    const [existing] = await pool.query("SELECT id FROM users WHERE id = ?", [id]);
    if (!existing.length) {
      return res.status(404).json({
        success: false,
        message: "Usuario no encontrado"
      });
    }

    await pool.query("DELETE FROM users WHERE id = ?", [id]);

    res.json({
      success: true,
      message: "Usuario eliminado correctamente"
    });
  } catch (err) {
    next(err);
  }
}
