import { SignJWT, jwtVerify } from 'jose';
import bcrypt from 'bcryptjs';

// Astro dev (Vite) expose les .env via import.meta.env ; Node runtime prod via process.env.
// On lit les deux pour couvrir tous les cas (dev, preview, prod Plesk Node).
const env = {
  ...(typeof process !== 'undefined' ? process.env : {}),
  ...(import.meta.env as Record<string, string | undefined>),
};

const ADMIN_PASSWORD_HASH = (env.ADMIN_PASSWORD_HASH as string | undefined) ?? '';
const JWT_SECRET = (env.ADMIN_JWT_SECRET as string | undefined) ?? '';

// Lazy : on ne throw pas au chargement du module (Astro build importe ce fichier
// en SSR sans forcément avoir le .env). On throw au premier usage runtime.
let cachedKey: Uint8Array | null = null;
function getSecretKey(): Uint8Array {
  if (cachedKey) return cachedKey;
  if (!JWT_SECRET || JWT_SECRET.length < 32) {
    throw new Error(
      '[auth] ADMIN_JWT_SECRET manquant ou trop court (>= 32 chars). ' +
        'Générer via `npm run hash:password -- <motdepasse>` et reporter dans .env.',
    );
  }
  cachedKey = new TextEncoder().encode(JWT_SECRET);
  return cachedKey;
}

export const ADMIN_COOKIE = 'portfolio_admin';

export async function verifyPassword(password: string): Promise<boolean> {
  if (!ADMIN_PASSWORD_HASH) {
    console.error('[auth] ADMIN_PASSWORD_HASH manquant dans .env');
    return false;
  }
  return bcrypt.compare(password, ADMIN_PASSWORD_HASH);
}

export async function createSession(): Promise<string> {
  return new SignJWT({ role: 'admin' })
    .setProtectedHeader({ alg: 'HS256' })
    .setIssuedAt()
    .setExpirationTime('7d')
    .sign(getSecretKey());
}

export async function verifySession(token: string | undefined): Promise<boolean> {
  if (!token) return false;
  try {
    await jwtVerify(token, getSecretKey());
    return true;
  } catch {
    return false;
  }
}

export function hashPasswordCLI(password: string): string {
  return bcrypt.hashSync(password, 12);
}
