import type { Request, Response, NextFunction } from 'express';
import * as dashboardService from '../services/dashboard.service.js';
import { generarAlertasAutomaticas } from '../services/alertas-auto.service.js';
import { getAlertasManualesPendientes } from '../services/alertas-manuales.service.js';
import { AppError } from '../middlewares/error.middleware.js';

function getDefaultRange() {
  const now = new Date();
  const y = now.getFullYear();
  const m = now.getMonth() + 1;
  const lastDay = new Date(y, m, 0).getDate();
  return {
    fechaInicio: `${y}-${String(m).padStart(2, '0')}-01`,
    fechaFin: `${y}-${String(m).padStart(2, '0')}-${String(lastDay).padStart(2, '0')}`,
    año: y,
    mes: m,
  };
}

function parseConciliacion(req: Request): boolean {
  return req.query.conciliacion === 'true' || req.query.conciliacion === '1';
}

export async function getKpis(req: Request, res: Response, next: NextFunction) {
  try {
    if (!req.tenantPool) {
      return next(new AppError(400, 'Tenant no configurado'));
    }

    const defaults = getDefaultRange();
    const fechaInicio = (req.query.fechaInicio as string) || defaults.fechaInicio;
    const fechaFin = (req.query.fechaFin as string) || defaults.fechaFin;
    const conciliacion = parseConciliacion(req);
    const contribuyenteId = (req.query.contribuyenteId as string) || null;

    const tenantId = req.viewingTenantId || req.user!.tenantId;
    const kpis = await dashboardService.getKpis(req.tenantPool, fechaInicio, fechaFin, tenantId, conciliacion, contribuyenteId);
    res.json(kpis);
  } catch (error) {
    next(error);
  }
}

export async function getIngresosEgresos(req: Request, res: Response, next: NextFunction) {
  try {
    if (!req.tenantPool) {
      return next(new AppError(400, 'Tenant no configurado'));
    }

    const año = parseInt(req.query.año as string) || new Date().getFullYear();
    const conciliacion = parseConciliacion(req);
    const contribuyenteId = (req.query.contribuyenteId as string) || null;
    const tenantId = req.viewingTenantId || req.user!.tenantId;

    const data = await dashboardService.getIngresosEgresos(req.tenantPool, año, tenantId, conciliacion, contribuyenteId);
    res.json(data);
  } catch (error) {
    next(error);
  }
}

export async function getRegimenesDelPeriodo(req: Request, res: Response, next: NextFunction) {
  try {
    if (!req.tenantPool) {
      return next(new AppError(400, 'Tenant no configurado'));
    }

    const defaults = getDefaultRange();
    const fechaInicio = (req.query.fechaInicio as string) || defaults.fechaInicio;
    const fechaFin = (req.query.fechaFin as string) || defaults.fechaFin;
    const conciliacion = parseConciliacion(req);
    const contribuyenteId = (req.query.contribuyenteId as string) || null;

    const tenantId = req.viewingTenantId || req.user?.tenantId;
    const regimenes = await dashboardService.getRegimenesDelPeriodo(req.tenantPool, fechaInicio, fechaFin, conciliacion, contribuyenteId, tenantId);
    res.json(regimenes);
  } catch (error) {
    next(error);
  }
}

export async function getAlertas(req: Request, res: Response, next: NextFunction) {
  try {
    if (!req.tenantPool) {
      return next(new AppError(400, 'Tenant no configurado'));
    }

    const limit = parseInt(req.query.limit as string) || 5;
    const tenantId = req.viewingTenantId || req.user!.tenantId;
    const contribuyenteId = (req.query.contribuyenteId as string) || null;

    // Combinar alertas persistidas (manuales, filtered by role) + automáticas (calculadas)
    const [manuales, automaticas] = await Promise.all([
      getAlertasManualesPendientes(req.tenantPool, contribuyenteId, req.user!.userId, req.user!.role),
      generarAlertasAutomaticas(req.tenantPool, tenantId, contribuyenteId),
    ]);

    // Unir, ordenar por prioridad, y limitar
    const prioridadOrden: Record<string, number> = { alta: 1, media: 2, baja: 3 };
    const alertas = [...automaticas, ...manuales]
      .sort((a, b) => (prioridadOrden[a.prioridad] || 3) - (prioridadOrden[b.prioridad] || 3))
      .slice(0, limit);

    res.json(alertas);
  } catch (error) {
    next(error);
  }
}
