import type { Request, Response } from 'express';
import { uploadFiel, getFielStatus, deleteFiel } from '../services/fiel.service.js';
import type { FielUploadRequest } from '@horux/shared';
import type { Pool } from 'pg';

/**
 * Crea recordatorios automáticos de vencimiento de e.firma en el calendario.
 * 60 días, 30 días y 7 días antes del vencimiento.
 * Elimina recordatorios previos de e.firma antes de crear nuevos.
 */
async function crearRecordatoriosEfirma(
  pool: Pool,
  userId: string,
  validUntil: string,
): Promise<void> {
  const vencimiento = new Date(validUntil);
  const PREFIJO = '[e.firma]';

  // Eliminar recordatorios previos de e.firma para evitar duplicados al re-subir
  await pool.query(
    `DELETE FROM recordatorios WHERE titulo LIKE $1`,
    [`${PREFIJO}%`]
  );

  const recordatorios = [
    { dias: 60, titulo: `${PREFIJO} Tu e.firma vence en 60 días` },
    { dias: 30, titulo: `${PREFIJO} Tu e.firma vence en 30 días` },
    { dias: 7, titulo: `${PREFIJO} Tu e.firma vence en 7 días — ¡Renueva pronto!` },
  ];

  for (const { dias, titulo } of recordatorios) {
    const fecha = new Date(vencimiento);
    fecha.setDate(fecha.getDate() - dias);

    // Solo crear si la fecha no ha pasado
    if (fecha > new Date()) {
      await pool.query(
        `INSERT INTO recordatorios (titulo, descripcion, fecha_limite, privado, creado_por)
         VALUES ($1, $2, $3, false, $4)`,
        [
          titulo,
          `La e.firma (FIEL) vence el ${vencimiento.toLocaleDateString('es-MX')}. Renueva en el portal del SAT.`,
          fecha.toISOString().split('T')[0],
          userId,
        ]
      );
    }
  }
}

function effectiveTenantId(req: Request): string {
  return req.viewingTenantId || req.user!.tenantId;
}

/**
 * Sube y configura las credenciales FIEL
 */
export async function upload(req: Request, res: Response): Promise<void> {
  try {
    const tenantId = effectiveTenantId(req);

    const { cerFile, keyFile, password } = req.body as FielUploadRequest;

    if (!cerFile || !keyFile || !password) {
      res.status(400).json({ error: 'cerFile, keyFile y password son requeridos' });
      return;
    }

    // Validate file sizes (typical .cer/.key files are under 10KB, base64 ~33% larger)
    const MAX_FILE_SIZE = 50_000; // 50KB base64 ≈ ~37KB binary
    if (cerFile.length > MAX_FILE_SIZE || keyFile.length > MAX_FILE_SIZE) {
      res.status(400).json({ error: 'Los archivos FIEL son demasiado grandes (máx 50KB)' });
      return;
    }

    if (password.length > 256) {
      res.status(400).json({ error: 'Contraseña FIEL demasiado larga' });
      return;
    }

    const result = await uploadFiel(tenantId, cerFile, keyFile, password);

    if (!result.success) {
      res.status(400).json({ error: result.message });
      return;
    }

    // Crear recordatorios de vencimiento en el calendario
    if (result.status?.validUntil && req.tenantPool) {
      crearRecordatoriosEfirma(req.tenantPool, req.user!.userId, result.status.validUntil)
        .catch(err => console.error('[FIEL] Error creando recordatorios de vencimiento:', err));
    }

    res.json({
      message: result.message,
      status: result.status,
    });
  } catch (error: any) {
    console.error('[FIEL Controller] Error en upload:', error);
    res.status(500).json({ error: 'Error interno del servidor' });
  }
}

/**
 * Obtiene el estado de la FIEL configurada
 */
export async function status(req: Request, res: Response): Promise<void> {
  try {
    const tenantId = effectiveTenantId(req);
    const fielStatus = await getFielStatus(tenantId);
    res.json(fielStatus);
  } catch (error: any) {
    console.error('[FIEL Controller] Error en status:', error);
    res.status(500).json({ error: 'Error interno del servidor' });
  }
}

/**
 * Elimina las credenciales FIEL
 */
export async function remove(req: Request, res: Response): Promise<void> {
  try {
    const tenantId = effectiveTenantId(req);
    const deleted = await deleteFiel(tenantId);

    if (!deleted) {
      res.status(404).json({ error: 'No hay FIEL configurada' });
      return;
    }

    res.json({ message: 'FIEL eliminada correctamente' });
  } catch (error: any) {
    console.error('[FIEL Controller] Error en remove:', error);
    res.status(500).json({ error: 'Error interno del servidor' });
  }
}
