import { createLogger } from "./logger.tsx";
import { listarColaboradores, type Colaborador } from "./colaboradores.tsx";
import { listarFolhasPagamento } from "./folha-pagamento.tsx";
import { listarPedidosFerias } from "./ferias.tsx";
import { listarAusencias } from "./ausencias.tsx";
import { listarCessacoes } from "./cessacao-contrato.tsx";

const logger = createLogger("DashboardRH");

// Agregador central para o Dashboard de Recursos Humanos - compõe os
// mesmos listarXxx já usados pelos ecrãs individuais, para nunca duplicar a
// leitura/filtragem de dados em cada consumidor (o dashboard é só uma vista
// combinada, não introduz nenhuma fonte de dados nova).

export interface EstatisticasDashboardRH {
  colaboradores: {
    total: number;
    ativos: number;
    suspensos: number;
    cessados: number;
    porDepartamento: { departamento: string; total: number }[];
  };
  folhaMesAtual: {
    ano: number;
    mes: number;
    processada: boolean;
    totalColaboradoresProcessados: number;
    totalColaboradoresAtivos: number;
    totalRemuneracoes: number;
    totalDescontoINSSTrabalhador: number;
    totalEncargoINSSEmpregador: number;
    totalDescontoIRPS: number;
    totalLiquido: number;
  };
  evolucaoMassaSalarial: { ano: number; mes: number; totalLiquido: number; totalRemuneracoes: number }[];
  ferias: {
    pendentes: number;
    proximas: { colaboradorId: string; colaboradorNome: string; dataInicio: string; dataFim: string }[];
  };
  ausencias: {
    pendentes: number;
    activasAgora: number;
  };
  contratosATerminar: { colaboradorId: string; colaboradorNome: string; dataFimContrato: string; diasRestantes: number }[];
  cessacoesRecentes: { colaboradorId: string; colaboradorNome: string; motivo: string; dataCessacaoEfetiva: string }[];
}

function hojeISO(): string {
  return new Date().toISOString().slice(0, 10);
}

