/** * Serviço para gerenciar carrinho via API BFF * Integração com https://bff-dev.saveinmed.com.br/api/v1/carrinhos */ const BFF_BASE_URL = process.env.NEXT_PUBLIC_BFF_API_URL!; /** * Interface para dados do carrinho na API */ export interface CarrinhoApiData { itens: string[]; // IDs dos produtos codigoInterno: string; // Código interno do carrinho labNome: string[]; // Nomes dos laboratórios quantidade: number[]; // Quantidades de cada produto valorTotal: number[]; // Valores totais de cada produto usuarios: string; // ID do usuário } /** * Interface para resposta da API */ export interface CarrinhoApiResponse { success: boolean; data?: any; error?: string; message?: string; } /** * Serviço de carrinho para API BFF */ export const carrinhoApiService = { /** * Obtém o token de autenticação do localStorage */ getAuthToken: (): string | null => { return localStorage.getItem('access_token'); }, /** * Obtém o ID do usuário atual */ getUserId: (): string | null => { try { const userStr = localStorage.getItem('user'); if (!userStr) return null; const user = JSON.parse(userStr); return user.$id || user.id || user.usuario_id || null; } catch { return null; } }, /** * Busca dados do usuário via API /me se não estiver no localStorage */ fetchUserData: async (): Promise => { try { const token = carrinhoApiService.getAuthToken(); if (!token) return null; const response = await fetch(`${BFF_BASE_URL}/auth/me`, { method: 'GET', headers: { 'accept': 'application/json', 'Authorization': `Bearer ${token}`, }, }); if (response.ok) { const userData = await response.json(); localStorage.setItem('user', JSON.stringify(userData)); return userData; } return null; } catch (error) { console.error('Erro ao buscar dados do usuário:', error); return null; } }, /** * Gera código interno único para o carrinho */ generateCodigoInterno: (): string => { const timestamp = Date.now(); const random = Math.floor(Math.random() * 10000); return `CARR${timestamp}${random}`; }, /** * Converte produtos locais para formato da API */ convertProdutosToApiFormat: (produtos: any[]): Partial => { const itens: string[] = []; const labNome: string[] = []; const quantidade: number[] = []; const valorTotal: number[] = []; produtos.forEach(item => { const produto = item.produto; const qtd = item.quantidade; const preco = produto.preco_final || 0; itens.push(produto.$id || produto.id); quantidade.push(qtd); valorTotal.push(preco * qtd); // Extrair nome do laboratório let nomelab = ''; if (produto.lab_nome) { nomelab = produto.lab_nome; } else if (produto.laboratorio) { if (typeof produto.laboratorio === 'string') { nomelab = produto.laboratorio; } else if (produto.laboratorio.nome) { nomelab = produto.laboratorio.nome; } } labNome.push(nomelab || 'Laboratório não informado'); }); return { itens, labNome, quantidade, valorTotal, }; }, /** * Cria um novo carrinho na API */ criar: async (produtos: any[]): Promise => { try { const token = carrinhoApiService.getAuthToken(); if (!token) { return { success: false, error: 'Token de autenticação não encontrado' }; } let userId = carrinhoApiService.getUserId(); // Se não tem usuário no localStorage, buscar via API if (!userId) { const userData = await carrinhoApiService.fetchUserData(); userId = userData?.$id || userData?.id || userData?.usuario_id; } if (!userId) { return { success: false, error: 'ID do usuário não encontrado' }; } const apiData = carrinhoApiService.convertProdutosToApiFormat(produtos); const payload = { documentId: "unique()", data: { ...apiData, codigoInterno: carrinhoApiService.generateCodigoInterno(), usuarios: userId, } }; const response = await fetch(`${BFF_BASE_URL}/carrinhos`, { method: 'POST', headers: { 'accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, }, body: JSON.stringify(payload), }); const data = await response.json(); if (response.ok) { return { success: true, data }; } else { console.error('❌ Erro ao criar carrinho:', data); return { success: false, error: data.message || 'Erro ao criar carrinho' }; } } catch (error) { console.error('💥 Erro na criação do carrinho:', error); return { success: false, error: 'Erro de conexão ao criar carrinho' }; } }, /** * Atualiza um carrinho existente na API */ atualizar: async (carrinhoId: string, produtos: any[]): Promise => { try { const token = carrinhoApiService.getAuthToken(); if (!token) { return { success: false, error: 'Token de autenticação não encontrado' }; } let userId = carrinhoApiService.getUserId(); // Se não tem usuário no localStorage, buscar via API if (!userId) { const userData = await carrinhoApiService.fetchUserData(); userId = userData?.$id || userData?.id || userData?.usuario_id; } if (!userId) { return { success: false, error: 'ID do usuário não encontrado' }; } const apiData = carrinhoApiService.convertProdutosToApiFormat(produtos); const payload = { data: { ...apiData, codigoInterno: carrinhoApiService.generateCodigoInterno(), usuarios: userId, } }; const response = await fetch(`${BFF_BASE_URL}/carrinhos/${carrinhoId}`, { method: 'PATCH', headers: { 'accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, }, body: JSON.stringify(payload), }); const data = await response.json(); if (response.ok) { return { success: true, data }; } else { console.error('❌ Erro ao atualizar carrinho:', data); return { success: false, error: data.message || 'Erro ao atualizar carrinho' }; } } catch (error) { console.error('💥 Erro na atualização do carrinho:', error); return { success: false, error: 'Erro de conexão ao atualizar carrinho' }; } }, /** * Exclui um carrinho da API */ excluir: async (carrinhoId: string): Promise => { try { const token = carrinhoApiService.getAuthToken(); if (!token) { return { success: false, error: 'Token de autenticação não encontrado' }; } const response = await fetch(`${BFF_BASE_URL}/carrinhos/${carrinhoId}`, { method: 'DELETE', headers: { 'accept': 'application/json', 'Authorization': `Bearer ${token}`, }, }); if (response.ok) { return { success: true }; } else { const data = await response.json().catch(() => ({})); console.error('❌ Erro ao excluir carrinho:', data); return { success: false, error: data.message || 'Erro ao excluir carrinho' }; } } catch (error) { console.error('💥 Erro na exclusão do carrinho:', error); return { success: false, error: 'Erro de conexão ao excluir carrinho' }; } }, /** * Lista carrinhos do usuário */ listarPorUsuario: async (): Promise => { try { const token = carrinhoApiService.getAuthToken(); if (!token) { return { success: false, error: 'Token de autenticação não encontrado' }; } let userId = carrinhoApiService.getUserId(); // Se não tem usuário no localStorage, buscar via API if (!userId) { const userData = await carrinhoApiService.fetchUserData(); userId = userData?.$id || userData?.id || userData?.usuario_id; } if (!userId) { return { success: false, error: 'ID do usuário não encontrado' }; } const response = await fetch(`${BFF_BASE_URL}/carrinhos?usuarios=${userId}`, { method: 'GET', headers: { 'accept': 'application/json', 'Authorization': `Bearer ${token}`, }, }); const data = await response.json(); if (response.ok) { return { success: true, data }; } else { console.error('❌ Erro ao listar carrinhos:', data); return { success: false, error: data.message || 'Erro ao listar carrinhos' }; } } catch (error) { console.error('💥 Erro ao listar carrinhos:', error); return { success: false, error: 'Erro de conexão ao listar carrinhos' }; } }, };