import * as kv from "./kv_store.tsx";
import * as movimentosStock from "./movimentos-stock.tsx";
import * as stockLotes from "./stock-lotes.tsx";
import * as stockArmazem from "./stock-armazem.tsx";
import { createLogger } from "./logger.tsx";

const logger = createLogger('Artigos');

// ========== TIPOS ==========

export type TipoArtigo = "produto" | "servico";
export type UnidadeArtigo = "Un" | "Kg" | "L" | "m" | "m2" | "m3" | "Cx" | "Pc" | "Hr" | "Dia";
export type MetodoCusteioArtigo = "custo_medio" | "fifo" | "fefo" | "lifo" | "manual";

export interface Artigo {
  id: string;
  empresaId: string; // Multi-tenant: cada empresa tem seus artigos
  codigo: string; // Cï¿½digo interno (ex: ART001)
  codigoBarras?: string; // Cï¿½digo de barras para POS/scanner
  nome?: string;
  descricao?: string;
  tipo?: TipoArtigo; // produto ou serviï¿½o
  unidade?: UnidadeArtigo;
  precoCompra?: number;
  precoVenda?: number;
  metodoCusteio?: MetodoCusteioArtigo;
  iva?: number; // % de IVA (0, 16, etc)
  ivaIncluso?: boolean; // IVA incluso no preï¿½o
  ivaIncluidoNaoLiquidado?: boolean; // IVA incluso no preco mas ja liquidado a montante (nao entra na Base de Incidencia nem no Total de IVA do documento)
  motivoIsencao?: string;
  codigoMotivoIsencao?: string;
  desconto?: number; // Desconto em %
  fornecedorId?: string; // Fornecedor principal
  fornecedorNome?: string; // Nome do fornecedor (desnormalizado para performance)
  fornecedorCodigo?: string; // Cï¿½digo do fornecedor (desnormalizado)
  fornecedorNuit?: string; // NUIT do fornecedor (desnormalizado)
  armazemId?: string; // ID do armazï¿½m onde o artigo estï¿½ alocado
  estoqueAtual?: number; // Apenas para produtos
  estoqueMinimo?: number; // Alerta de estoque mï¿½nimo
  dataEntrada?: string; // Data de entrada no estoque (formato ISO: YYYY-MM-DD)
  dataValidade?: string; // Data de validade do produto (formato ISO: YYYY-MM-DD)
  lote?: string; // Ãšltimo lote registado para entrada do artigo
  imagemUrl?: string; // URL da imagem do artigo
  // âï¿½â¬¦ NOVOS CAMPOS DO DOCUMENTO DE COMPRA
  numeroDocumento?: string; // Nï¿½mero do documento do fornecedor (ex: FT 2025/123)
  tipoDocumento?: string; // Tipo do documento (Factura, Factura-Recibo, etc)
  dataDocumento?: string; // Data do documento do fornecedor (formato ISO: YYYY-MM-DD)
  observacoes?: string;
  criadoPor?: string;
  criadoPorNome?: string;
  criadoPorEmail?: string;
  atualizadoPor?: string;
  atualizadoPorNome?: string;
  atualizadoPorEmail?: string;
  ativo: boolean;
  dataCriacao: string;
  dataAtualizacao?: string;
}

// ========== FUNÃ’â¬¡Ã’â¬¢ES DE GESTÃ’ï¿½O DE ARTIGOS ==========

/**
 * Gerar código automático para artigo
 */
async function gerarCodigoArtigo(empresaId: string): Promise<string> {
  const artigos = await listarArtigos(empresaId);
  const proximoNumero = artigos.length + 1;
  return `ART${proximoNumero.toString().padStart(4, '0')}`; // ART0001, ART0002, etc
}