export async function obterEstatisticasDashboardRH(empresaId: string): Promise<EstatisticasDashboardRH> {
  try {
    const agora = new Date();
    const anoAtual = agora.getFullYear();
    const mesAtual = agora.getMonth() + 1;
    const hoje = hojeISO();

    const [colaboradoresLista, todasFolhas, pedidosFerias, todasAusencias, cessacoes] = await Promise.all([
      listarColaboradores(empresaId),
      listarFolhasPagamento(empresaId),
      listarPedidosFerias(empresaId),
      listarAusencias(empresaId),
      listarCessacoes(empresaId),
    ]);

    const nomesPorColaborador = new Map<string, string>(colaboradoresLista.map((c) => [c.id, c.nome]));
    const buscarNome = (colaboradorId: string) => nomesPorColaborador.get(colaboradorId) || "Colaborador";

    // ===== Colaboradores =====
    const porDepartamentoMap = new Map<string, number>();
    for (const colaborador of colaboradoresLista) {
      if (colaborador.estado !== "ativo") continue;
      const departamento = colaborador.departamento?.trim() || "Sem departamento";
      porDepartamentoMap.set(departamento, (porDepartamentoMap.get(departamento) || 0) + 1);
    }

    const colaboradoresStats = {
      total: colaboradoresLista.length,
      ativos: colaboradoresLista.filter((c) => c.estado === "ativo").length,
      suspensos: colaboradoresLista.filter((c) => c.estado === "suspenso").length,
      cessados: colaboradoresLista.filter((c) => c.estado === "cessado").length,
      porDepartamento: Array.from(porDepartamentoMap.entries())
        .map(([departamento, total]) => ({ departamento, total }))
        .sort((a, b) => b.total - a.total),
    };

    // ===== Folha do mês actual =====
    const folhasMesAtual = todasFolhas.filter((f) => f.ano === anoAtual && f.mes === mesAtual);
    const folhaMesAtual = {
      ano: anoAtual,
      mes: mesAtual,
      processada: folhasMesAtual.length > 0,
      totalColaboradoresProcessados: folhasMesAtual.length,
      totalColaboradoresAtivos: colaboradoresStats.ativos,
      totalRemuneracoes: folhasMesAtual.reduce((acc, f) => acc + (f.totalRemuneracoes || 0), 0),
      totalDescontoINSSTrabalhador: folhasMesAtual.reduce((acc, f) => acc + (f.descontoINSSTrabalhador || 0), 0),
      totalEncargoINSSEmpregador: folhasMesAtual.reduce((acc, f) => acc + (f.encargoINSSEmpregador || 0), 0),
      totalDescontoIRPS: folhasMesAtual.reduce((acc, f) => acc + (f.descontoIRPS || 0), 0),
      totalLiquido: folhasMesAtual.reduce((acc, f) => acc + (f.salarioLiquido || 0), 0),
    };

    // ===== Evolução da massa salarial (últimos 6 meses com folhas) =====
    const porPeriodoMap = new Map<string, { ano: number; mes: number; totalLiquido: number; totalRemuneracoes: number }>();
    for (const folha of todasFolhas) {
      const chave = `${folha.ano}-${String(folha.mes).padStart(2, "0")}`;
      const actual = porPeriodoMap.get(chave) || { ano: folha.ano, mes: folha.mes, totalLiquido: 0, totalRemuneracoes: 0 };
      actual.totalLiquido += folha.salarioLiquido || 0;
      actual.totalRemuneracoes += folha.totalRemuneracoes || 0;
      porPeriodoMap.set(chave, actual);
    }
    const evolucaoMassaSalarial = Array.from(porPeriodoMap.entries())
      .sort(([a], [b]) => a.localeCompare(b))
      .slice(-6)
      .map(([, valor]) => valor);

    // ===== Férias =====
    const feriasPendentes = pedidosFerias.filter((p) => p.estado === "pendente");
    const feriasProximas = pedidosFerias
      .filter((p) => p.estado === "aprovado" && p.dataInicio >= hoje)
      .sort((a, b) => a.dataInicio.localeCompare(b.dataInicio))
      .slice(0, 5)
      .map((p) => ({
        colaboradorId: p.colaboradorId,
        colaboradorNome: buscarNome(p.colaboradorId),
        dataInicio: p.dataInicio,
        dataFim: p.dataFim,
      }));

    // ===== Ausências =====
    const ausenciasPendentes = todasAusencias.filter((a) => a.estado === "pendente").length;
    const ausenciasActivas = todasAusencias.filter(
      (a) => a.estado === "aprovado" && a.dataInicio <= hoje && a.dataFim >= hoje,
    ).length;

    // ===== Contratos a terminar nos próximos 60 dias =====
    const em60Dias = new Date(agora.getTime() + 60 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
    const contratosATerminar = colaboradoresLista
      .filter((c) => c.estado === "ativo" && c.dataFimContrato && c.dataFimContrato >= hoje && c.dataFimContrato <= em60Dias)
      .sort((a, b) => (a.dataFimContrato || "").localeCompare(b.dataFimContrato || ""))
      .map((c) => ({
        colaboradorId: c.id,
        colaboradorNome: c.nome,
        dataFimContrato: c.dataFimContrato as string,
        diasRestantes: Math.ceil(
          (new Date(`${c.dataFimContrato}T00:00:00`).getTime() - agora.getTime()) / (24 * 60 * 60 * 1000),
        ),
      }));

    // ===== Cessações recentes =====
    const cessacoesRecentes = [...cessacoes]
      .sort((a, b) => b.dataCessacaoEfetiva.localeCompare(a.dataCessacaoEfetiva))
      .slice(0, 5)
      .map((c) => ({
        colaboradorId: c.colaboradorId,
        colaboradorNome: buscarNome(c.colaboradorId),
        motivo: c.motivo,
        dataCessacaoEfetiva: c.dataCessacaoEfetiva,
      }));

    return {
      colaboradores: colaboradoresStats,
      folhaMesAtual,
      evolucaoMassaSalarial,
      ferias: { pendentes: feriasPendentes.length, proximas: feriasProximas },
      ausencias: { pendentes: ausenciasPendentes, activasAgora: ausenciasActivas },
      contratosATerminar,
      cessacoesRecentes,
    };
  } catch (error) {
    logger.error("Erro ao calcular estatísticas do dashboard RH:", error);
    throw error;
  }
}
