interface ProdutoVenda {
  id: string;
  catalogo_id: string;
  preco_venda: number;
  preco_final?: number;     // ✅ Preço final calculado pela API
  observacoes?: string;
  data_validade: string;
  qtdade_estoque?: number;  // ✅ Agora incluído no endpoint unificado
  empresa_id?: string;      // ✅ ID da empresa que está vendendo o produto
  createdAt: string;
  updatedAt: string;
}

interface ProdutoEstoque {
  id: string;
  catalogo_id: string;
  venda_id: string;
  quantidade: number;
  createdAt: string;
  updatedAt: string;
}

interface ProdutoCatalogo {
  $id: string;
  codigo_ean: string;
  codigo_interno: string;
  nome: string;
  descricao?: string;
  preco_base: number;
  preco_fabrica?: number;
  pmc?: number;
  desconto_comercial: number;
  laboratorio?: string;
  categoria?: string;
  subcategoria?: string;
  lab_nome?: string;      // ✅ Nome do laboratório
  cat_nome?: string;      // ✅ Nome da categoria
}

interface ProdutoCompleto {
  id: string;
  $id?: string;          // ✅ Para compatibilidade com Appwrite
  catalogo_id: string;
  nome: string;
  descricao?: string;
  preco_venda: number;
  preco_base: number;
  preco_final?: number;  // ✅ Preço final para exibição na listagem
  quantidade_estoque: number;
  observacoes?: string;
  data_validade: string;
  codigo_ean: string;
  codigo_interno: string;
  laboratorio?: string;
  categoria?: string;
  lab_nome?: string;      // ✅ Nome do laboratório
  cat_nome?: string;      // ✅ Nome da categoria
  empresa_id?: string;    // ✅ ID da empresa que está vendendo o produto
}

interface ResponseVenda {
  items: ProdutoVenda[];
  total: number;
}

interface ResponseEstoque {
  items: ProdutoEstoque[];
  total: number;
}

interface ResponseCatalogo {
  documents: ProdutoCatalogo[];
  total: number;
}

class ProdutosVendaService {
  private baseUrl = process.env.NEXT_PUBLIC_BFF_API_URL!;

  private getAuthHeaders(): Record<string, string> {
    const token = localStorage.getItem('access_token');
    if (!token) {
      console.warn("⚠️ Nenhum token de acesso encontrado. Usuário pode não estar autenticado.");
    }
    return {
      "accept": "application/json",
      "Content-Type": "application/json",
      ...(token && { "Authorization": `Bearer ${token}` })
    };
  }

  /**
   * Busca dados do usuário logado via endpoint /auth/me
   * @returns Promise com os dados do usuário ou null se erro
   */
  private async buscarUsuarioLogado(): Promise<any | null> {
    try {
      const token = localStorage.getItem('access_token');

      if (!token) {
        console.error('🔑 Token de acesso não encontrado');
        return null;
      }


      const response = await fetch(`${this.baseUrl}/auth/me`, {
        method: 'GET',
        headers: this.getAuthHeaders(),
      });

      if (!response.ok) {
        console.error('❌ Erro ao buscar dados do usuário:', response.status, response.statusText);
        return null;
      }

      const userData = await response.json();

      return userData;
    } catch (error) {
      console.error('❌ Erro exception ao buscar dados do usuário:', error);
      return null;
    }
  }

  /**
   * Extrai o IDs de empresa dos dados do usuário
   * @param userData - Dados do usuário do endpoint /auth/me
   * @returns Array de string com os IDs das empresas ou array vazio se não encontrado
   */
  private extrairEmpresasIds(userData: any | null): string[] {
    if (!userData) {
      return [];
    }


    // Buscar o campo empresasDados
    const empresasDados = userData.empresasDados || userData["empresas-dados"] || userData.empresas_dados;

    if (Array.isArray(empresasDados)) {
      return empresasDados;
    }

    return [];
  }

