import crypto from "crypto";

const JWT_SECRET = process.env.JWT_SECRET || "laundry_secret_key_123456";

export function hashPassword(password) {
  return crypto.createHash("sha256").update(password).digest("hex");
}

export function generateToken(user) {
  const header = Buffer.from(JSON.stringify({ alg: "HS256", typ: "JWT" })).toString("base64url");
  const payload = Buffer.from(JSON.stringify({ id: user.id, username: user.username, role: user.role })).toString("base64url");
  const signature = crypto.createHmac("sha256", JWT_SECRET).update(`${header}.${payload}`).digest("base64url");
  return `${header}.${payload}.${signature}`;
}

export function verifyToken(token) {
  try {
    const [header, payload, signature] = token.split(".");
    const expectedSignature = crypto.createHmac("sha256", JWT_SECRET).update(`${header}.${payload}`).digest("base64url");
    if (signature !== expectedSignature) return null;
    return JSON.parse(Buffer.from(payload, "base64url").toString());
  } catch (err) {
    return null;
  }
}

export function requireAuth(req, res, next) {
  try {
    const authHeader = req.headers.authorization;
    if (!authHeader || !authHeader.startsWith("Bearer ")) {
      return res.status(401).json({
        success: false,
        message: "No autorizado. Sesión no encontrada."
      });
    }

    const token = authHeader.split(" ")[1];
    const decoded = verifyToken(token);
    if (!decoded) {
      return res.status(401).json({
        success: false,
        message: "Sesión inválida o expirada."
      });
    }

    req.user = decoded;
    next();
  } catch (err) {
    next(err);
  }
}

export function requireAdmin(req, res, next) {
  if (!req.user || req.user.role !== "admin") {
    return res.status(403).json({
      success: false,
      message: "Acceso denegado. Permisos de administrador requeridos."
    });
  }
  next();
}

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

const PERMISSIONS = {
  admin: "*",
  manager: {
    dashboard: ["view"],
    customers: ["view", "create", "edit"],
    orders: ["view", "create", "edit"],
    services: ["view", "create", "edit"],
    pickup: ["view", "edit"],
    delivery: ["view", "edit"],
    cash: ["view", "create", "edit"],
    inventory: ["view", "create", "edit"],
    suppliers: ["view", "create", "edit"],
    trends: ["view"],
    reports: ["view"],
    loyalty: ["view", "create", "edit"],
    users: [],
    roles: [],
    settings: []
  },
  cashier: {
    dashboard: ["view"],
    customers: ["view", "create"],
    orders: ["view", "create", "edit"],
    services: ["view"],
    pickup: ["view"],
    delivery: ["view"],
    cash: ["view", "create", "edit"],
    inventory: [],
    suppliers: [],
    trends: [],
    reports: [],
    loyalty: [],
    users: [],
    roles: [],
    settings: []
  },
  user: {
    dashboard: ["view"],
    customers: ["view"],
    orders: ["view"],
    services: ["view"],
    pickup: ["view"],
    delivery: ["view"],
    cash: [],
    inventory: [],
    suppliers: [],
    trends: [],
    reports: [],
    loyalty: [],
    users: [],
    roles: [],
    settings: []
  }
};

function normalizeRole(role) {
  return ROLE_ALIASES[role] || role || "user";
}

export function requirePermission(moduleId, action = "view") {
  return (req, res, next) => {
    const role = normalizeRole(req.user?.role);
    const permissions = PERMISSIONS[role];
    if (permissions === "*" || permissions?.[moduleId]?.includes(action)) {
      return next();
    }
    return res.status(403).json({
      success: false,
      message: "Acceso denegado. No tienes permisos para esta accion."
    });
  };
}
