import type { Request, Response, NextFunction } from 'express';
import { AppError } from '../middlewares/error.middleware.js';
import * as despachoService from '../services/despacho-stats.service.js';

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

const ROLES_OWNER = new Set(['owner', 'cfo']);
const ROLES_SUPERVISORY = new Set(['owner', 'cfo', 'supervisor']);
const ROLES_ASIGNADOS = new Set(['owner', 'cfo', 'supervisor', 'auxiliar']);

export async function getContribuyentesStats(req: Request, res: Response, next: NextFunction) {
  try {
    if (!ROLES_OWNER.has(req.user!.role)) {
      throw new AppError(403, 'Solo owner puede ver estas métricas');
    }
    const tenantId = effectiveTenantId(req);
    const año = req.query.año ? parseInt(String(req.query.año), 10) : undefined;
    const mes = req.query.mes ? parseInt(String(req.query.mes), 10) : undefined;
    const stats = await despachoService.getContribuyentesStats(req.tenantPool!, tenantId, año, mes);
    res.json(stats);
  } catch (error) {
    next(error);
  }
}

export async function getMisAsignados(req: Request, res: Response, next: NextFunction) {
  try {
    if (!ROLES_ASIGNADOS.has(req.user!.role)) {
      throw new AppError(403, 'No tienes contribuyentes asignados');
    }
    const año = req.query.año ? parseInt(String(req.query.año), 10) : undefined;
    const mes = req.query.mes ? parseInt(String(req.query.mes), 10) : undefined;
    const data = await despachoService.getMisAsignados(
      req.tenantPool!,
      req.user!.userId,
      req.user!.role,
      año,
      mes,
    );
    res.json(data);
  } catch (error) {
    next(error);
  }
}

export async function getEquipoStats(req: Request, res: Response, next: NextFunction) {
  try {
    if (!ROLES_SUPERVISORY.has(req.user!.role)) {
      throw new AppError(403, 'Solo owner y supervisor pueden ver al equipo');
    }
    const año = req.query.año ? parseInt(String(req.query.año), 10) : undefined;
    const mes = req.query.mes ? parseInt(String(req.query.mes), 10) : undefined;
    const data = await despachoService.getEquipoStats(
      req.tenantPool!,
      req.user!.userId,
      req.user!.role,
      effectiveTenantId(req),
      año,
      mes,
    );
    res.json(data);
  } catch (error) {
    next(error);
  }
}
