// ========== MÓDULO DE STOCK POR ARMAZÉM ==========
// Gestão de stock distribuído por armazéns

import * as kv from "./kv_store.tsx";
import { createLogger } from "./logger.tsx";

const logger = createLogger('StockArmazem');

// ========== PREFIXO ÚNICO ==========
const STOCK_ARMAZEM_PREFIX = "stockarmazem_";
const ARMAZEM_KV_PREFIX = "armazem:";

// ========== INTERFACES ==========
export interface StockArmazem {
  id: string;
  empresaId: string;
  armazemId: string;
  artigoId: string;
  quantidade: number;
  quantidadeReservada: number;
  quantidadeDisponivel: number;
  localizacao?: string;
  lote?: string;
  dataValidade?: string;
  custoMedio: number;
  criadoEm: string;
  atualizadoEm: string;
}

// ========== FUNÇÕES AUXILIARES ==========

function gerarId(): string {
  return `stock_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}

function calcularQuantidadeDisponivel(quantidade: number, quantidadeReservada: number): number {
  return quantidade - quantidadeReservada;
}

function validarSaldoStock(quantidade: number, quantidadeReservada: number): string | null {
  if (!Number.isFinite(quantidade) || !Number.isFinite(quantidadeReservada)) {
    return 'Quantidade de stock invalida';
  }

  if (quantidadeReservada < 0) {
    return 'Stock reservado nao pode ser negativo';
  }

  if (quantidade < 0) {
    return 'Stock insuficiente no armazem';
  }

  if (calcularQuantidadeDisponivel(quantidade, quantidadeReservada) < 0) {
    return 'Operacao invalida: stock reservado superior ao saldo disponivel no armazem';
  }

  return null;
}

function arredondarCustoMedio(valor: number): number {
  return Math.round((Number(valor) + Number.EPSILON) * 100) / 100;
}

// Media ponderada: mistura o custo medio actual (para a quantidade que ja
// estava no armazem) com o custo desta entrada, na proporcao das quantidades.
// Sem isto o custoMedio ficava sempre 0 (nunca era escrito fora da criacao
// inicial do registo), fazendo o CMV de vendas cair para 0 silenciosamente.
export function calcularNovoCustoMedio(
  quantidadeAnterior: number,
  custoMedioAnterior: number,
  quantidadeEntrada: number,
  custoUnitarioEntrada: number,
): number {
  if (!(quantidadeEntrada > 0) || !(custoUnitarioEntrada > 0)) {
    return custoMedioAnterior;
  }

  if (!(quantidadeAnterior > 0) || !(custoMedioAnterior > 0)) {
    return arredondarCustoMedio(custoUnitarioEntrada);
  }

  const valorAnterior = quantidadeAnterior * custoMedioAnterior;
  const valorEntrada = quantidadeEntrada * custoUnitarioEntrada;
  return arredondarCustoMedio((valorAnterior + valorEntrada) / (quantidadeAnterior + quantidadeEntrada));
}

function normalizarReferenciaArmazem(armazemId: string): string {
  const referencia = String(armazemId || '').trim();
  return referencia.startsWith(ARMAZEM_KV_PREFIX)
    ? referencia.slice(ARMAZEM_KV_PREFIX.length)
    : referencia;
}

// ✅ Função helper para garantir que SEMPRE salva com prefixo correto
async function salvarStock(stock: StockArmazem): Promise<void> {
  const chaveCompleta = stock.id.startsWith(STOCK_ARMAZEM_PREFIX) 
    ? `${STOCK_ARMAZEM_PREFIX}${stock.id.replace(STOCK_ARMAZEM_PREFIX, '')}` 
    : `${STOCK_ARMAZEM_PREFIX}${stock.id}`;
  
  await kv.set(chaveCompleta, stock);
  // console.log('[StockArmazem] 💾 Stock salvo com chave:', chaveCompleta);
}

// ========== CRIAR STOCK ==========
export async function criarStock(dados: Omit<StockArmazem, 'id' | 'criadoEm' | 'atualizadoEm'>): Promise<StockArmazem> {
  const armazemIdCanonical = normalizarReferenciaArmazem(dados.armazemId);
  // 🚨 PROTEÇÃO ANTI-DUPLICADOS: Verificar se JÁ EXISTE antes de criar!
  // console.log('[StockArmazem] 🔍 Verificando duplicados antes de criar...');
  const existente = await buscarStockArtigoArmazem(dados.empresaId, dados.artigoId, armazemIdCanonical);
  
  if (existente) {
    // console.error('🚨 TENTATIVA DE CRIAR DUPLICADO BLOQUEADA!');
    // console.error(`[StockArmazem] Empresa: ${dados.empresaId}`);
    // console.error(`[StockArmazem] Artigo: ${dados.artigoId}`);
    // console.error(`[StockArmazem] Armazém: ${dados.armazemId}`);
    // console.error(`[StockArmazem] Registro existente: ${existente.id}`);
    
    throw new Error(`ERRO CRÍTICO: Tentativa de criar stock duplicado! Já existe registro para empresa=${dados.empresaId}, artigo=${dados.artigoId}, armazém=${dados.armazemId}. Use upsertStock() ao invés de criarStock().`);
  }
  
  const agora = new Date().toISOString();
  const quantidadeReservada = dados.quantidadeReservada || 0;
  const erroSaldo = validarSaldoStock(dados.quantidade, quantidadeReservada);
  if (erroSaldo) {
    throw new Error(erroSaldo);
  }

  const stock: StockArmazem = {
    ...dados,
    id: gerarId(),
    armazemId: armazemIdCanonical,
    quantidadeDisponivel: calcularQuantidadeDisponivel(dados.quantidade, quantidadeReservada),
    criadoEm: agora,
    atualizadoEm: agora,
  };

  // ✅ CRÍTICO: Salvar com prefixo completo para getByPrefix funcionar!
  await salvarStock(stock);
  // console.log('[StockArmazem] ✅ Novo stock criado (sem duplicados):', stock.id);
  return stock;
}

// 🆕 FUNÇÃO UPSERT SEGURA - Cria ou atualiza sem duplicar
export async function upsertStock(dados: {
  empresaId: string;
  armazemId: string;
  artigoId: string;
  quantidade: number;
  quantidadeReservada?: number;
  custoMedio?: number;
  localizacao?: string;
  lote?: string;
  dataValidade?: string;
}): Promise<StockArmazem> {
  // console.log('[StockArmazem] 🔄 UPSERT: Buscando stock existente...');
  const armazemIdCanonical = normalizarReferenciaArmazem(dados.armazemId);
  
  // Buscar stock existente
  let stock = await buscarStockArtigoArmazem(dados.empresaId, dados.artigoId, armazemIdCanonical);
  
  if (stock) {
    const quantidadeReservada = dados.quantidadeReservada ?? stock.quantidadeReservada;
    const erroSaldo = validarSaldoStock(dados.quantidade, quantidadeReservada);
    if (erroSaldo) {
      throw new Error(erroSaldo);
    }

    // ✅ ATUALIZAR existente
    // console.log(`[StockArmazem] 📝 Stock encontrado, atualizando: ${stock.id}`);
    const stockAtualizado: StockArmazem = {
      ...stock,
      armazemId: armazemIdCanonical,
      quantidade: dados.quantidade,
      quantidadeReservada,
      quantidadeDisponivel: calcularQuantidadeDisponivel(dados.quantidade, quantidadeReservada),
      custoMedio: dados.custoMedio ?? stock.custoMedio,
      localizacao: dados.localizacao ?? stock.localizacao,
      lote: dados.lote ?? stock.lote,
      dataValidade: dados.dataValidade ?? stock.dataValidade,
      atualizadoEm: new Date().toISOString(),
    };
    
    await salvarStock(stockAtualizado);
    // console.log('[StockArmazem] ✅ Stock atualizado com sucesso');
    return stockAtualizado;
  } else {
    const quantidadeReservada = dados.quantidadeReservada || 0;
    const erroSaldo = validarSaldoStock(dados.quantidade, quantidadeReservada);
    if (erroSaldo) {
      throw new Error(erroSaldo);
    }

    // ✅ CRIAR novo (sem passar por criarStock que agora bloqueia duplicados)
    // console.log('[StockArmazem] ➕ Stock não encontrado, criando novo...');
    const agora = new Date().toISOString();
    const novoStock: StockArmazem = {
      id: gerarId(),
      empresaId: dados.empresaId,
      armazemId: armazemIdCanonical,
      artigoId: dados.artigoId,
      quantidade: dados.quantidade,
      quantidadeReservada,
      quantidadeDisponivel: calcularQuantidadeDisponivel(dados.quantidade, quantidadeReservada),
      custoMedio: dados.custoMedio || 0,
      localizacao: dados.localizacao,
      lote: dados.lote,
      dataValidade: dados.dataValidade,
      criadoEm: agora,
      atualizadoEm: agora,
    };
    
    await salvarStock(novoStock);
    // console.log('[StockArmazem] ✅ Novo stock criado:', novoStock.id);
    return novoStock;
  }
}

// ========== BUSCAR STOCK ==========
export async function buscarStockPorId(id: string): Promise<StockArmazem | null> {
  // Buscar com ou sem prefixo
  const comPrefixo = id.startsWith(STOCK_ARMAZEM_PREFIX) ? id : `${STOCK_ARMAZEM_PREFIX}${id}`;
  return await kv.get(comPrefixo);
}

// Buscar stock de um artigo em um armazém específico
export async function buscarStockArtigoArmazem(empresaId: string, artigoId: string, armazemId: string): Promise<StockArmazem | null> {
  const todosStocks = await kv.getByPrefix<StockArmazem>(STOCK_ARMAZEM_PREFIX);
  const armazemIdNormalizado = normalizarReferenciaArmazem(armazemId);
  
  // 🔍 BUSCAR TODOS os registros que correspondem (para detectar duplicados)
  const registrosEncontrados = todosStocks.filter(s => 
    s.empresaId === empresaId && 
    s.artigoId === artigoId && 
    (s.armazemId === armazemId || s.armazemId === armazemIdNormalizado || normalizarReferenciaArmazem(s.armazemId) === armazemIdNormalizado)
  );
  
  // 🚨 ALERTA CRÍTICO: Detectar duplicados
  if (registrosEncontrados.length > 1) {
    // console.error('🚨🚨🚨 ALERTA CRÍTICO: DUPLICADOS DETECTADOS! 🚨🚨🚨');
    // console.error(`[StockArmazem] Empresa: ${empresaId}`);
    // console.error(`[StockArmazem] Artigo: ${artigoId}`);
    // console.error(`[StockArmazem] Armazém: ${armazemId}`);
    // console.error(`[StockArmazem] Registros duplicados: ${registrosEncontrados.length}`);
    // console.error(`[StockArmazem] IDs:`, registrosEncontrados.map(r => r.id));
    
    // ⚠️ AVISO: Sistema continuará com o primeiro registro, mas isso precisa ser corrigido!
    // console.error('⚠️ AÇÃO NECESSÁRIA: Execute a rota de reset de stocks para corrigir!');
  }
  
  return registrosEncontrados[0] || null;
}

// ========== LISTAR STOCKS ==========

// Listar todo o stock de um armazém
export async function listarStockPorArmazem(armazemId: string): Promise<StockArmazem[]> {
  const todosStocks = await kv.getByPrefix<StockArmazem>(STOCK_ARMAZEM_PREFIX);
  const armazemIdNormalizado = normalizarReferenciaArmazem(armazemId);
  return todosStocks.filter(s =>
    s.armazemId === armazemId ||
    s.armazemId === armazemIdNormalizado ||
    normalizarReferenciaArmazem(s.armazemId) === armazemIdNormalizado
  );
}

// Listar armazéns onde um artigo está disponível
export async function listarArmazensPorArtigo(artigoId: string): Promise<StockArmazem[]> {
  const todosStocks = await kv.getByPrefix<StockArmazem>(STOCK_ARMAZEM_PREFIX);
  return todosStocks.filter(s => s.artigoId === artigoId && s.quantidade > 0);
}

// Listar todo o stock de uma empresa (todos os armazéns)
export async function listarStockPorEmpresa(empresaId: string): Promise<StockArmazem[]> {
  if (!empresaId) {
    // console.error('[StockArmazem] ❌ empresaId é obrigatório');
    throw new Error('empresaId é obrigatório');
  }
  
  const todosStocks = await kv.getByPrefix<StockArmazem>(STOCK_ARMAZEM_PREFIX);
  const stocksDaEmpresa = todosStocks.filter(s => s.empresaId === empresaId);
  
  // console.log(`[StockArmazem] 📊 Stocks encontrados para empresa ${empresaId}:`, stocksDaEmpresa.length);
  return stocksDaEmpresa;
}

// Obter resumo de stock de um artigo (somatório de todos os armazéns)
export async function obterResumoStockArtigo(artigoId: string): Promise<{
  quantidadeTotal: number;
  quantidadeReservada: number;
  quantidadeDisponivel: number;
  armazens: Array<{ armazemId: string; quantidade: number }>;
}> {
  const stocks = await listarArmazensPorArtigo(artigoId);
  
  const quantidadeTotal = stocks.reduce((sum, s) => sum + s.quantidade, 0);
  const quantidadeReservada = stocks.reduce((sum, s) => sum + s.quantidadeReservada, 0);
  const quantidadeDisponivel = stocks.reduce((sum, s) => sum + s.quantidadeDisponivel, 0);
  
  const armazens = stocks.map(s => ({
    armazemId: s.armazemId,
    quantidade: s.quantidade,
  }));
  
  return {
    quantidadeTotal,
    quantidadeReservada,
    quantidadeDisponivel,
    armazens,
  };
}

// ✅ NOVA: Obter stock total de um artigo para uma empresa (todos os armazéns)
export async function obterStockTotalArtigo(empresaId: string, artigoId: string): Promise<number> {
  try {
    const todosStocks = await listarStockPorEmpresa(empresaId);
    const stocksDoArtigo = todosStocks.filter(s => s.artigoId === artigoId);
    const total = stocksDoArtigo.reduce((sum, s) => sum + s.quantidade, 0);
    console.log(`[StockArmazem] Stock total do artigo ${artigoId}:`, total, 'registros:', stocksDoArtigo.length);
    return total;
  } catch (error) {
    console.error('[StockArmazem] Erro ao obter stock total:', error);
    return 0;
  }
}

// ✅ NOVA: Obter mapa de stock para múltiplos artigos (otimizado para POS)
export async function obterMapaStockArtigos(empresaId: string, artigosIds: string[]): Promise<Record<string, number>> {
  try {
    console.log(`[StockArmazem] 🔍 Buscando stock para ${artigosIds.length} artigos da empresa ${empresaId}`);
    const todosStocks = await listarStockPorEmpresa(empresaId);
    console.log(`[StockArmazem] 📊 Total de stocks encontrados na empresa:`, todosStocks.length);
    
    const mapaStock: Record<string, number> = {};
    
    // Inicializar todos com 0
    artigosIds.forEach(id => mapaStock[id] = 0);
    
    // Somar stocks por artigo
    todosStocks.forEach(stock => {
      if (artigosIds.includes(stock.artigoId)) {
        mapaStock[stock.artigoId] = (mapaStock[stock.artigoId] || 0) + stock.quantidade;
        console.log(`[StockArmazem] ✅ Artigo ${stock.artigoId}: +${stock.quantidade} (total: ${mapaStock[stock.artigoId]})`);
      }
    });
    
    // Mostrar resumo
    const comStock = Object.values(mapaStock).filter(q => q > 0).length;
    const semStock = Object.values(mapaStock).filter(q => q <= 0).length;
    console.log(`[StockArmazem] 📊 Resumo: ${comStock} artigos COM stock, ${semStock} artigos SEM stock`);
    
    return mapaStock;
  } catch (error) {
    console.error('[StockArmazem] Erro ao obter mapa de stock:', error);
    return {};
  }
}

// ========== ATUALIZAR STOCK ==========
export async function atualizarQuantidade(
  empresaId: string,
  artigoId: string,
  armazemId: string,
  quantidade: number,
  operacao: 'adicionar' | 'remover' | 'definir'
): Promise<StockArmazem> {
  const armazemIdCanonical = normalizarReferenciaArmazem(armazemId);
  let stock = await buscarStockArtigoArmazem(empresaId, artigoId, armazemIdCanonical);
  
  // Se não existe, criar novo registro
  if (!stock) {
    if (operacao === 'remover') {
      throw new Error('Stock não encontrado para remoção');
    }
    
    stock = await criarStock({
      empresaId,
      armazemId: armazemIdCanonical,
      artigoId,
      quantidade: operacao === 'definir' ? quantidade : quantidade,
      quantidadeReservada: 0,
      quantidadeDisponivel: quantidade,
      custoMedio: 0,
    });
    
    return stock;
  }
  
  // Atualizar quantidade existente
  let novaQuantidade = stock.quantidade;
  
  switch (operacao) {
    case 'adicionar':
      novaQuantidade += quantidade;
      break;
    case 'remover':
      novaQuantidade -= quantidade;
      break;
    case 'definir':
      novaQuantidade = quantidade;
      break;
  }

  const erroSaldo = validarSaldoStock(novaQuantidade, stock.quantidadeReservada);
  if (erroSaldo) {
    throw new Error(erroSaldo);
  }
  
  const stockAtualizado: StockArmazem = {
    ...stock,
    armazemId: armazemIdCanonical,
    quantidade: novaQuantidade,
    quantidadeDisponivel: calcularQuantidadeDisponivel(novaQuantidade, stock.quantidadeReservada),
    atualizadoEm: new Date().toISOString(),
  };
  
  await salvarStock(stockAtualizado);
  
  return stockAtualizado;
}

// Função compatível com movimentos-stock.tsx
export async function atualizarStockArmazem(dados: {
  empresaId: string;
  armazemId: string;
  armazemCodigo: string;
  armazemNome: string;
  artigoId: string;
  artigoCodigo: string;
  artigoNome: string;
  quantidadeDelta: number; // Positivo para entrada, negativo para saída
  custoUnitarioEntrada?: number; // Custo desta entrada, usado para actualizar a media ponderada
}): Promise<{ success: boolean; data?: StockArmazem; error?: string }> {
  try {
    // console.log('[StockArmazem] 📦 Atualizando stock:', dados);
    const armazemIdCanonical = normalizarReferenciaArmazem(dados.armazemId);

    let stock = await buscarStockArtigoArmazem(dados.empresaId, dados.artigoId, armazemIdCanonical);

    // Se não existe, criar novo
    if (!stock) {
      if (dados.quantidadeDelta < 0) {
        return { success: false, error: 'Stock não encontrado para saída' };
      }

      stock = await criarStock({
        empresaId: dados.empresaId,
        armazemId: armazemIdCanonical,
        artigoId: dados.artigoId,
        quantidade: dados.quantidadeDelta,
        quantidadeReservada: 0,
        quantidadeDisponivel: dados.quantidadeDelta,
        custoMedio: dados.custoUnitarioEntrada && dados.custoUnitarioEntrada > 0
          ? arredondarCustoMedio(dados.custoUnitarioEntrada)
          : 0,
      });

      return { success: true, data: stock };
    }

    // Calcular nova quantidade
    const novaQuantidade = stock.quantidade + dados.quantidadeDelta;
    const erroSaldo = validarSaldoStock(novaQuantidade, stock.quantidadeReservada);
    if (erroSaldo) {
      return { success: false, error: erroSaldo };
    }

    const custoMedio = dados.quantidadeDelta > 0
      ? calcularNovoCustoMedio(stock.quantidade, stock.custoMedio, dados.quantidadeDelta, dados.custoUnitarioEntrada || 0)
      : stock.custoMedio;

    const stockAtualizado: StockArmazem = {
      ...stock,
      armazemId: armazemIdCanonical,
      quantidade: novaQuantidade,
      quantidadeDisponivel: calcularQuantidadeDisponivel(novaQuantidade, stock.quantidadeReservada),
      custoMedio,
      atualizadoEm: new Date().toISOString(),
    };
    
    await salvarStock(stockAtualizado);
    
    return { success: true, data: stockAtualizado };
    
  } catch (error) {
    // console.error('[StockArmazem] ❌ Erro ao atualizar stock:', error);
    return { success: false, error: error.message };
  }
}

// Transferir stock entre armazéns
export async function transferirStock(
  empresaId: string,
  artigoId: string,
  armazemOrigemId: string,
  armazemDestinoId: string,
  quantidade: number
): Promise<{ origem: StockArmazem; destino: StockArmazem }> {
  const armazemOrigemCanonical = normalizarReferenciaArmazem(armazemOrigemId);
  const armazemDestinoCanonical = normalizarReferenciaArmazem(armazemDestinoId);
  if (!Number.isFinite(quantidade) || quantidade <= 0) {
    throw new Error('Quantidade invalida para transferencia');
  }

  if (armazemOrigemCanonical === armazemDestinoCanonical) {
    throw new Error('Armazem de origem e destino devem ser diferentes');
  }

  const stockOrigem = await buscarStockArtigoArmazem(empresaId, artigoId, armazemOrigemCanonical);
  if (!stockOrigem || stockOrigem.quantidadeDisponivel < quantidade) {
    throw new Error('Stock insuficiente no armazem de origem');
  }

  const stockDestinoAnterior = await buscarStockArtigoArmazem(empresaId, artigoId, armazemDestinoCanonical);
  let origemAtualizada: StockArmazem | null = null;

  try {
    origemAtualizada = await atualizarQuantidade(empresaId, artigoId, armazemOrigemCanonical, quantidade, 'remover');

    // ✅ O destino herda o custo do armazem de origem (media ponderada com o
    // que ja tinha) em vez de atualizarQuantidade, que criava o registo novo
    // sempre com custoMedio=0 e nunca actualizava o custo em cima existente.
    const custoMedioDestino = calcularNovoCustoMedio(
      stockDestinoAnterior?.quantidade || 0,
      stockDestinoAnterior?.custoMedio || 0,
      quantidade,
      stockOrigem.custoMedio || 0,
    );
    const destinoAtualizada = await upsertStock({
      empresaId,
      artigoId,
      armazemId: armazemDestinoCanonical,
      quantidade: (stockDestinoAnterior?.quantidade || 0) + quantidade,
      quantidadeReservada: stockDestinoAnterior?.quantidadeReservada,
      custoMedio: custoMedioDestino,
      localizacao: stockDestinoAnterior?.localizacao,
      lote: stockDestinoAnterior?.lote,
      dataValidade: stockDestinoAnterior?.dataValidade,
    });

    return {
      origem: origemAtualizada,
      destino: destinoAtualizada,
    };
  } catch (error) {
    if (origemAtualizada) {
      await upsertStock({
        empresaId,
        artigoId,
        armazemId: armazemOrigemCanonical,
        quantidade: stockOrigem.quantidade,
        quantidadeReservada: stockOrigem.quantidadeReservada,
        custoMedio: stockOrigem.custoMedio,
        localizacao: stockOrigem.localizacao,
        lote: stockOrigem.lote,
        dataValidade: stockOrigem.dataValidade,
      });
    }

    if (stockDestinoAnterior) {
      await upsertStock({
        empresaId,
        artigoId,
        armazemId: armazemDestinoCanonical,
        quantidade: stockDestinoAnterior.quantidade,
        quantidadeReservada: stockDestinoAnterior.quantidadeReservada,
        custoMedio: stockDestinoAnterior.custoMedio,
        localizacao: stockDestinoAnterior.localizacao,
        lote: stockDestinoAnterior.lote,
        dataValidade: stockDestinoAnterior.dataValidade,
      });
    }

    throw error;
  }
}
// Reservar stock
export async function reservarStock(
  empresaId: string,
  artigoId: string,
  armazemId: string,
  quantidade: number
): Promise<StockArmazem> {
  if (!Number.isFinite(quantidade) || quantidade <= 0) {
    throw new Error('Quantidade invalida para reserva');
  }

  const armazemIdCanonical = normalizarReferenciaArmazem(armazemId);
  const stock = await buscarStockArtigoArmazem(empresaId, artigoId, armazemIdCanonical);
  
  if (!stock) {
    throw new Error('Stock não encontrado');
  }
  
  if (stock.quantidadeDisponivel < quantidade) {
    throw new Error('Stock disponível insuficiente');
  }
  
  const stockAtualizado: StockArmazem = {
    ...stock,
    armazemId: armazemIdCanonical,
    quantidadeReservada: stock.quantidadeReservada + quantidade,
    quantidadeDisponivel: stock.quantidadeDisponivel - quantidade,
    atualizadoEm: new Date().toISOString(),
  };
  
  await salvarStock(stockAtualizado);
  // console.log(`[StockArmazem] 🔒 Stock reservado: ${quantidade} unidades`);
  
  return stockAtualizado;
}

// Liberar stock reservado
export async function liberarStock(
  empresaId: string,
  artigoId: string,
  armazemId: string,
  quantidade: number
): Promise<StockArmazem> {
  if (!Number.isFinite(quantidade) || quantidade <= 0) {
    throw new Error('Quantidade invalida para libertacao de reserva');
  }

  const armazemIdCanonical = normalizarReferenciaArmazem(armazemId);
  const stock = await buscarStockArtigoArmazem(empresaId, artigoId, armazemIdCanonical);
  
  if (!stock) {
    throw new Error('Stock não encontrado');
  }
  
  if (stock.quantidadeReservada < quantidade) {
    throw new Error('Quantidade a liberar maior que reservada');
  }
  
  const stockAtualizado: StockArmazem = {
    ...stock,
    armazemId: armazemIdCanonical,
    quantidadeReservada: stock.quantidadeReservada - quantidade,
    quantidadeDisponivel: stock.quantidadeDisponivel + quantidade,
    atualizadoEm: new Date().toISOString(),
  };
  
  await salvarStock(stockAtualizado);
  // console.log(`[StockArmazem] 🔓 Stock liberado: ${quantidade} unidades`);
  
  return stockAtualizado;
}

// ========== ESTATÍSTICAS ==========
export async function obterEstatisticasArmazem(armazemId: string, empresaId?: string): Promise<{
  totalArtigos: number;
  quantidadeTotal: number;
  quantidadeReservada: number;
  quantidadeDisponivel: number;
  valorTotal: number;
}> {
  const todosStocks = await kv.getByPrefix<StockArmazem>(STOCK_ARMAZEM_PREFIX);
  const armazemIdNormalizado = normalizarReferenciaArmazem(armazemId);
  
  // Filtrar por armazemId e opcionalmente por empresaId
  let stocks = todosStocks.filter(
    s =>
      s.armazemId === armazemId ||
      s.armazemId === armazemIdNormalizado ||
      normalizarReferenciaArmazem(s.armazemId) === armazemIdNormalizado
  );
  if (empresaId) {
    stocks = stocks.filter(s => s.empresaId === empresaId);
  }
  
  // console.log(`[StockArmazem] 📊 Estatísticas do armazém ${armazemId}:`, {
  //   totalRegistros: stocks.length,
  //   empresaId: empresaId || 'TODAS'
  // });
  
  return {
    totalArtigos: stocks.length,
    quantidadeTotal: stocks.reduce((sum, s) => sum + s.quantidade, 0),
    quantidadeReservada: stocks.reduce((sum, s) => sum + s.quantidadeReservada, 0),
    quantidadeDisponivel: stocks.reduce((sum, s) => sum + s.quantidadeDisponivel, 0),
    valorTotal: stocks.reduce((sum, s) => sum + (s.quantidade * s.custoMedio), 0),
  };
}

// ========== DELETAR ==========
export async function deletarStock(id: string): Promise<void> {
  const chaveCompleta = id.startsWith(STOCK_ARMAZEM_PREFIX) ? id : `${STOCK_ARMAZEM_PREFIX}${id}`;
  await kv.del(chaveCompleta);
  // console.log('[StockArmazem] 🗑️ Stock deletado:', id);
}