async function registrarEntradaDiretaComLote(
  artigo: Artigo,
  dados: Partial<Artigo> & { empresaId: string },
  estoqueInicial: number,
  dataReferencia: string,
  lote?: string,
): Promise<{ success: boolean; error?: string }> {
  if (!dados.armazemId || artigo.tipo !== "produto" || estoqueInicial <= 0) {
    return { success: true };
  }

  const movimentoResult = await movimentosStock.criarMovimento({
    empresaId: dados.empresaId,
    artigoId: artigo.id,
    tipo: "entrada",
    quantidade: estoqueInicial,
    motivo: "recepcao",
    armazemId: dados.armazemId,
    lote,
    custoUnitario: dados.precoCompra || artigo.precoCompra || 0,
    documentoTipo: dados.tipoDocumento,
    documentoNumero: dados.numeroDocumento,
    dataMovimento: dados.dataDocumento || dataReferencia,
    responsavel: dados.criadoPorNome || dados.criadoPor || (dados as any).usuarioAuditoriaNome,
    responsavelId: dados.criadoPor || (dados as any).usuarioAuditoriaId,
    responsavelNome: dados.criadoPorNome || (dados as any).usuarioAuditoriaNome,
    responsavelEmail: dados.criadoPorEmail || (dados as any).usuarioAuditoriaEmail,
    criadoPor: dados.criadoPor || (dados as any).usuarioAuditoriaId,
    criadoPorNome: dados.criadoPorNome || (dados as any).usuarioAuditoriaNome,
    criadoPorEmail: dados.criadoPorEmail || (dados as any).usuarioAuditoriaEmail,
    observacoes: `Entrada automática do documento ${dados.tipoDocumento || ""} ${dados.numeroDocumento || ""}`.trim(),
  });

  if (!movimentoResult.success || !movimentoResult.data) {
    return { success: false, error: movimentoResult.error || "Falha ao criar movimento de entrada" };
  }

  const loteAnterior = await stockLotes.buscarLotePorIdentidade(
    dados.empresaId,
    artigo.id,
    dados.armazemId,
    lote,
    dados.dataValidade,
  );

  try {
    await stockLotes.upsertLote({
      empresaId: dados.empresaId,
      artigoId: artigo.id,
      armazemId: dados.armazemId,
      lote,
      dataValidade: dados.dataValidade,
      quantidade: estoqueInicial,
      custoUnitario: dados.precoCompra || artigo.precoCompra || 0,
      fornecedorId: dados.fornecedorId || artigo.fornecedorId,
      documentoCompraId: dados.numeroDocumento,
    });
  } catch (error) {
    const reversao = await movimentosStock.deletarMovimento(movimentoResult.data.id);
    if (!reversao.success) {
      return { success: false, error: reversao.error || "Falha ao reverter movimento de entrada" };
    }
    if (loteAnterior) {
      await stockLotes.upsertLote({
        empresaId: loteAnterior.empresaId,
        artigoId: loteAnterior.artigoId,
        armazemId: loteAnterior.armazemId,
        lote: loteAnterior.lote,
        dataValidade: loteAnterior.dataValidade,
        dataFabricacao: loteAnterior.dataFabricacao,
        quantidade: loteAnterior.quantidade,
        quantidadeReservada: loteAnterior.quantidadeReservada,
        custoUnitario: loteAnterior.custoUnitario,
        fornecedorId: loteAnterior.fornecedorId,
        documentoCompraId: loteAnterior.documentoCompraId,
        localizacao: loteAnterior.localizacao,
        status: loteAnterior.status,
      });
    }
    return { success: false, error: error instanceof Error ? error.message : String(error) };
  }

  return { success: true };
}
async function enriquecerArtigosComLoteAtual(empresaId: string, artigos: Artigo[]): Promise<Artigo[]> {
  if (artigos.length === 0) {
    return artigos;
  }

  const lotes = await stockLotes.listarLotesPorEmpresa(empresaId);
  const lotesMaisRecentes = new Map<string, { lote: string; referencia: string }>();

  for (const lote of lotes) {
    if (!lote.lote?.trim()) continue;

    const referencia = lote.atualizadoEm || lote.criadoEm || "";
    const atual = lotesMaisRecentes.get(lote.artigoId);

    if (!atual || referencia > atual.referencia) {
      lotesMaisRecentes.set(lote.artigoId, {
        lote: lote.lote.trim(),
        referencia,
      });
    }
  }

  return artigos.map((artigo) => ({
    ...artigo,
    lote: lotesMaisRecentes.get(artigo.id)?.lote || artigo.lote,
  }));
}

