import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'; import { MessageProvider } from '@insignia/iios-message-web'; import { RestClient, type Ticket, type CallbackRequest, type TicketState } from '@insignia/iios-kernel-client'; const SupportContext = createContext(null); /** Wraps MessageProvider (chat) and provides a support REST client. */ export function SupportProvider({ serviceUrl, token, children, }: { serviceUrl: string; token: string; children: React.ReactNode; }): React.ReactElement { const client = useMemo(() => new RestClient({ serviceUrl, token }), [serviceUrl, token]); return ( {children} ); } function useSupportClient(): RestClient { const c = useContext(SupportContext); if (!c) throw new Error('support hooks must be used within '); return c; } /** Escalate a chat thread to support (creates + queues a ticket). */ export function useEscalate(): (threadId: string, subject?: string) => Promise { const client = useSupportClient(); return (threadId, subject) => client.escalate(threadId, subject); } /** The caller's tickets (scope 'mine') or an agent's assigned tickets ('assigned'). */ export function useTickets(scope: 'mine' | 'assigned' = 'mine', pollMs = 3000): { tickets: Ticket[]; refresh: () => Promise; createTicket: (subject: string, opts?: { priority?: string; threadId?: string }) => Promise; patch: (id: string, state: TicketState) => Promise; } { const client = useSupportClient(); const [tickets, setTickets] = useState([]); const refresh = useCallback(async () => { try { setTickets(await client.listTickets(scope)); } catch { /* transient */ } }, [client, scope]); useEffect(() => { void refresh(); const t = setInterval(() => void refresh(), pollMs); return () => clearInterval(t); }, [refresh, pollMs]); const createTicket = async (subject: string, opts?: { priority?: string; threadId?: string }) => { const t = await client.createTicket({ subject, ...opts }); await refresh(); return t; }; const patch = async (id: string, state: TicketState) => { await client.patchTicket(id, state); await refresh(); }; return { tickets, refresh, createTicket, patch }; } /** Agent convenience: their assigned tickets. */ export function useAssignedTickets(pollMs = 3000) { return useTickets('assigned', pollMs); } export function useCallbackRequest(): (input: { preferChannel: string; preferredTime?: string; notes?: string; ticketId?: string; }) => Promise { const client = useSupportClient(); return (input) => client.requestCallback(input); } /** Agent presence: set AVAILABLE/OFFLINE. */ export function useAvailability(): (state: string) => Promise { const client = useSupportClient(); return (state) => client.setAvailability(state); } /** Agent onboarding: join the default queue + go AVAILABLE (self-seed). */ export function useGoOnline(): () => Promise { const client = useSupportClient(); return async () => { await client.joinDefaultQueue(); await client.setAvailability('AVAILABLE'); }; }