  async buscarProdutosVenda(page: number = 1): Promise<ResponseVenda> {
    try {
      const response = await fetch(`${this.baseUrl}/produtos-venda?page=${page}&limit=100`, {
        method: "GET",
        headers: this.getAuthHeaders(),
      });

      if (!response.ok) {
        if (response.status === 401) {
          throw new Error("Não autorizado. Por favor, faça login novamente.");
        }
        throw new Error(`Erro ao buscar produtos de venda: ${response.status}`);
      }

      return await response.json();
    } catch (error) {
      console.error("Erro ao buscar produtos de venda:", error);
      throw error;
    }
  }

  async buscarProdutoVendaPorId(id: string): Promise<ProdutoVenda | null> {
    try {

      const response = await fetch(`${this.baseUrl}/produtos-venda/${id}`, {
        method: "GET",
        headers: this.getAuthHeaders(),
      });

      if (!response.ok) {
        if (response.status === 404) {
          console.warn(`⚠️ [ProdutosVenda] Produto de venda não encontrado: ${id}`);
          return null;
        }
        if (response.status === 401) {
          throw new Error("Não autorizado. Por favor, faça login novamente.");
        }
        throw new Error(`Erro ao buscar produto de venda: ${response.status}`);
      }

      const produto = await response.json();
      return produto;
    } catch (error) {
      console.error(`❌ [ProdutosVenda] Erro ao buscar produto de venda ${id}:`, error);
      throw error;
    }
  }

  // NOTA: Método removido pois agora usamos apenas o endpoint unificado /produtos-venda para estoque
  // Mantemos buscarProdutosCatalogo() pois ainda precisamos dos dados de laboratório e categoria

  async buscarProdutosCatalogo(page: number = 1): Promise<ResponseCatalogo> {
    try {
      const response = await fetch(`${this.baseUrl}/produtos-catalogo?page=${page}`, {
        method: "GET",
        headers: this.getAuthHeaders(),
      });

      if (!response.ok) {
        if (response.status === 401) {
          throw new Error("Não autorizado. Por favor, faça login novamente.");
        }
        throw new Error(`Erro ao buscar produtos do catálogo: ${response.status}`);
      }

      return await response.json();
    } catch (error) {
      console.error("Erro ao buscar produtos do catálogo:", error);
      throw error;
    }
  }

  async buscarProdutosCompletos(page: number = 1): Promise<ProdutoCompleto[]> {
    try {

      // Buscar dados de venda (que agora inclui estoque) e catálogo em paralelo
      const [vendaResponse, catalogoResponse] = await Promise.all([
        this.buscarProdutosVenda(page),
        this.buscarProdutosCatalogo(page),
      ]);



      // Criar um mapa de produtos do catálogo por id para busca rápida
      const catalogoMap = new Map<string, ProdutoCatalogo>();
      catalogoResponse.documents.forEach(catalogo => {
        catalogoMap.set(catalogo.$id, catalogo);
      });

      // Combinar os dados
      const produtosCompletos: ProdutoCompleto[] = vendaResponse.items.map(venda => {
        const catalogo = catalogoMap.get(venda.catalogo_id);

        return {
          id: venda.id,
          $id: venda.id,                     // ✅ Para compatibilidade
          catalogo_id: venda.catalogo_id,
          nome: catalogo?.nome || `Produto ${venda.catalogo_id}`,
          descricao: catalogo?.descricao || venda.observacoes,
          preco_venda: venda.preco_venda,
          preco_final: venda.preco_final,    // ✅ Incluir preco_final da API
          preco_base: catalogo?.preco_base || 0,
          quantidade_estoque: venda.qtdade_estoque || 0, // ✅ Agora vem do endpoint /produtos-venda
          observacoes: venda.observacoes,
          data_validade: venda.data_validade,
          codigo_ean: catalogo?.codigo_ean || "",
          codigo_interno: catalogo?.codigo_interno || "",
          laboratorio: catalogo?.laboratorio,
          categoria: catalogo?.categoria,
          lab_nome: catalogo?.lab_nome,      // ✅ Incluir lab_nome do catálogo
          cat_nome: catalogo?.cat_nome,      // ✅ Incluir cat_nome do catálogo
          empresa_id: venda.empresa_id,      // ✅ Incluir empresa_id do produto de venda
        };
      });

      return produtosCompletos;
    } catch (error) {
      console.error("❌ Erro ao buscar produtos completos:", error);
      throw error;
    }
  }

