import * as kv from "./kv_store.tsx";
import { createLogger } from "./logger.tsx";
import { isValidNuit, normalizeNuit } from "./nuit.tsx";

const logger = createLogger('Fornecedores');

// ========== TIPOS ==========

export interface Fornecedor {
  id: string;
  empresaId: string; // Multi-tenant: cada empresa tem seus fornecedores
  codigo: string; // Código interno (ex: FOR001)
  nome: string;
  nomeComercial?: string;
  nuit: string; // NUIT obrigatório em Moçambique
  email?: string;
  telefone?: string;
  telemovel?: string;
  endereco?: string;
  cidade?: string;
  provincia?: string;
  pais: string;
  observacoes?: string;
  ativo: boolean;
  dataCriacao: string;
  dataAtualizacao?: string;
}

// ========== FUNÇÕES DE GESTÃO DE FORNECEDORES ==========

/**
 * Gerar código automático para fornecedor
 */
async function gerarCodigoFornecedor(empresaId: string): Promise<string> {
  const fornecedores = await listarFornecedores(empresaId);
  const proximoNumero = fornecedores.length + 1;
  return `FOR${proximoNumero.toString().padStart(4, '0')}`; // FOR0001, FOR0002, etc
}

/**
 * Criar novo fornecedor
 */
