import * as kv from "./kv_store.tsx";
import { createLogger } from "./logger.tsx";

const logger = createLogger('ComunicacaoDependentesIRPS');

// Rasto administrativo de alteracoes a dependentes de um colaborador, para
// eventual comunicacao a Autoridade Tributaria. Ao contrario de
// comunicacao-inss.tsx, NAO existe aqui um prazo legal confirmado (nao foi
// encontrada, nesta sessao, uma fonte primaria que fixe um numero de dias
// para comunicar alteracoes de dependentes no CIRPS) — por isso este
// registo NAO inventa um `prazoLimite`. Serve apenas para auditoria: quando
// um dependente e adicionado/alterado/removido, fica um registo datado,
// que o utilizador marca manualmente como comunicado quando entender
// necessario (ex: no proximo Certificado de Retencao Anual ou contacto
// directo com a AT).
export type TipoComunicacaoDependenteIRPS = "adicao" | "alteracao" | "remocao";
export type EstadoComunicacaoDependenteIRPS = "pendente" | "comunicado";

export interface ComunicacaoDependenteIRPS {
  id: string;
  empresaId: string;
  colaboradorId: string;
  colaboradorNome: string;
  dependenteId: string;
  dependenteNome: string;
  tipo: TipoComunicacaoDependenteIRPS;
  dataEvento: string; // YYYY-MM-DD
  detalhes: Record<string, unknown>;
  estado: EstadoComunicacaoDependenteIRPS;
  dataComunicacao?: string;
  numeroProtocolo?: string;
  comunicadoPor?: string;
  observacoes?: string;
  dataCriacao: string;
  dataAtualizacao?: string;
}

const COMUNICACAO_PREFIX = "comunicacao_dependente_irps:";

// Nunca lanca — chamado como efeito colateral de criarDependente/
// atualizarDependente/deletarDependente, que nao devem falhar por causa de
// um problema neste registo auxiliar.
export async function criarComunicacaoDependenteIRPS(dados: {
  empresaId: string;
  colaboradorId: string;
  colaboradorNome: string;
  dependenteId: string;
  dependenteNome: string;
  tipo: TipoComunicacaoDependenteIRPS;
  dataEvento: string;
  detalhes: Record<string, unknown>;
}): Promise<void> {
  try {
    const id = `comunicacao_dependente_irps_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    const comunicacao: ComunicacaoDependenteIRPS = {
      id,
      empresaId: dados.empresaId,
      colaboradorId: dados.colaboradorId,
      colaboradorNome: dados.colaboradorNome,
      dependenteId: dados.dependenteId,
      dependenteNome: dados.dependenteNome,
      tipo: dados.tipo,
      dataEvento: dados.dataEvento,
      detalhes: dados.detalhes,
      estado: "pendente",
      dataCriacao: new Date().toISOString(),
    };

    await kv.set(`${COMUNICACAO_PREFIX}${id}`, comunicacao);
    logger.info(`Comunicação de dependente IRPS criada: ${dados.tipo} — ${dados.dependenteNome} (colaborador ${dados.colaboradorNome})`);
  } catch (error) {
    logger.error("Erro ao criar comunicação de dependente IRPS:", error);
  }
}

export async function buscarComunicacaoDependenteIRPSPorId(id: string): Promise<ComunicacaoDependenteIRPS | null> {
  try {
    return (await kv.get(`${COMUNICACAO_PREFIX}${id}`)) as ComunicacaoDependenteIRPS | null;
  } catch (error) {
    logger.error("Erro ao buscar comunicação de dependente IRPS:", error);
    return null;
  }
}

export async function listarComunicacoesDependentesIRPS(
  empresaId: string,
  filtros?: { colaboradorId?: string; tipo?: TipoComunicacaoDependenteIRPS; estado?: EstadoComunicacaoDependenteIRPS },
): Promise<ComunicacaoDependenteIRPS[]> {
  try {
    const todas = await kv.getByPrefix<ComunicacaoDependenteIRPS>(COMUNICACAO_PREFIX);
    let comunicacoes = todas.filter((item) => item && item.empresaId === empresaId);

    if (filtros?.colaboradorId) comunicacoes = comunicacoes.filter((item) => item.colaboradorId === filtros.colaboradorId);
    if (filtros?.tipo) comunicacoes = comunicacoes.filter((item) => item.tipo === filtros.tipo);
    if (filtros?.estado) comunicacoes = comunicacoes.filter((item) => item.estado === filtros.estado);

    comunicacoes.sort((a, b) => b.dataEvento.localeCompare(a.dataEvento));
    return comunicacoes;
  } catch (error) {
    logger.error("Erro ao listar comunicações de dependentes IRPS:", error);
    return [];
  }
}

export async function marcarComunicacaoDependenteIRPSEnviada(
  id: string,
  comunicadoPor: string,
  numeroProtocolo?: string,
  observacoes?: string,
): Promise<{ success: boolean; data?: ComunicacaoDependenteIRPS; error?: string }> {
  try {
    if (!comunicadoPor?.trim()) {
      return { success: false, error: "É obrigatório identificar quem enviou a comunicação" };
    }

    const comunicacao = await buscarComunicacaoDependenteIRPSPorId(id);
    if (!comunicacao) {
      return { success: false, error: "Comunicação não encontrada" };
    }
    if (comunicacao.estado === "comunicado") {
      return { success: false, error: "Esta comunicação já foi marcada como enviada" };
    }

    const atualizada: ComunicacaoDependenteIRPS = {
      ...comunicacao,
      estado: "comunicado",
      dataComunicacao: new Date().toISOString(),
      numeroProtocolo: numeroProtocolo?.trim() || undefined,
      observacoes: observacoes?.trim() || undefined,
      comunicadoPor: comunicadoPor.trim(),
      dataAtualizacao: new Date().toISOString(),
    };

    await kv.set(`${COMUNICACAO_PREFIX}${id}`, atualizada);
    logger.info(`Comunicação de dependente IRPS marcada como enviada: ${id}`);

    return { success: true, data: atualizada };
  } catch (error) {
    logger.error("Erro ao marcar comunicação de dependente IRPS como enviada:", error);
    return { success: false, error: error.message };
  }
}