/**
 * Criar novo artigo
 */
export async function criarArtigo(dados: Partial<Artigo> & { empresaId: string }): Promise<{ success: boolean; data?: Artigo; error?: string }> {
  try {
    logger.info('[Artigos] Ã°Å¸â¬Âµ DADOS RECEBIDOS para criar artigo:', JSON.stringify(dados, null, 2));
    
    // âï¿½â¬¦ Validar dados obrigatórios - APENAS empresa é obrigatório (fornecedor é opcional!)
    if (!dados.empresaId) {
      return { success: false, error: "Empresa ï¿½ obrigatï¿½ria" };
    }

    // Validar preços se fornecidos
    if ((dados.precoCompra !== undefined && dados.precoCompra < 0) || 
        (dados.precoVenda !== undefined && dados.precoVenda < 0)) {
      return { success: false, error: "Preï¿½os nï¿½o podem ser negativos" };
    }

    // Usar código fornecido pelo usuário ou gerar automaticamente
    const codigo = dados.codigo
      ? dados.codigo
      : await gerarCodigoArtigo(dados.empresaId);

    const artigoExistente = await buscarArtigoPorCodigo(dados.empresaId, codigo);

    // Se o produto já existe, tratamos a operação como nova entrada no mesmo artigo.
    if (artigoExistente) {
      const estoqueInicialExistente = dados.estoqueAtual || 0;
      const entradaDiretaExistente = Boolean(
        artigoExistente.tipo === "produto" && dados.armazemId && estoqueInicialExistente > 0
      );
      const loteExistente = entradaDiretaExistente
        ? ((dados.lote && dados.lote.trim()) || await stockLotes.sugerirProximoLote(dados.empresaId, artigoExistente.id, artigoExistente.codigo))
        : (dados.lote || artigoExistente.lote);

      const artigoAnterior = { ...artigoExistente };
      const artigoAtualizado = {
        ...artigoExistente,
        nome: dados.nome ?? artigoExistente.nome,
        descricao: dados.descricao ?? artigoExistente.descricao,
        unidade: dados.unidade ?? artigoExistente.unidade,
        codigoBarras: dados.codigoBarras ?? artigoExistente.codigoBarras,
        precoCompra: dados.precoCompra ?? artigoExistente.precoCompra,
        precoVenda: dados.precoVenda ?? artigoExistente.precoVenda,
        metodoCusteio: (dados.metodoCusteio as MetodoCusteioArtigo | undefined) ?? artigoExistente.metodoCusteio ?? "custo_medio",
        iva: dados.iva ?? artigoExistente.iva,
        ivaIncluso: dados.ivaIncluso ?? artigoExistente.ivaIncluso,
        ivaIncluidoNaoLiquidado: dados.ivaIncluidoNaoLiquidado ?? artigoExistente.ivaIncluidoNaoLiquidado,
        motivoIsencao: dados.motivoIsencao ?? artigoExistente.motivoIsencao,
        codigoMotivoIsencao: dados.codigoMotivoIsencao ?? artigoExistente.codigoMotivoIsencao,
        desconto: dados.desconto ?? artigoExistente.desconto,
        fornecedorId: dados.fornecedorId ?? artigoExistente.fornecedorId,
        fornecedorNome: dados.fornecedorNome ?? artigoExistente.fornecedorNome,
        fornecedorCodigo: dados.fornecedorCodigo ?? artigoExistente.fornecedorCodigo,
        fornecedorNuit: dados.fornecedorNuit ?? artigoExistente.fornecedorNuit,
        armazemId: dados.armazemId || artigoExistente.armazemId,
        estoqueMinimo: dados.estoqueMinimo ?? artigoExistente.estoqueMinimo,
        dataValidade: dados.dataValidade || artigoExistente.dataValidade,
        lote: loteExistente,
        imagemUrl: dados.imagemUrl ?? artigoExistente.imagemUrl,
        numeroDocumento: dados.numeroDocumento || artigoExistente.numeroDocumento,
        tipoDocumento: dados.tipoDocumento || artigoExistente.tipoDocumento,
        dataDocumento: dados.dataDocumento || artigoExistente.dataDocumento,
        observacoes: dados.observacoes ?? artigoExistente.observacoes,
        ativo: dados.ativo !== undefined ? dados.ativo : artigoExistente.ativo,
        dataEntrada: artigoExistente.dataEntrada,
        dataAtualizacao: new Date().toISOString(),
      } as Artigo;

      await kv.set(`artigo:${artigoExistente.id}`, artigoAtualizado);

      if (entradaDiretaExistente) {
        const entradaResult = await registrarEntradaDiretaComLote(
          artigoAtualizado,
          dados,
          estoqueInicialExistente,
          new Date().toISOString().split("T")[0],
          loteExistente,
        );

        if (!entradaResult.success) {
          await kv.set(`artigo:${artigoExistente.id}`, artigoAnterior);
          return { success: false, error: entradaResult.error };
        }
      }

      return { success: true, data: artigoAtualizado };
    }

    // Gerar ID
    const id = `artigo_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

    logger.info('[Artigos] Ã°Å¸â¬Âµ Código que será usado:', codigo);
    logger.info('[Artigos] Ã°Å¸â¬Âµ Nome que será usado:', dados.nome);

    const dataAtual = new Date().toISOString();
    
    // âï¿½â¬¦ VALIDAR ESTOQUE: Se tipo produto e tem armazém, estoqueAtual DEVE SER ZERO
    // O stock será criado automaticamente pelo movimento de entrada
    const estoqueInicial = dados.estoqueAtual || 0;
    const entradaDiretaEmStock = Boolean(
      dados.armazemId && dados.tipo === 'produto' && estoqueInicial > 0
    );
    const loteResolvido = entradaDiretaEmStock
      ? ((dados.lote && dados.lote.trim()) || await stockLotes.sugerirProximoLote(dados.empresaId, id, codigo))
      : dados.lote;
    
    logger.info('[Artigos] Ã°Å¸â¬Âµ estoqueInicial recebido:', estoqueInicial);
    logger.info('[Artigos] Ã°Å¸â¬Âµ armazemId recebido:', dados.armazemId);
    logger.info('[Artigos] Ã°Å¸â¬Âµ tipo recebido:', dados.tipo);
    
    const artigo = {
      id,
      codigo,
      empresaId: dados.empresaId,
      codigoBarras: dados.codigoBarras,
      nome: dados.nome,
      descricao: dados.descricao,
      tipo: dados.tipo,
      unidade: dados.unidade,
      precoCompra: dados.precoCompra,
      precoVenda: dados.precoVenda,
      metodoCusteio: (dados.metodoCusteio as MetodoCusteioArtigo | undefined) || "custo_medio",
      iva: dados.iva,
      ivaIncluso: dados.ivaIncluso,
      ivaIncluidoNaoLiquidado: dados.ivaIncluidoNaoLiquidado,
      motivoIsencao: dados.motivoIsencao,
      codigoMotivoIsencao: dados.codigoMotivoIsencao,
      ativo: dados.ativo !== undefined ? dados.ativo : true,
      fornecedorId: dados.fornecedorId,
      fornecedorNome: dados.fornecedorNome,
      fornecedorCodigo: dados.fornecedorCodigo,
      fornecedorNuit: dados.fornecedorNuit,
      armazemId: dados.armazemId,
      // âÅ¡Â Ã¯Â¸Â CRÃ’ÂTICO: Se tem armazém, o estoqueAtual começa em 0
      // O movimento de entrada irá criar o stock correto
      estoqueAtual: dados.armazemId && dados.tipo === 'produto' ? 0 : estoqueInicial,
      estoqueMinimo: dados.estoqueMinimo,
      dataValidade: dados.dataValidade,
      lote: loteResolvido,
      imagemUrl: dados.imagemUrl,
      // âï¿½â¬¦ CAMPOS DO DOCUMENTO DE COMPRA
      numeroDocumento: dados.numeroDocumento,
      tipoDocumento: dados.tipoDocumento,
      dataDocumento: dados.dataDocumento,
      observacoes: dados.observacoes,
      criadoPor: dados.criadoPor || (dados as any).usuarioAuditoriaId,
      criadoPorNome: dados.criadoPorNome || (dados as any).usuarioAuditoriaNome,
      criadoPorEmail: dados.criadoPorEmail || (dados as any).usuarioAuditoriaEmail,
      dataCriacao: dataAtual,
      dataEntrada: dataAtual.split('T')[0], // âï¿½â¬¦ AUTOMÃTICO: Data de entrada no formato YYYY-MM-DD
    } as Artigo;

    // console.log('[Artigos] Ã°Å¸â¬Âµ Artigo FINAL que será salvo:', JSON.stringify(artigo, null, 2));
    // console.log(`[Artigos] Ã°Å¸â¬Âµ Stock inicial solicitado: ${estoqueInicial}, Stock salvo no artigo: ${artigo.estoqueAtual}`);

    // Se tipo for serviço, remover campos de estoque
    if (artigo.tipo === "servico") {
      delete artigo.estoqueAtual;
      delete artigo.estoqueMinimo;
      delete artigo.dataEntrada; // Serviços não têm data de entrada no estoque
    }

    // Salvar artigo
    await kv.set(`artigo:${id}`, artigo);

    logger.info(`[Artigos] âï¿½â¬¦ Artigo criado: ${codigo} - ${dados.nome}`);

    // âï¿½â¬¦ NOVO: Se houver armazém e quantidade > 0, criar movimento de entrada automático
    if (dados.armazemId && artigo.tipo === 'produto' && estoqueInicial > 0) {
      logger.info(`[Artigos] Ã°Å¸â¬Âµ Criando movimento de entrada automático no armazém ${dados.armazemId} com quantidade ${estoqueInicial}`);
      
      const entradaResult = await registrarEntradaDiretaComLote(
        artigo,
        dados,
        estoqueInicial,
        dataAtual.split('T')[0],
        loteResolvido,
      );

      if (!entradaResult.success) {
        await kv.del(`artigo:${id}`);
        return { success: false, error: entradaResult.error || 'Falha ao criar entrada de stock do artigo' };
      }

      logger.info(`[Artigos] âï¿½â¬¦ Movimento de entrada criado automaticamente`);
    } else {
      logger.info(`[Artigos] âÅ¡Â Ã¯Â¸Â Movimento NÃ’ï¿½O criado. Dados:`, {
        armazemId: dados.armazemId,
        tipo: artigo.tipo,
        estoqueInicial
      });
    }

    return { success: true, data: artigo };
  } catch (error) {
    // console.error("[Artigos] Erro ao criar artigo:", error);
    return { success: false, error: error.message };
  }
}

/**
 * Buscar artigo por ID
 */
export async function buscarArtigoPorId(id: string): Promise<Artigo | null> {
  try {
    const chave = `artigo:${id}`;
    // console.log(`[Artigos] Ã°Å¸â¬Â Buscando artigo com chave: \"${chave}\"`);
    const artigo = await kv.get(chave);
    // console.log(`[Artigos] Ã°Å¸ï¿½SÂ¦ Resultado da busca:`, artigo ? `Encontrado: ${artigo.codigo}` : 'NÃ’ï¿½O ENCONTRADO');
    return artigo as Artigo | null;
  } catch (error) {
    // console.error("Artigos] Erro ao buscar artigo:", error);
    return null;
  }
}

