import { GlobalFunctions, TransferAreaProperties } from '@/GlobalFunctions'; import { apiService } from './api'; export interface CreateOpinionResponse { success: boolean; id?: string; file_url?: string; file_url_melhoria?: string; } export interface CreateOpinionRequest { titulo: string; categoria: string; instrucoes: string; userEmail?: string; estabelecimentoId?: number; } export type OpinionStatus = 'processando' | 'concluido' | 'erro'; export interface OpinionRecord { id: string; estabelecimento_id: number; user_email: string; titulo: string; categoria: string; instrucoes: string; file_url: string; created_at: string; file_url_melhoria: string; status?: OpinionStatus; isLocalPending?: boolean; } export interface GetOpinionsParams { page?: number; per_page?: number; search?: string; userEmail?: string; estabelecimentoId?: number; } export interface GetOpinionsResponse { data: OpinionRecord[]; total: number; page: number; per_page: number; } type ApiErrorShape = { message?: string; status?: number }; class AgentService { private readonly CREATE_ENDPOINT = '/webhook/codex/gepam/parecer-tecnico'; private readonly OPINIONS_BASE = '/webhook/fd073ec0-81ab-4681-8acd-b0da71f6ad30/codex'; private resolveUserContext(userEmail?: string, estabelecimentoId?: number) { const email = userEmail || GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail); const estabId = estabelecimentoId || GlobalFunctions.getTransferProperty(TransferAreaProperties.EstabelecimentoCodigo); return { email, estabId }; } private assertUserContext(email: unknown, estabId: unknown) { if (!email) { throw { success: false, message: 'Email do usuário não fornecido' }; } if (!estabId) { throw { success: false, message: 'ID do estabelecimento não fornecido' }; } } private toApiError(error: unknown): never { const e = error as ApiErrorShape; throw { success: false, message: e?.message || 'Erro desconhecido', status: e?.status, }; } async createOpinion(request: CreateOpinionRequest): Promise { const { titulo, categoria, instrucoes, userEmail, estabelecimentoId } = request; if (!titulo?.trim()) { throw { success: false, message: 'Título do parecer é obrigatório' }; } if (!instrucoes?.trim()) { throw { success: false, message: 'Instruções são obrigatórias' }; } const { email, estabId } = this.resolveUserContext(userEmail, estabelecimentoId); this.assertUserContext(email, estabId); try { const response = await apiService.post( this.CREATE_ENDPOINT, { user_email: email, estabelecimento_id: estabId, titulo: titulo.trim(), categoria: categoria.trim(), instrucoes: instrucoes.trim(), }, { timeout: 600_000 } ); return response.data; } catch (error: unknown) { console.error('Erro ao criar parecer:', error); this.toApiError(error); } } async getOpinions(params?: GetOpinionsParams): Promise { const { page = 1, per_page = 10, search = '', userEmail, estabelecimentoId } = params || {}; const { email, estabId } = this.resolveUserContext(userEmail, estabelecimentoId); this.assertUserContext(email, estabId); try { const url = `${this.OPINIONS_BASE}/get_parecer/${email}/${estabId}`; const response = await apiService.get(url, { params: { page, per_page, search }, }); const raw = response.data; if (Array.isArray(raw)) return raw; if (raw && typeof raw === 'object') { if (Array.isArray((raw as GetOpinionsResponse).data)) return (raw as GetOpinionsResponse).data; if (Array.isArray((raw as { opinions?: OpinionRecord[] }).opinions)) { return (raw as unknown as { opinions: OpinionRecord[] }).opinions; } } return []; } catch (error: unknown) { console.error('Erro ao buscar pareceres:', error); this.toApiError(error); } } async downloadOpinion(fileUrl: string, fileName: string): Promise { if (!fileUrl) { throw { success: false, message: 'URL do arquivo não fornecida' }; } const triggerDownload = (href: string) => { const link = document.createElement('a'); link.href = href; link.download = fileName; link.target = '_blank'; link.rel = 'noopener noreferrer'; document.body.appendChild(link); link.click(); document.body.removeChild(link); }; try { const response = await fetch(fileUrl, { method: 'GET', mode: 'cors', cache: 'no-cache' }); if (!response.ok) { throw new Error(`Erro HTTP: ${response.status}`); } const blob = await response.blob(); const blobUrl = URL.createObjectURL(blob); triggerDownload(blobUrl); URL.revokeObjectURL(blobUrl); } catch { const url = new URL(fileUrl); url.searchParams.set('response-content-disposition', `attachment; filename="${encodeURIComponent(fileName)}"`); triggerDownload(url.toString()); } } async deleteOpinion(opinionId: string, userEmail?: string): Promise<{ success: boolean }> { if (!opinionId) { throw { success: false, message: 'ID do parecer não fornecido' }; } const email = userEmail || GlobalFunctions.getTransferProperty(TransferAreaProperties.UsuarioEmail); if (!email) { throw { success: false, message: 'Email do usuário não fornecido' }; } try { const url = `${this.OPINIONS_BASE}/delete_parecer/${email}/${opinionId}`; const response = await apiService.delete<{ success: boolean }[]>(url); if (Array.isArray(response.data) && response.data.length > 0) { return response.data[0]; } return { success: true }; } catch (error: unknown) { console.error('Erro ao excluir parecer:', error); this.toApiError(error); } } } export const agentService = new AgentService();