import { useState, useCallback, useEffect } from 'react' import { protocolApi, sectorApi, type Sector, type Team } from '../services/chatApiService' // ─── Types ──────────────────────────────────────────────────────────────────── export type ProtocolStatus = | 'OPEN' | 'IN_PROGRESS' | 'WAITING_CLIENT' | 'WAITING_AGENT' | 'RESOLVED' | 'CANCELLED' export interface Protocol { id: string number: string chatId: string contactId: string sectorId: string | null teamId: string | null agentId: string | null status: ProtocolStatus summary: string | null deadline: string | null resolvedAt: string | null createdAt: string updatedAt: string sector?: { name: string } | null team?: { name: string } | null } // ─── Hook ───────────────────────────────────────────────────────────────────── export function useProtocolPanel(chatId: string | null) { const [protocols, setProtocols] = useState([]) const [loading, setLoading] = useState(false) // Sectors & teams for the "open protocol" form const [sectors, setSectors] = useState([]) const [teams, setTeams] = useState([]) const [selectedSectorId, setSelectedSectorId] = useState('') const [selectedTeamId, setSelectedTeamId] = useState('') const [loadingSectors, setLoadingSectors] = useState(false) const [loadingTeams, setLoadingTeams] = useState(false) // Opening a new protocol const [isOpening, setIsOpening] = useState(false) const [showOpenForm, setShowOpenForm] = useState(false) // Updating status const [updatingId, setUpdatingId] = useState(null) // Toast const [toast, setToast] = useState<{ message: string; type: 'success' | 'error' } | null>(null) const showToast = useCallback((message: string, type: 'success' | 'error') => { setToast({ message, type }) setTimeout(() => setToast(null), 3000) }, []) // ── Load protocols ──────────────────────────────────────────────────────── const load = useCallback(async () => { if (!chatId) { setProtocols([]); return } setLoading(true) try { const data = await protocolApi.list(chatId) setProtocols(data as Protocol[]) } catch { // silently ignore } finally { setLoading(false) } }, [chatId]) useEffect(() => { load() }, [chatId]) // ── Load sectors (lazy, once) ───────────────────────────────────────────── const loadSectors = useCallback(async () => { if (sectors.length > 0) return setLoadingSectors(true) try { const data = await sectorApi.list() setSectors(data.filter((s) => s.isActive)) } catch { // ignore } finally { setLoadingSectors(false) } }, [sectors.length]) // ── Load teams when sector changes ──────────────────────────────────────── useEffect(() => { if (!selectedSectorId) { setTeams([]); setSelectedTeamId(''); return } setLoadingTeams(true) sectorApi.listTeams(selectedSectorId) .then((data) => { setTeams(data.filter((t) => t.isActive)); setSelectedTeamId('') }) .catch(() => {}) .finally(() => setLoadingTeams(false)) }, [selectedSectorId]) const openForm = useCallback(() => { setShowOpenForm(true) setSelectedSectorId('') setSelectedTeamId('') loadSectors() }, [loadSectors]) // ── Open new protocol ───────────────────────────────────────────────────── const openProtocol = useCallback(async () => { if (!chatId) return setIsOpening(true) try { const protocol = await protocolApi.open(chatId, { sectorId: selectedSectorId || undefined, teamId: selectedTeamId || undefined, }) setProtocols((prev) => [protocol as Protocol, ...prev]) setShowOpenForm(false) showToast('Protocolo aberto.', 'success') } catch (err: any) { showToast(err?.response?.data?.error ?? 'Erro ao abrir protocolo.', 'error') } finally { setIsOpening(false) } }, [chatId, selectedSectorId, selectedTeamId, showToast]) // ── Update status ───────────────────────────────────────────────────────── const updateStatus = useCallback(async (protocol: Protocol, status: ProtocolStatus) => { if (!chatId) return setUpdatingId(protocol.id) try { await protocolApi.update(chatId, protocol.id, { status }) setProtocols((prev) => prev.map((p) => p.id === protocol.id ? { ...p, status, resolvedAt: status === 'RESOLVED' ? new Date().toISOString() : p.resolvedAt } : p ) ) showToast('Status atualizado.', 'success') } catch { showToast('Erro ao atualizar status.', 'error') } finally { setUpdatingId(null) } }, [chatId, showToast]) // ── Derived ─────────────────────────────────────────────────────────────── const activeProtocol = protocols.find( (p) => p.status !== 'RESOLVED' && p.status !== 'CANCELLED' ) ?? null const hasActive = activeProtocol !== null return { protocols, loading, load, activeProtocol, hasActive, // open form showOpenForm, setShowOpenForm, openForm, sectors, teams, selectedSectorId, setSelectedSectorId, selectedTeamId, setSelectedTeamId, loadingSectors, loadingTeams, isOpening, openProtocol, // update updatingId, updateStatus, toast, } }