/**
 * Buscar artigo por código
 */
export async function buscarArtigoPorCodigo(empresaId: string, codigo: string): Promise<Artigo | null> {
  try {
    const codigoNormalizado = (codigo || '').trim().toLowerCase();
    if (!empresaId || !codigoNormalizado) return null;

    const todosArtigos = await kv.getByPrefix<Artigo>("artigo:");
    return todosArtigos.find((artigo) =>
      artigo?.empresaId === empresaId &&
      String(artigo.codigo || '').trim().toLowerCase() === codigoNormalizado
    ) || null;
  } catch (error) {
    return null;
  }
}

/**
 * Listar artigos de uma empresa
 */
export async function listarArtigos(empresaId: string, filtros?: {
  ativo?: boolean;
  tipo?: TipoArtigo;
  fornecedorId?: string;
}): Promise<Artigo[]> {
  try {
    logger.info('Ã°Å¸ï¿½SÂ¦ [Artigos] Listando artigos para empresaId:', empresaId);
    logger.info('Ã°Å¸ï¿½SÂ¦ [Artigos] Filtros:', filtros);
    
    const todosArtigos = await kv.getByPrefix<Artigo>("artigo:");
    
    logger.info('Ã°Å¸ï¿½SÂ¦ [Artigos] Total de artigos no KV:', todosArtigos.length);
    
    let artigos = todosArtigos.filter((a) => a && a.empresaId === empresaId);
    
    logger.info('Ã°Å¸ï¿½SÂ¦ [Artigos] Artigos após filtrar por empresaId:', artigos.length);

    // Aplicar filtros
    if (filtros?.ativo !== undefined) {
      artigos = artigos.filter((a) => a.ativo === filtros.ativo);
      logger.info('Ã°Å¸ï¿½SÂ¦ [Artigos] Artigos após filtro ativo:', artigos.length);
    }
    
    if (filtros?.tipo) {
      artigos = artigos.filter((a) => a.tipo === filtros.tipo);
      logger.info('Ã°Å¸ï¿½SÂ¦ [Artigos] Artigos após filtro tipo:', artigos.length);
    }
    
    if (filtros?.fornecedorId) {
      artigos = artigos.filter((a) => a.fornecedorId === filtros.fornecedorId);
      logger.info('Ã°Å¸ï¿½SÂ¦ [Artigos] Artigos após filtro fornecedorId:', artigos.length);
    }

    // Ordenar por código
    artigos.sort((a, b) => a.codigo.localeCompare(b.codigo));
    
    logger.info('Ã°Å¸ï¿½SÂ¦ [Artigos] Artigos finais:', artigos.length);
    if (artigos.length > 0) {
      logger.info('Ã°Å¸ï¿½SÂ¦ [Artigos] Primeiro artigo:', artigos[0]);
    }

    return await enriquecerArtigosComLoteAtual(empresaId, artigos);
  } catch (error) {
    logger.error("âÂï¿½ [Artigos] Erro ao listar artigos:", error);
    return [];
  }
}

