import crypto from 'crypto';
import { ADMIN_PASSWORD } from '../config.js';

const ADMIN_COOKIE = 'ff_admin_session';
const SESSION_TTL_MS = 12 * 60 * 60 * 1000;

function parseCookies(header = '') {
  return header
    .split(';')
    .map(part => part.trim())
    .filter(Boolean)
    .reduce((acc, part) => {
      const eqIndex = part.indexOf('=');
      if (eqIndex === -1) return acc;
      const key = part.slice(0, eqIndex).trim();
      const value = part.slice(eqIndex + 1).trim();
      acc[key] = decodeURIComponent(value);
      return acc;
    }, {});
}

function safeEqual(a, b) {
  const left = Buffer.from(String(a ?? ''));
  const right = Buffer.from(String(b ?? ''));
  if (left.length !== right.length) return false;
  return crypto.timingSafeEqual(left, right);
}

function sign(payload) {
  return crypto.createHmac('sha256', ADMIN_PASSWORD).update(payload).digest('base64url');
}

function getCookieOptions() {
  return {
    httpOnly: true,
    sameSite: 'lax',
    secure: false,
    path: '/',
    maxAge: SESSION_TTL_MS,
  };
}

export function isAdminConfigured() {
  return Boolean(ADMIN_PASSWORD);
}

export function verifyAdminPassword(password) {
  if (!isAdminConfigured()) return false;
  return safeEqual(password, ADMIN_PASSWORD);
}

export function createAdminSessionValue() {
  const payload = Buffer.from(JSON.stringify({ exp: Date.now() + SESSION_TTL_MS }), 'utf-8').toString('base64url');
  return `${payload}.${sign(payload)}`;
}

export function setAdminSession(res) {
  res.cookie(ADMIN_COOKIE, createAdminSessionValue(), getCookieOptions());
}

export function clearAdminSession(res) {
  res.clearCookie(ADMIN_COOKIE, getCookieOptions());
}

export function isAdminAuthenticated(req) {
  if (!isAdminConfigured()) return false;
  const cookies = parseCookies(req.headers.cookie || '');
  const raw = cookies[ADMIN_COOKIE];
  if (!raw) return false;
  const [payload, signature] = raw.split('.');
  if (!payload || !signature) return false;
  if (!safeEqual(sign(payload), signature)) return false;

  try {
    const session = JSON.parse(Buffer.from(payload, 'base64url').toString('utf-8'));
    return Number(session.exp) > Date.now();
  } catch {
    return false;
  }
}

export function requireAdmin(req, res, next) {
  if (!isAdminConfigured()) {
    return res.status(503).json({ error: 'admin_not_configured', message: 'La contraseña de admin no está configurada.' });
  }
  if (!isAdminAuthenticated(req)) {
    return res.status(401).json({ error: 'admin_auth_required', message: 'Debes iniciar sesión como admin.' });
  }
  next();
}
