'use client' import { useCallback, useEffect, useState } from 'react' import type { NotebookSchemaPayload, NotePropertyValues } from '@/lib/structured-views/types' type SchemaState = { schema: NotebookSchemaPayload | null noteValues: Record loading: boolean error: string | null } export function useNotebookSchema(notebookId: string | null | undefined) { const [state, setState] = useState({ schema: null, noteValues: {}, loading: false, error: null, }) const reload = useCallback(async () => { if (!notebookId) { setState({ schema: null, noteValues: {}, loading: false, error: null }) return } setState((s) => ({ ...s, loading: true, error: null })) try { const res = await fetch(`/api/notebooks/${notebookId}/schema`) const json = await res.json() if (!res.ok || !json.success) { throw new Error(json.error || 'Failed to load schema') } setState({ schema: json.data.schema, noteValues: json.data.noteValues ?? {}, loading: false, error: null, }) } catch (e) { setState((s) => ({ ...s, loading: false, error: e instanceof Error ? e.message : 'Error', })) } }, [notebookId]) useEffect(() => { void reload() }, [reload]) const enableStructuredMode = useCallback(async () => { if (!notebookId) return null const res = await fetch(`/api/notebooks/${notebookId}/schema`, { method: 'POST' }) const json = await res.json() if (!res.ok || !json.success) throw new Error(json.error || 'Failed') await reload() return json.data.schema as NotebookSchemaPayload }, [notebookId, reload]) const disableStructuredMode = useCallback(async () => { if (!notebookId) return const res = await fetch(`/api/notebooks/${notebookId}/schema`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: 'disable' }), }) const json = await res.json() if (!res.ok || !json.success) throw new Error(json.error || 'Failed') await reload() }, [notebookId, reload]) const addProperty = useCallback( async (name: string, type: string, options?: string[]) => { if (!notebookId) return null const res = await fetch(`/api/notebooks/${notebookId}/schema`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: 'addProperty', name, type, options }), }) const json = await res.json() if (!res.ok || !json.success) throw new Error(json.error || 'Failed') await reload() return json.data.schema as NotebookSchemaPayload }, [notebookId, reload], ) const deleteProperty = useCallback( async (propertyId: string) => { if (!notebookId) return const res = await fetch(`/api/notebooks/${notebookId}/schema`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: 'deleteProperty', propertyId }), }) const json = await res.json() if (!res.ok || !json.success) throw new Error(json.error || 'Failed') await reload() }, [notebookId, reload], ) const setKanbanGroupProperty = useCallback( async (propertyId: string | null) => { if (!notebookId) return const res = await fetch(`/api/notebooks/${notebookId}/schema`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action: 'updateViewSettings', kanbanGroupPropertyId: propertyId }), }) const json = await res.json() if (!res.ok || !json.success) throw new Error(json.error || 'Failed') await reload() }, [notebookId, reload], ) const patchNoteValuesLocal = useCallback((noteId: string, patch: NotePropertyValues) => { setState((s) => ({ ...s, noteValues: { ...s.noteValues, [noteId]: { ...(s.noteValues[noteId] ?? {}), ...patch }, }, })) }, []) return { ...state, reload, enableStructuredMode, disableStructuredMode, addProperty, deleteProperty, setKanbanGroupProperty, patchNoteValuesLocal, } }