/**
 * Atualizar artigo
 */
export async function atualizarArtigo(
  id: string,
  dados: Partial<Artigo>
): Promise<{ success: boolean; data?: Artigo; error?: string }> {
  try {
    const artigo = await buscarArtigoPorId(id);
    
    if (!artigo) {
      return { success: false, error: "Artigo nï¿½o encontrado" };
    }

    // Validar preços se estiverem sendo atualizados
    if (dados.precoCompra !== undefined && dados.precoCompra < 0) {
      return { success: false, error: "Preï¿½o de compra nï¿½o pode ser negativo" };
    }
    
    if (dados.precoVenda !== undefined && dados.precoVenda < 0) {
      return { success: false, error: "Preï¿½o de venda nï¿½o pode ser negativo" };
    }

    const artigoAtualizado = {
      ...artigo,
      ...dados,
      id: artigo.id, // Garantir que ID não mude
      codigo: artigo.codigo, // Garantir que código não mude
      empresaId: artigo.empresaId, // Garantir que empresa não mude
      dataCriacao: artigo.dataCriacao, // Garantir que data de criação não mude
      criadoPor: artigo.criadoPor,
      criadoPorNome: artigo.criadoPorNome,
      criadoPorEmail: artigo.criadoPorEmail,
      atualizadoPor: dados.atualizadoPor || (dados as any).usuarioAuditoriaId,
      atualizadoPorNome: dados.atualizadoPorNome || (dados as any).usuarioAuditoriaNome,
      atualizadoPorEmail: dados.atualizadoPorEmail || (dados as any).usuarioAuditoriaEmail,
      dataAtualizacao: new Date().toISOString(),
    };

    // Se mudou para serviço, remover campos de estoque
    if (artigoAtualizado.tipo === "servico") {
      // ✅ Reclassificar um produto com stock existente para servico apagava
      // as unidades do registo sem qualquer movimento de ajuste nem rasto —
      // um desfasamento permanente entre o stock historico (facturas/notas
      // antigas que o venderam como produto) e a classificacao actual.
      if (artigo.tipo !== "servico" && Number(artigo.estoqueAtual || 0) !== 0) {
        return {
          success: false,
          error: `Nao e possivel reclassificar "${artigo.nome || artigo.codigo}" para servico com stock existente (${artigo.estoqueAtual} unidade(s)). Reduza o stock a zero (ex: ajuste de inventario) antes de mudar o tipo.`,
        };
      }
      delete artigoAtualizado.estoqueAtual;
      delete artigoAtualizado.estoqueMinimo;
      delete artigoAtualizado.dataEntrada; // Serviços não têm data de entrada no estoque
    }

    await kv.set(`artigo:${id}`, artigoAtualizado);

    // console.log(`[Artigos] âï¿½â¬¦ Artigo atualizado: ${id}`);

    return { success: true, data: artigoAtualizado };
  } catch (error) {
    // console.error("[Artigos] Erro ao atualizar artigo:", error);
    return { success: false, error: error.message };
  }
}