  /**
   * Busca produtos completos excluindo os da própria empresa do usuário logado
   * @param page - Número da página
   * @returns Promise<ProdutoCompleto[]> - Lista de produtos filtrados
   */
  async buscarProdutosCompletosParaCompra(page: number = 1): Promise<ProdutoCompleto[]> {
    try {

      // Buscar dados do usuário logado em paralelo com os produtos
      const [produtosCompletos, usuarioLogado] = await Promise.all([
        this.buscarProdutosCompletos(page),
        this.buscarUsuarioLogado()
      ]);

      // Se não conseguir buscar dados do usuário, retornar todos os produtos
      if (!usuarioLogado) {
        console.warn("⚠️ Não foi possível buscar dados do usuário, retornando todos os produtos");
        return produtosCompletos;
      }

      // Extrair IDs das empresas do usuário
      const empresasUsuario = this.extrairEmpresasIds(usuarioLogado);

      if (empresasUsuario.length === 0) {
        console.warn("⚠️ Usuário não possui empresas associadas, retornando todos os produtos");
        return produtosCompletos;
      }


      // Filtrar produtos que NÃO são da empresa do usuário
      const produtosFiltrados = produtosCompletos.filter(produto => {
        // Se o produto não tem empresa_id, manter na lista
        if (!produto.empresa_id) {
          return true;
        }

        // Excluir produtos das empresas do usuário
        const isProdutoDaPropriaEmpresa = empresasUsuario.includes(produto.empresa_id);



        return !isProdutoDaPropriaEmpresa;
      });


      return produtosFiltrados;
    } catch (error) {
      console.error("❌ Erro ao buscar produtos para compra:", error);
      // Em caso de erro, retornar produtos sem filtro para não quebrar a aplicação
      console.warn("⚠️ Retornando produtos sem filtro devido ao erro");
      return this.buscarProdutosCompletos(page);
    }
  }

  async buscarTodosProdutosCompletos(): Promise<ProdutoCompleto[]> {
    try {

      let todosProdutos: ProdutoCompleto[] = [];
      let page = 1;
      let hasMore = true;

      while (hasMore) {
        const produtosPagina = await this.buscarProdutosCompletosParaCompra(page);

        if (produtosPagina.length > 0) {
          todosProdutos.push(...produtosPagina);
          page++;
          // Se retornou menos que o esperado, provavelmente é a última página
          if (produtosPagina.length < 20) { // assumindo que API retorna ~20 por página
            hasMore = false;
          }
        } else {
          hasMore = false;
        }
      }

      return todosProdutos;
    } catch (error) {
      console.error("❌ Erro ao buscar todos os produtos:", error);
      throw error;
    }
  }

  async buscarProdutosPorNome(nome: string, page: number = 1): Promise<ProdutoCompleto[]> {
    try {
      // Por enquanto, vamos buscar todos os produtos e filtrar pelo nome
      // Em uma implementação real, a API deveria suportar filtros
      const produtos = await this.buscarProdutosCompletosParaCompra(page);

      if (!nome.trim()) {
        return produtos;
      }

      const termoBusca = nome.toLowerCase().trim();
      return produtos.filter(produto =>
        produto.nome.toLowerCase().includes(termoBusca) ||
        produto.descricao?.toLowerCase().includes(termoBusca) ||
        produto.codigo_ean.toLowerCase().includes(termoBusca) ||
        produto.codigo_interno.toLowerCase().includes(termoBusca)
      );
    } catch (error) {
      console.error("❌ Erro ao buscar produtos por nome:", error);
      throw error;
    }
  }

