import type { EscalaoIrps, ParametrosFiscaisRH } from "./parametros-fiscais-rh.tsx";
import { calcularDescontoINSSTrabalhador, calcularDescontoIRPS, validarParametrosFiscaisCompletos } from "./calculo-salarial.tsx";

// Simulador de impacto de IRPS — funcao PURA (sem kv.*), nao persiste nada.
// Objectivo: responder rapidamente "se eu mudar X, quanto muda o IRPS/liquido
// aproximado?", para 4 cenarios pedidos pelo utilizador:
//   1) alteracao salarial (novoSalarioBase)
//   2) nova tabela de escaloes (escaloesHipoteticos)
//   3) mudanca de metodologia bruto/liquido de INSS (irpsIncideSobreRendimentoBrutoHipotetico)
//
// Simplificacao deliberada: calcula sobre o salario base directamente (nao
// reprocessa rubricas/horas extra como calcularFolhaSalarial) — e uma
// ferramenta de simulacao rapida, nao um reprocessamento oficial da folha.
// Para o numero exacto de uma folha real, usar reprocessarFolhasPagamentoEmLote.
//
// Deducao por dependente: NAO esta implementada em nenhum lado do motor de
// calculo (Dependente.elegivelDeducaoIrps e apenas uma marcacao manual, sem
// nenhum consumidor — confirmado por grep). Por isso este simulador nao
// finge simular esse impacto: devolve sempre um aviso explicito em vez de um
// numero inventado.
export interface EntradaSimulacaoImpactoIRPS {
  salarioBase: number;
  novoSalarioBase?: number;
  escaloesHipoteticos?: EscalaoIrps[];
  irpsIncideSobreRendimentoBrutoHipotetico?: boolean;
}

export interface CenarioSimulacaoIRPS {
  salarioBase: number;
  descontoINSSTrabalhador: number;
  rendimentoColectavelIRPS: number;
  descontoIRPS: number;
  salarioLiquidoAproximado: number; // salarioBase - INSS - IRPS (aproximado — nao inclui outras rubricas)
}

export interface ResultadoSimulacaoImpactoIRPS {
  cenarioAtual: CenarioSimulacaoIRPS;
  cenarioSimulado: CenarioSimulacaoIRPS;
  diferencaDescontoIRPS: number;
  diferencaSalarioLiquido: number;
  parametrosAlterados: string[];
  avisoDeducaoDependente: string;
}

function calcularCenario(salarioBase: number, parametros: ParametrosFiscaisRH): CenarioSimulacaoIRPS {
  const descontoINSSTrabalhador = calcularDescontoINSSTrabalhador(salarioBase, parametros);
  const rendimentoColectavelIRPS = parametros.irpsIncideSobreRendimentoBruto
    ? salarioBase
    : Math.round((salarioBase - descontoINSSTrabalhador) * 100) / 100;
  const descontoIRPS = calcularDescontoIRPS(rendimentoColectavelIRPS, parametros);
  const salarioLiquidoAproximado = Math.round((salarioBase - descontoINSSTrabalhador - descontoIRPS) * 100) / 100;

  return { salarioBase, descontoINSSTrabalhador, rendimentoColectavelIRPS, descontoIRPS, salarioLiquidoAproximado };
}

export function simularImpactoIRPS(
  entrada: EntradaSimulacaoImpactoIRPS,
  parametrosAtuais: ParametrosFiscaisRH,
): { success: true; data: ResultadoSimulacaoImpactoIRPS } | { success: false; error: string } {
  const emFalta = validarParametrosFiscaisCompletos(parametrosAtuais);
  if (emFalta.length > 0) {
    return { success: false, error: `Não é possível simular — parâmetros por confirmar: ${emFalta.join(", ")}.` };
  }

  if (!Number.isFinite(entrada.salarioBase) || entrada.salarioBase < 0) {
    return { success: false, error: "Salário base inválido" };
  }

  const parametrosAlterados: string[] = [];

  const parametrosSimulados: ParametrosFiscaisRH = { ...parametrosAtuais };
  if (entrada.escaloesHipoteticos && entrada.escaloesHipoteticos.length > 0) {
    parametrosSimulados.irpsEscaloes = entrada.escaloesHipoteticos;
    parametrosAlterados.push("escaloesIrps");
  }
  if (entrada.irpsIncideSobreRendimentoBrutoHipotetico !== undefined) {
    parametrosSimulados.irpsIncideSobreRendimentoBruto = entrada.irpsIncideSobreRendimentoBrutoHipotetico;
    parametrosAlterados.push("metodologia");
  }

  const novoSalarioBase = entrada.novoSalarioBase !== undefined ? entrada.novoSalarioBase : entrada.salarioBase;
  if (entrada.novoSalarioBase !== undefined && entrada.novoSalarioBase !== entrada.salarioBase) {
    parametrosAlterados.push("salarioBase");
  }

  const cenarioAtual = calcularCenario(entrada.salarioBase, parametrosAtuais);
  const cenarioSimulado = calcularCenario(novoSalarioBase, parametrosSimulados);

  return {
    success: true,
    data: {
      cenarioAtual,
      cenarioSimulado,
      diferencaDescontoIRPS: Math.round((cenarioSimulado.descontoIRPS - cenarioAtual.descontoIRPS) * 100) / 100,
      diferencaSalarioLiquido: Math.round((cenarioSimulado.salarioLiquidoAproximado - cenarioAtual.salarioLiquidoAproximado) * 100) / 100,
      parametrosAlterados,
      avisoDeducaoDependente:
        "O sistema ainda não calcula dedução de IRPS por dependente (Dependente.elegivelDeducaoIrps é apenas uma marcação manual, sem cálculo associado) — esta simulação não reflecte alterações no número de dependentes.",
    },
  };
}