/**
 * Atualizar estoque do artigo
 */
export async function atualizarEstoque(
  id: string,
  quantidade: number,
  operacao: "adicionar" | "remover" | "definir"
): Promise<{ success: boolean; data?: Artigo; error?: string }> {
  try {
    const artigo = await buscarArtigoPorId(id);
    
    if (!artigo) {
      return { success: false, error: "Artigo nÃ’Â£o encontrado" };
    }

    if (artigo.tipo === "servico") {
      return { success: false, error: "Serviï¿½os nï¿½o possuem estoque" };
    }

    let novoEstoque = artigo.estoqueAtual || 0;

    switch (operacao) {
      case "adicionar":
        novoEstoque += quantidade;
        break;
      case "remover":
        novoEstoque -= quantidade;
        // âï¿½â¬¦ PERMITIR ESTOQUE NEGATIVO (para vendas sob encomenda)
        // Apenas avisar no log se ficar negativo
        if (novoEstoque < 0) {
          logger.warn(`[Artigos] âÅ¡Â Ã¯Â¸Â ATENÃ’â¬¡Ã’ï¿½O: Estoque do artigo ${artigo.codigo} ficou NEGATIVO: ${novoEstoque}`);
          logger.warn(`[Artigos] Ã°Å¸ï¿½"Â¡ Isso pode indicar uma venda sob encomenda ou necessidade de reposição urgente.`);
        }
        break;
      case "definir":
        novoEstoque = quantidade;
        break;
    }

    return await atualizarArtigo(id, { estoqueAtual: novoEstoque });
  } catch (error) {
    // console.error("[Artigos] Erro ao atualizar estoque:", error);
    return { success: false, error: error.message };
  }
}

