import { createHmac, pbkdf2Sync, randomBytes, timingSafeEqual } from "node:crypto";
import { cookies } from "next/headers";
import { getDbPool } from "@/db";
import { ensureCapitalTenant } from "@/lib/tenant";

const COOKIE = "autovistoria_session";
export const SUPPORT_COOKIE = "autovistoria_support_tenant";
type Role = "capital_admin" | "capital_operator" | "analyst" | "client_admin" | "client_manager" | "integration_user";
export type Session = { userId: string; tenantId: string | null; name: string; email: string; role: Role; exp: number };
export type SupportSession = { tenantId: string; operatorId: string; operatorName: string; exp: number; mode: "capital_support" };
const secret = () => process.env.APP_SECRET || "troque-esta-chave-em-producao";
export const hashPassword = (password: string) => { const salt = randomBytes(16).toString("hex"); const hash = pbkdf2Sync(password, salt, 120000, 32, "sha256").toString("hex"); return `pbkdf2$120000$${salt}$${hash}`; };
export const verifyPassword = (password: string, saved: string) => { const [kind, rounds, salt, hash] = saved.split("$"); if (kind !== "pbkdf2" || !rounds || !salt || !hash) return false; const candidate = pbkdf2Sync(password, salt, Number(rounds), 32, "sha256").toString("hex"); return timingSafeEqual(Buffer.from(candidate), Buffer.from(hash)); };
export const signSession = (session: Omit<Session, "exp">) => { const payload = Buffer.from(JSON.stringify({ ...session, exp: Date.now() + 1000 * 60 * 60 * 12 })).toString("base64url"); return `${payload}.${createHmac("sha256", secret()).update(payload).digest("base64url")}`; };
export const readSessionValue = (value?: string) => { if (!value) return null; const [payload, signature] = value.split("."); if (!payload || !signature) return null; const expected = createHmac("sha256", secret()).update(payload).digest("base64url"); if (signature !== expected) return null; try { const session = JSON.parse(Buffer.from(payload, "base64url").toString()) as Session; return session.exp > Date.now() ? session : null; } catch { return null; } };
export const getSession = async () => readSessionValue((await cookies()).get(COOKIE)?.value);
export const sessionCookie = (token: string) => ({ name: COOKIE, value: token, httpOnly: true, secure: process.env.NODE_ENV === "production", sameSite: "lax" as const, path: "/", maxAge: 60 * 60 * 12 });
export const signSupportSession = (session: Session, tenantId: string) => {
  const payload = Buffer.from(JSON.stringify({ tenantId, operatorId: session.userId, operatorName: session.name, mode: "capital_support", exp: Date.now() + 1000 * 60 * 60 })).toString("base64url");
  return `${payload}.${createHmac("sha256", secret()).update(payload).digest("base64url")}`;
};
export const readSupportSessionValue = (value?: string) => {
  if (!value) return null; const [payload, signature] = value.split("."); if (!payload || !signature) return null;
  const expected = createHmac("sha256", secret()).update(payload).digest("base64url"); if (signature !== expected) return null;
  try { const support = JSON.parse(Buffer.from(payload, "base64url").toString()) as SupportSession; return support.mode === "capital_support" && support.exp > Date.now() ? support : null; } catch { return null; }
};
export const getSupportSession = async () => readSupportSessionValue((await cookies()).get(SUPPORT_COOKIE)?.value);
export const supportSessionCookie = (token: string) => ({ name: SUPPORT_COOKIE, value: token, httpOnly: true, secure: process.env.NODE_ENV === "production", sameSite: "lax" as const, path: "/", maxAge: 60 * 60 });
export async function ensureBootstrapAdmin() { const email = process.env.INITIAL_ADMIN_EMAIL; const password = process.env.INITIAL_ADMIN_PASSWORD; if (!email || !password) return; const db = getDbPool(); const tenantId = await ensureCapitalTenant(); const [rows] = await db.execute("SELECT id FROM users WHERE email = ? LIMIT 1", [email.toLowerCase()]); if ((rows as unknown[]).length) return; await db.execute("INSERT INTO users (id, tenant_id, name, email, password_hash, role) VALUES (UUID(), ?, 'Administrador Capital', ?, ?, 'capital_admin')", [tenantId, email.toLowerCase(), hashPassword(password)]); }