export async function criarFornecedor(dados: Omit<Fornecedor, 'id' | 'codigo' | 'dataCriacao'>): Promise<{ success: boolean; data?: Fornecedor; error?: string }> {
  try {
    const nuitNormalizado = normalizeNuit(dados.nuit);

    // Validar dados obrigatórios
    if (!dados.empresaId || !dados.nome || !nuitNormalizado) {
      return { success: false, error: "Empresa, nome e NUIT são obrigatórios" };
    }

    if (!isValidNuit(nuitNormalizado)) {
      return { success: false, error: "NUIT inválido. Deve conter exatamente 9 dígitos numéricos" };
    }

    // Verificar se NUIT já existe na empresa
    const fornecedorExistente = await buscarFornecedorPorNuit(dados.empresaId, nuitNormalizado);
    if (fornecedorExistente) {
      return { success: false, error: "Já existe um fornecedor com este NUIT" };
    }

    // Gerar ID e código
    const id = `fornecedor_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    const codigo = await gerarCodigoFornecedor(dados.empresaId);

    // ✅ ...dados vem ANTES de id/codigo: mesmo bug e correcao de clientes.tsx
    // (criarCliente) — o pedido do frontend pode incluir um campo "codigo"
    // vazio ou desactualizado, e nao pode sobrepor-se ao gerado aqui.
    const fornecedor: Fornecedor = {
      ...dados,
      id,
      codigo,
      nuit: nuitNormalizado,
      pais: dados.pais || "Moçambique",
      ativo: dados.ativo !== undefined ? dados.ativo : true,
      dataCriacao: new Date().toISOString(),
    };

    // Salvar fornecedor
    await kv.set(`fornecedor:${id}`, fornecedor);
    
    // Indexar por NUIT para busca rápida
    await kv.set(`fornecedor_nuit:${dados.empresaId}:${nuitNormalizado}`, id);

    logger.info(`Fornecedor criado: ${codigo} - ${dados.nome}`);

    return { success: true, data: fornecedor };
  } catch (error) {
    logger.error("Erro ao criar fornecedor:", error);
    return { success: false, error: error.message };
  }
}

/**
 * Buscar fornecedor por ID
 */
export async function buscarFornecedorPorId(id: string): Promise<Fornecedor | null> {
  try {
    const fornecedor = await kv.get(`fornecedor:${id}`);
    return fornecedor as Fornecedor | null;
  } catch (error) {
    logger.error("Erro ao buscar fornecedor:", error);
    return null;
  }
}

/**
 * Buscar fornecedor por NUIT
 */
export async function buscarFornecedorPorNuit(empresaId: string, nuit: string): Promise<Fornecedor | null> {
  try {
    const fornecedorId = await kv.get(`fornecedor_nuit:${empresaId}:${normalizeNuit(nuit)}`);
    if (!fornecedorId) return null;

    return await buscarFornecedorPorId(fornecedorId as string);
  } catch (error) {
    logger.error("Erro ao buscar fornecedor por NUIT:", error);
    return null;
  }
}

/**
 * Listar fornecedores de uma empresa
 */
export async function listarFornecedores(empresaId: string, filtros?: { ativo?: boolean }): Promise<Fornecedor[]> {
  try {
    const todosFornecedores = await kv.getByPrefix<Fornecedor>("fornecedor:");
    
    let fornecedores = todosFornecedores.filter((f) => f && f.empresaId === empresaId);

    // Aplicar filtro de status se fornecido
    if (filtros?.ativo !== undefined) {
      fornecedores = fornecedores.filter((f) => f.ativo === filtros.ativo);
    }

    // Ordenar por código
    fornecedores.sort((a, b) => a.codigo.localeCompare(b.codigo));

    return fornecedores;
  } catch (error) {
    logger.error("Erro ao listar fornecedores:", error);
    return [];
  }
}

/**
 * Atualizar fornecedor
 */
export async function atualizarFornecedor(
  id: string,
  dados: Partial<Fornecedor>
): Promise<{ success: boolean; data?: Fornecedor; error?: string }> {
  try {
    const fornecedor = await buscarFornecedorPorId(id);
    
    if (!fornecedor) {
      return { success: false, error: "Fornecedor não encontrado" };
    }

    // Se está alterando o NUIT, verificar se não existe outro com o mesmo NUIT
    const nuitAtualizado = dados.nuit !== undefined ? normalizeNuit(dados.nuit) : undefined;

    if (dados.nuit !== undefined) {
      if (!nuitAtualizado) {
        return { success: false, error: "NUIT é obrigatório" };
      }

      if (!isValidNuit(nuitAtualizado)) {
        return { success: false, error: "NUIT inválido. Deve conter exatamente 9 dígitos numéricos" };
      }
    }

    if (nuitAtualizado && nuitAtualizado !== fornecedor.nuit) {
      const nuitExiste = await buscarFornecedorPorNuit(fornecedor.empresaId, nuitAtualizado);
      if (nuitExiste) {
        return { success: false, error: "Já existe um fornecedor com este NUIT" };
      }

      // Remover índice antigo e criar novo
      await kv.del(`fornecedor_nuit:${fornecedor.empresaId}:${fornecedor.nuit}`);
      await kv.set(`fornecedor_nuit:${fornecedor.empresaId}:${nuitAtualizado}`, id);
    }

    const fornecedorAtualizado = {
      ...fornecedor,
      ...dados,
      ...(nuitAtualizado ? { nuit: nuitAtualizado } : {}),
      id: fornecedor.id, // Garantir que ID não mude
      codigo: fornecedor.codigo, // Garantir que código não mude
      empresaId: fornecedor.empresaId, // Garantir que empresa não mude
      dataCriacao: fornecedor.dataCriacao, // Garantir que data de criação não mude
      dataAtualizacao: new Date().toISOString(),
    };

    await kv.set(`fornecedor:${id}`, fornecedorAtualizado);

    logger.info(`Fornecedor atualizado: ${id}`);

    return { success: true, data: fornecedorAtualizado };
  } catch (error) {
    logger.error("Erro ao atualizar fornecedor:", error);
    return { success: false, error: error.message };
  }
}

/**
 * Deletar fornecedor
 */
export async function deletarFornecedor(id: string): Promise<{ success: boolean; error?: string }> {
  try {
    const fornecedor = await buscarFornecedorPorId(id);
    
    if (!fornecedor) {
      return { success: false, error: "Fornecedor não encontrado" };
    }

    const comprasFornecedor = (await kv.getByPrefix<any>("compra:"))
      .filter((compra) => compra && compra.fornecedorId === id);
    if (comprasFornecedor.length > 0) {
      return { success: false, error: "Fornecedor possui documentos de compra associados. Desative o fornecedor em vez de eliminar." };
    }

    const pagamentosFornecedor = (await kv.getByPrefix<any>("pagamento_compra:"))
      .filter((pagamento) => pagamento && pagamento.fornecedorId === id);
    if (pagamentosFornecedor.length > 0) {
      return { success: false, error: "Fornecedor possui pagamentos associados. Desative o fornecedor em vez de eliminar." };
    }
    // Remover fornecedor
    await kv.del(`fornecedor:${id}`);
    
    // Remover índice NUIT
    await kv.del(`fornecedor_nuit:${fornecedor.empresaId}:${fornecedor.nuit}`);

    logger.info(`Fornecedor deletado: ${id}`);

    return { success: true };
  } catch (error) {
    logger.error("Erro ao deletar fornecedor:", error);
    return { success: false, error: error.message };
  }
}

/**
 * Ativar/Desativar fornecedor
 */
export async function toggleFornecedor(id: string, ativo: boolean): Promise<{ success: boolean; data?: Fornecedor; error?: string }> {
  return await atualizarFornecedor(id, { ativo });
}