  /**
   * Atualiza a quantidade de estoque de um produto
   */
  async atualizarQuantidadeEstoque(produtoId: string, novaQuantidade: number): Promise<{ success: boolean, data?: any, error?: string }> {
    try {

      const response = await fetch(`${this.baseUrl}/produtos-venda/${produtoId}`, {
        method: "PUT",
        headers: this.getAuthHeaders(),
        body: JSON.stringify({
          qtdade_estoque: novaQuantidade
        }),
      });

      if (!response.ok) {
        if (response.status === 401) {
          throw new Error("Não autorizado. Por favor, faça login novamente.");
        }
        const errorData = await response.json();
        throw new Error(`Erro ao atualizar estoque: ${errorData.message || response.status}`);
      }

      const data = await response.json();
      return { success: true, data };
    } catch (error: any) {
      console.error(`❌ Erro ao atualizar estoque do produto ${produtoId}:`, error);
      return { success: false, error: error.message };
    }
  }

  /**
   * Reduz a quantidade de estoque de um produto
   */
  async reduzirEstoque(produtoId: string, quantidadeReduzir: number): Promise<{ success: boolean, data?: any, error?: string }> {
    try {

      // Primeiro buscar o produto atual para obter a quantidade atual
      const produtoAtual = await this.buscarProdutoVendaPorId(produtoId);
      if (!produtoAtual) {
        return { success: false, error: "Produto não encontrado" };
      }

      // Buscar dados completos para obter quantidade atual de estoque
      const produtosCompletos = await this.buscarProdutosCompletos();
      const produtoCompleto = produtosCompletos.find(p => p.id === produtoId);

      if (!produtoCompleto) {
        return { success: false, error: "Produto completo não encontrado" };
      }

      const quantidadeAtual = produtoCompleto.quantidade_estoque;
      const novaQuantidade = Math.max(0, quantidadeAtual - quantidadeReduzir);


      return await this.atualizarQuantidadeEstoque(produtoId, novaQuantidade);
    } catch (error: any) {
      console.error(`❌ Erro ao reduzir estoque do produto ${produtoId}:`, error);
      return { success: false, error: error.message };
    }
  }

  /**
   * Processa ajuste de estoque para múltiplos produtos (para checkout)
   */
  async processarAjusteEstoquePedido(itens: Array<{ produto: any, quantidade: number }>): Promise<{ sucessos: number, erros: number, detalhes: Array<{ produto: string, sucesso: boolean, erro?: string }> }> {

    let sucessos = 0;
    let erros = 0;
    const detalhes: Array<{ produto: string, sucesso: boolean, erro?: string }> = [];

    for (const item of itens) {
      try {
        const produtoId = item.produto.id;
        const quantidadeReduzir = item.quantidade;


        const resultado = await this.reduzirEstoque(produtoId, quantidadeReduzir);

        if (resultado.success) {
          sucessos++;
          detalhes.push({
            produto: item.produto.nome,
            sucesso: true
          });
        } else {
          erros++;
          detalhes.push({
            produto: item.produto.nome,
            sucesso: false,
            erro: resultado.error
          });
          console.error(`❌ Erro ao ajustar estoque: ${item.produto.nome} - ${resultado.error}`);
        }
      } catch (error: any) {
        erros++;
        detalhes.push({
          produto: item.produto.nome,
          sucesso: false,
          erro: error.message
        });
        console.error(`💥 Erro ao processar estoque do produto ${item.produto.nome}:`, error);
      }
    }

    return { sucessos, erros, detalhes };
  }
}

export const produtosVendaService = new ProdutosVendaService();
export type { ProdutoCompleto, ProdutoVenda, ProdutoEstoque, ProdutoCatalogo };