/**
 * Deletar artigo
 */
export async function deletarArtigo(id: string): Promise<{ success: boolean; error?: string }> {
  try {
    const artigo = await buscarArtigoPorId(id);
    
    if (!artigo) {
      return { success: false, error: "Artigo nÃ’Â£o encontrado" };
    }

    // console.log(`[Artigos] Ã°Å¸ï¿½ï¿½ï¿½Ã¯Â¸Â Iniciando deleção em cascata do artigo: ${artigo.codigo} - ${artigo.nome}`);

    // 1. Buscar todos os registros de stock_armazem deste artigo
    const stockArmazemKeys = (await kv.getByPrefixWithKeys("stockarmazem_"))
      .filter((stockReg: any) => stockReg.value?.empresaId === artigo.empresaId && stockReg.value?.artigoId === id);
    // console.log(`[Artigos] Ã°Å¸ï¿½SÂ¦ Encontrados ${stockArmazemKeys.length} registros de stock em armazéns`);

    // 2. Para cada armazém com stock, criar movimento de SAÃ’ÂDA com motivo "Artigo Deletado"
    const dataDelecao = new Date().toISOString();
    const dataDelecaoFormatada = dataDelecao.split('T')[0];

    for (const stockReg of stockArmazemKeys) {
      const stock = stockReg.value as any;
      
      if (stock.quantidade > 0) {
        // Criar movimento de saída
        const movimentoId = `${Date.now()}-delecao-${Math.random().toString(36).substr(2, 9)}`;
        const movimento = {
          id: movimentoId,
          empresaId: artigo.empresaId,
          artigoId: id,
          artigoCodigo: artigo.codigo,
          artigoNome: artigo.nome,
          tipo: 'saida',
          quantidade: stock.quantidade,
          motivo: 'artigo_deletado',
          armazemId: stock.armazemId,
          armazemCodigo: '', // Será preenchido se necessário
          armazemNome: '', // Será preenchido se necessário
          documentoTipo: 'Deleï¿½ï¿½o de Artigo',
          documentoNumero: `DEL-${artigo.codigo}`,
          observacoes: `Artigo "${artigo.nome}" foi deletado do sistema. Stock de ${stock.quantidade} unidades foi zerado.`,
          responsavel: 'Sistema',
          dataCriacao: dataDelecao,
          dataMovimento: dataDelecaoFormatada,
        };

        await kv.set(`movimento_stock:${movimentoId}`, movimento);
        // console.log(`[Artigos] Ã°Å¸ï¿½SÂ Movimento de saída criado: ${stock.quantidade} unidades do armazém ${stock.armazemId}`);
      }

      // Deletar o registro de stock_armazem
      await kv.del(stockReg.key);
      // console.log(`[Artigos] Ã°Å¸ï¿½ï¿½ï¿½Ã¯Â¸Â Stock deletado: ${stockReg.key}`);
    }

    // 3. Deletar o artigo
    await kv.del(`artigo:${id}`);

    // console.log(`[Artigos] âï¿½â¬¦ Artigo deletado com sucesso: ${id}`);
    // console.log(`[Artigos] Ã°Å¸ï¿½SÅ  Resumo: ${stockArmazemKeys.length} registros de stock removidos`);

    return { success: true };
  } catch (error) {
    // console.error("[Artigos] Erro ao deletar artigo:", error);
    return { success: false, error: error.message };
  }
}

