import * as kv from "./kv_store.tsx";
import { createLogger } from "./logger.tsx";

const logger = createLogger('PeriodoFolhaPagamento');

// Workflow de estados do processamento salarial, ao nivel de empresa+mes
// (nao por colaborador individual — cada FolhaPagamento continua a ser um
// registo por colaborador, este e o "envelope" que representa o ciclo
// mensal completo). Ambito deliberadamente reduzido a 3 estados + reabertura
// justificada, em vez do pipeline completo de 9 estados da especificacao
// original (Nao iniciado/Em preparacao/Rascunho/Processado/Em
// validacao/Aprovado/Fechado/Pago/Arquivado) — os estados omitidos dependem
// de funcionalidades ainda nao construidas (motor de alertas de preparacao,
// confirmacao de pagamento bancario, arquivo). Cobre o essencial pedido:
// aprovacao hierarquica + bloqueio de alteracoes apos fecho, com uma valvula
// de escape (reabrir com motivo obrigatorio) para correccoes.
export type EstadoPeriodoFolhaPagamento = "aberto" | "aprovado" | "fechado";

export interface PeriodoFolhaPagamento {
  id: string;
  empresaId: string;
  ano: number;
  mes: number;
  estado: EstadoPeriodoFolhaPagamento;
  aprovadoPor?: string;
  dataAprovacao?: string;
  fechadoPor?: string;
  dataFecho?: string;
  reabertoPor?: string;
  dataReabertura?: string;
  motivoReabertura?: string;
  dataCriacao: string;
  dataAtualizacao?: string;
}

const PERIODO_PREFIX = "periodo_folha_pagamento:";

function chavePeriodo(empresaId: string, ano: number, mes: number): string {
  return `${PERIODO_PREFIX}${empresaId}:${ano}:${String(mes).padStart(2, "0")}`;
}

// Nunca lanca erro nem bloqueia — se o periodo ainda nao existe, e
// implicitamente "aberto" (comportamento identico ao que ja existia antes
// deste workflow ser introduzido).
export async function obterPeriodoFolhaPagamento(
  empresaId: string,
  ano: number,
  mes: number,
): Promise<PeriodoFolhaPagamento> {
  try {
    const existente = await kv.get(chavePeriodo(empresaId, ano, mes)) as PeriodoFolhaPagamento | null;
    if (existente) return existente;
  } catch (error) {
    logger.error("Erro ao obter periodo de folha de pagamento:", error);
  }

  return {
    id: chavePeriodo(empresaId, ano, mes),
    empresaId,
    ano,
    mes,
    estado: "aberto",
    dataCriacao: new Date().toISOString(),
  };
}

export async function aprovarPeriodoFolhaPagamento(
  empresaId: string,
  ano: number,
  mes: number,
  totalFolhasProcessadas: number,
  aprovadoPor: string,
): Promise<{ success: boolean; data?: PeriodoFolhaPagamento; error?: string }> {
  try {
    if (totalFolhasProcessadas === 0) {
      return { success: false, error: "Não há folhas de pagamento processadas para aprovar neste período" };
    }

    const periodo = await obterPeriodoFolhaPagamento(empresaId, ano, mes);
    if (periodo.estado !== "aberto") {
      return { success: false, error: `Período já está "${periodo.estado}" — não é possível aprovar novamente` };
    }

    const periodoAtualizado: PeriodoFolhaPagamento = {
      ...periodo,
      estado: "aprovado",
      aprovadoPor,
      dataAprovacao: new Date().toISOString(),
      dataAtualizacao: new Date().toISOString(),
    };

    await kv.set(periodoAtualizado.id, periodoAtualizado);
    logger.info(`Período ${mes}/${ano} da empresa ${empresaId} aprovado por ${aprovadoPor}`);

    return { success: true, data: periodoAtualizado };
  } catch (error) {
    logger.error("Erro ao aprovar periodo de folha de pagamento:", error);
    return { success: false, error: error.message };
  }
}

export async function fecharPeriodoFolhaPagamento(
  empresaId: string,
  ano: number,
  mes: number,
  fechadoPor: string,
): Promise<{ success: boolean; data?: PeriodoFolhaPagamento; error?: string }> {
  try {
    const periodo = await obterPeriodoFolhaPagamento(empresaId, ano, mes);
    if (periodo.estado !== "aprovado") {
      return { success: false, error: 'Só é possível fechar um período depois de aprovado' };
    }

    const periodoAtualizado: PeriodoFolhaPagamento = {
      ...periodo,
      estado: "fechado",
      fechadoPor,
      dataFecho: new Date().toISOString(),
      dataAtualizacao: new Date().toISOString(),
    };

    await kv.set(periodoAtualizado.id, periodoAtualizado);
    logger.info(`Período ${mes}/${ano} da empresa ${empresaId} fechado por ${fechadoPor}`);

    return { success: true, data: periodoAtualizado };
  } catch (error) {
    logger.error("Erro ao fechar periodo de folha de pagamento:", error);
    return { success: false, error: error.message };
  }
}

export async function reabrirPeriodoFolhaPagamento(
  empresaId: string,
  ano: number,
  mes: number,
  reabertoPor: string,
  motivo: string,
): Promise<{ success: boolean; data?: PeriodoFolhaPagamento; error?: string }> {
  try {
    if (!motivo?.trim()) {
      return { success: false, error: "É obrigatório indicar o motivo da reabertura" };
    }

    const periodo = await obterPeriodoFolhaPagamento(empresaId, ano, mes);
    if (periodo.estado === "aberto") {
      return { success: false, error: "Período já está aberto" };
    }

    const periodoAtualizado: PeriodoFolhaPagamento = {
      ...periodo,
      estado: "aberto",
      reabertoPor,
      dataReabertura: new Date().toISOString(),
      motivoReabertura: motivo.trim(),
      dataAtualizacao: new Date().toISOString(),
    };

    await kv.set(periodoAtualizado.id, periodoAtualizado);
    logger.info(`Período ${mes}/${ano} da empresa ${empresaId} reaberto por ${reabertoPor}: ${motivo}`);

    return { success: true, data: periodoAtualizado };
  } catch (error) {
    logger.error("Erro ao reabrir periodo de folha de pagamento:", error);
    return { success: false, error: error.message };
  }
}
