import * as kv from "./kv_store.tsx";
import * as kvAtomic from "./kv_atomic.tsx";
import { createLogger } from "./logger.tsx";
import { listarFolhasPagamento } from "./folha-pagamento.tsx";
import { buscarColaboradorPorId } from "./colaboradores.tsx";

const logger = createLogger('CertificadoRetencaoIRPS');

// Certificado de Retencao Anual de IRPS — documento emitido pela empresa a
// cada colaborador, resumindo o total de rendimento sujeito e IRPS retido no
// ano (Arts. 83/87 do CIRPS regem a guia de pagamento mensal — Modelo 19 —
// ja implementada; este certificado e um comprovativo ANUAL por
// colaborador, util para o proprio trabalhador e para efeitos de prova de
// retencao). Nao existe um modelo oficial descarregado da AT confirmado
// para este documento nesta sessao (ao contrario do Modelo 19) — por isso
// segue o padrao de documento recriado/impresso (como Recibo de Vencimento,
// Livro de Trabalho Excepcional, etc.), nao o padrao de sobreposicao de PDF
// oficial.
export type EstadoCertificadoRetencaoIRPS = "emitido" | "anulado";

export interface CertificadoRetencaoIRPS {
  id: string;
  empresaId: string;
  colaboradorId: string;
  colaboradorNome: string;
  ano: number;
  numeroCertificado: string; // sequencial por empresa+ano
  totalRendimentoColectavel: number;
  totalRetencaoIRPS: number;
  numeroMesesComFolha: number;
  estado: EstadoCertificadoRetencaoIRPS;
  motivoAnulacao?: string;
  emitidoPor: string;
  dataEmissao: string;
  certificadoOriginalId?: string; // presente quando este certificado substitui um certificado anulado
  dataCriacao: string;
  dataAtualizacao?: string;
}

const CERTIFICADO_PREFIX = "certificado_retencao_irps:";

async function reservarNumeroCertificado(empresaId: string, ano: number): Promise<string> {
  const existentes = await listarCertificadosRetencaoIRPS(empresaId, { ano });
  let candidato = existentes.length + 1;

  for (let tentativa = 0; tentativa < 500; tentativa += 1) {
    const numero = String(candidato).padStart(4, "0");
    const chave = `certificado_retencao_irps_numero:${empresaId}:${ano}:${numero}`;
    const resultado = await kvAtomic.createIfAbsent(chave, { reservedAt: new Date().toISOString() });
    if (resultado.created) return numero;
    candidato += 1;
  }

  throw new Error("Não foi possível gerar um número de certificado único");
}