/**
 * Ativar/Desativar artigo
 */
export async function toggleArtigo(id: string, ativo: boolean): Promise<{ success: boolean; data?: Artigo; error?: string }> {
  return await atualizarArtigo(id, { ativo });
}

/**
 * Listar artigos com estoque baixo
 */
export async function listarArtigosEstoqueBaixo(empresaId: string): Promise<any[]> {
  try {
    const artigos = await listarArtigos(empresaId, { tipo: "produto", ativo: true });
    const stocks = await stockArmazem.listarStockPorEmpresa(empresaId);

    return artigos
      .map((artigo) => {
        const quantidade = stocks
          .filter((stock) => stock.artigoId === artigo.id)
          .reduce((total, stock) => total + (Number(stock.quantidade) || 0), 0);
        const estoqueMinimo = Number(artigo.estoqueMinimo || 0);
        const artigoNome = artigo.nome || artigo.descricao || artigo.codigo;

        return {
          ...artigo,
          estoqueAtual: quantidade,
          quantidade,
          estoqueMinimo,
          artigoId: artigo.id,
          artigoCodigo: artigo.codigo,
          artigoNome,
        };
      })
      .filter((artigo) => artigo.quantidade <= 0 || (artigo.estoqueMinimo > 0 && artigo.quantidade <= artigo.estoqueMinimo))
      .sort((a, b) => {
        const prioridadeA = a.quantidade <= 0 ? 0 : 1;
        const prioridadeB = b.quantidade <= 0 ? 0 : 1;
        if (prioridadeA !== prioridadeB) return prioridadeA - prioridadeB;
        return a.quantidade - b.quantidade;
      });
  } catch (error) {
    // console.error("[Artigos] Erro ao listar artigos com estoque baixo:", error);
    return [];
  }
}
