import { useCallback, useEffect, useState } from 'react'; import { useEditorConfig } from '../state/EditorConfigContext'; import { SitesmithSummary, SitesmithMessage, SendResult } from '../types/sitesmith'; function apiBase(apiUrl: string): string { return apiUrl.replace(/site-builder\.php$/, 'sitesmith.php'); } export function useSitesmith(siteId: number) { const { whpConfig } = useEditorConfig(); const [summary, setSummary] = useState(null); const [messages, setMessages] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const refreshEntitlement = useCallback(async () => { if (!whpConfig) return; try { const r = await fetch(`${apiBase(whpConfig.apiUrl)}?action=entitlement`, { credentials: 'include' }); const j = await r.json(); if (j.ok) setSummary(j.summary); } catch (e: any) { setError(String(e?.message ?? e)); } }, [whpConfig]); const fetchHistory = useCallback(async () => { if (!whpConfig) { setLoading(false); return; } try { const r = await fetch(`${apiBase(whpConfig.apiUrl)}?action=history&site_id=${siteId}`, { credentials: 'include' }); const j = await r.json(); if (j.ok) setMessages(j.messages); } catch (e: any) { setError(String(e?.message ?? e)); } finally { setLoading(false); } }, [whpConfig, siteId]); useEffect(() => { void refreshEntitlement(); void fetchHistory(); }, [refreshEntitlement, fetchHistory]); const send = useCallback(async ( userText: string, canvasSummary: string, target?: { node_id: string; display_name: string; tree_json: string }, ): Promise => { if (!whpConfig) return { ok: false, status: 'BLOCKED', message: 'No WHP config' }; setMessages((m) => [...m, { role: 'user', content: userText, response_type: null, created_at: new Date().toISOString() }]); const body: Record = { site_id: siteId, message: userText, canvas_summary: canvasSummary }; if (target) body.target = target; const r = await fetch(`${apiBase(whpConfig.apiUrl)}?action=send`, { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': whpConfig.csrfToken }, body: JSON.stringify(body), }); const j: SendResult = await r.json(); void fetchHistory(); void refreshEntitlement(); return j; }, [whpConfig, siteId, fetchHistory, refreshEntitlement]); const clearHistory = useCallback(async (): Promise<{ ok: boolean; cleared?: number; error?: string }> => { if (!whpConfig) return { ok: false, error: 'No WHP config' }; try { const r = await fetch(`${apiBase(whpConfig.apiUrl)}?action=clear_history`, { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': whpConfig.csrfToken }, body: JSON.stringify({ site_id: siteId }), }); const j = await r.json(); if (j.ok) setMessages([]); return j; } catch (e: any) { return { ok: false, error: String(e?.message ?? e) }; } }, [whpConfig, siteId]); return { summary, messages, loading, error, send, refreshEntitlement, clearHistory }; }