export async function gerarCertificadoRetencaoIRPS(
  empresaId: string,
  colaboradorId: string,
  ano: number,
  emitidoPor: string,
): Promise<{ success: boolean; data?: CertificadoRetencaoIRPS; error?: string }> {
  try {
    if (!emitidoPor?.trim()) {
      return { success: false, error: "É obrigatório identificar quem emitiu o certificado" };
    }

    const colaborador = await buscarColaboradorPorId(colaboradorId);
    if (!colaborador || colaborador.empresaId !== empresaId) {
      return { success: false, error: "Colaborador não encontrado nesta empresa" };
    }

    const existentes = await listarCertificadosRetencaoIRPS(empresaId, { colaboradorId, ano });
    const certificadoActivo = existentes.find((c) => c.estado !== "anulado");
    if (certificadoActivo) {
      return { success: false, error: `Já existe um certificado (${certificadoActivo.numeroCertificado}) para ${colaborador.nome} em ${ano}` };
    }

    const folhas = await listarFolhasPagamento(empresaId, { colaboradorId, ano });
    if (folhas.length === 0) {
      return { success: false, error: `Não existem folhas de pagamento processadas para ${colaborador.nome} em ${ano}` };
    }

    const totalRetencaoIRPS = Math.round(folhas.reduce((soma, f) => soma + f.descontoIRPS, 0) * 100) / 100;
    const totalRendimentoColectavel = Math.round(folhas.reduce((soma, f) => soma + f.rendimentoColectavelIRPS, 0) * 100) / 100;

    const numeroCertificado = await reservarNumeroCertificado(empresaId, ano);
    const id = `certificado_retencao_irps_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

    const certificado: CertificadoRetencaoIRPS = {
      id,
      empresaId,
      colaboradorId,
      colaboradorNome: colaborador.nome,
      ano,
      numeroCertificado,
      totalRendimentoColectavel,
      totalRetencaoIRPS,
      numeroMesesComFolha: folhas.length,
      estado: "emitido",
      emitidoPor: emitidoPor.trim(),
      dataEmissao: new Date().toISOString(),
      dataCriacao: new Date().toISOString(),
    };

    await kv.set(`${CERTIFICADO_PREFIX}${id}`, certificado);
    logger.info(`Certificado de retenção IRPS gerado: ${numeroCertificado} — ${colaborador.nome} — ${ano}`);

    return { success: true, data: certificado };
  } catch (error) {
    logger.error("Erro ao gerar certificado de retenção IRPS:", error);
    return { success: false, error: error.message };
  }
}

export async function buscarCertificadoRetencaoIRPSPorId(id: string): Promise<CertificadoRetencaoIRPS | null> {
  try {
    return (await kv.get(`${CERTIFICADO_PREFIX}${id}`)) as CertificadoRetencaoIRPS | null;
  } catch (error) {
    logger.error("Erro ao buscar certificado de retenção IRPS:", error);
    return null;
  }
}

export async function listarCertificadosRetencaoIRPS(
  empresaId: string,
  filtros?: { colaboradorId?: string; ano?: number; estado?: EstadoCertificadoRetencaoIRPS },
): Promise<CertificadoRetencaoIRPS[]> {
  try {
    const todos = await kv.getByPrefix<CertificadoRetencaoIRPS>(CERTIFICADO_PREFIX);
    let certificados = todos.filter((item) => item && item.empresaId === empresaId);

    if (filtros?.colaboradorId) certificados = certificados.filter((item) => item.colaboradorId === filtros.colaboradorId);
    if (filtros?.ano !== undefined) certificados = certificados.filter((item) => item.ano === filtros.ano);
    if (filtros?.estado) certificados = certificados.filter((item) => item.estado === filtros.estado);

    certificados.sort((a, b) => (b.ano - a.ano) || b.numeroCertificado.localeCompare(a.numeroCertificado));
    return certificados;
  } catch (error) {
    logger.error("Erro ao listar certificados de retenção IRPS:", error);
    return [];
  }
}

export async function anularCertificadoRetencaoIRPS(
  id: string,
  motivo: string,
  anuladoPor: string,
): Promise<{ success: boolean; data?: CertificadoRetencaoIRPS; error?: string }> {
  try {
    if (!motivo?.trim()) return { success: false, error: "É obrigatório indicar o motivo da anulação" };

    const certificado = await buscarCertificadoRetencaoIRPSPorId(id);
    if (!certificado) return { success: false, error: "Certificado não encontrado" };
    if (certificado.estado === "anulado") return { success: false, error: "Este certificado já está anulado" };

    const atualizado: CertificadoRetencaoIRPS = {
      ...certificado,
      estado: "anulado",
      motivoAnulacao: motivo.trim(),
      dataAtualizacao: new Date().toISOString(),
    };

    await kv.set(`${CERTIFICADO_PREFIX}${id}`, atualizado);
    logger.info(`Certificado de retenção IRPS anulado: ${certificado.numeroCertificado} por ${anuladoPor}`);

    return { success: true, data: atualizado };
  } catch (error) {
    logger.error("Erro ao anular certificado de retenção IRPS:", error);
    return { success: false, error: error.message };
  }
}
