import { create } from 'zustand' import { secAgentApi, secNodeApi, secConvApi, secCalApi, secNumberApi, type SecAgent, type BrainNode, type SecConversation, type SecMessage, type CalendarSlot, type SecNumber, } from '../services/secretariaApi' interface SecretariaState { // Data agents: SecAgent[] selectedAgent: SecAgent | null nodes: BrainNode[] conversations: SecConversation[] selectedConversation: SecConversation | null messages: SecMessage[] calendarSlots: CalendarSlot[] // Loading flags loadingAgents: boolean loadingNodes: boolean loadingConversations: boolean loadingMessages: boolean sendingMessage: boolean loadingCalendar: boolean // ── Agents ──────────────────────────────────────────────────────────────── loadAgents: () => Promise selectAgent: (a: SecAgent | null) => void createAgent: (d: Partial) => Promise updateAgent: (id: string, d: Partial) => Promise deleteAgent: (id: string) => Promise // ── Brain Nodes ─────────────────────────────────────────────────────────── loadNodes: (agentId: string) => Promise createNode: (agentId: string, d: Partial) => Promise updateNode: (id: string, d: Partial) => Promise deleteNode: (id: string) => Promise // ── Conversations ───────────────────────────────────────────────────────── loadConversations: (agentId?: string) => Promise selectConversation: (c: SecConversation | null) => void createConversation: (agentId: string, contactName: string) => Promise deleteConversation: (id: string) => Promise updateConversationStatus: (id: string, status: SecConversation['status']) => Promise // ── Messages ────────────────────────────────────────────────────────────── loadMessages: (convId: string) => Promise sendMessage: (convId: string, text: string) => Promise // ── Calendar ────────────────────────────────────────────────────────────── loadCalendar: (params?: { from?: string; to?: string; status?: string }) => Promise createCalendarSlot: (d: Partial) => Promise updateCalendarSlot: (id: string, d: Partial) => Promise deleteCalendarSlot: (id: string) => Promise // ── Numbers ─────────────────────────────────────────────────────────────── numbers: SecNumber[] loadingNumbers: boolean loadNumbers: () => Promise createNumber: (d: Partial) => Promise updateNumber: (id: string, d: Partial) => Promise deleteNumber: (id: string) => Promise } export const useSecretariaStore = create((set, get) => ({ agents: [], selectedAgent: null, nodes: [], conversations: [], selectedConversation: null, messages: [], calendarSlots: [], numbers: [], loadingAgents: false, loadingNodes: false, loadingConversations: false, loadingMessages: false, sendingMessage: false, loadingCalendar: false, loadingNumbers: false, // ── Agents ──────────────────────────────────────────────────────────────── loadAgents: async () => { set({ loadingAgents: true }) try { const agents = await secAgentApi.list() set({ agents }) // Auto-seleciona o primeiro agente se nenhum selecionado if (!get().selectedAgent && agents.length > 0) { get().selectAgent(agents[0]) } } finally { set({ loadingAgents: false }) } }, selectAgent: (a) => { set({ selectedAgent: a, nodes: [], conversations: [], selectedConversation: null, messages: [] }) if (a) { get().loadNodes(a.id) get().loadConversations(a.id) } }, createAgent: async (d) => { const agent = await secAgentApi.create(d) set((s) => ({ agents: [...s.agents, agent] })) return agent }, updateAgent: async (id, d) => { const updated = await secAgentApi.update(id, d) set((s) => ({ agents: s.agents.map((a) => (a.id === id ? updated : a)), selectedAgent: s.selectedAgent?.id === id ? updated : s.selectedAgent, })) }, deleteAgent: async (id) => { await secAgentApi.delete(id) set((s) => ({ agents: s.agents.filter((a) => a.id !== id), selectedAgent: s.selectedAgent?.id === id ? null : s.selectedAgent, })) }, // ── Brain Nodes ─────────────────────────────────────────────────────────── loadNodes: async (agentId) => { set({ loadingNodes: true }) try { const nodes = await secNodeApi.list(agentId) set({ nodes }) } finally { set({ loadingNodes: false }) } }, createNode: async (agentId, d) => { const node = await secNodeApi.create(agentId, d) set((s) => ({ nodes: [...s.nodes, node] })) }, updateNode: async (id, d) => { const updated = await secNodeApi.update(id, d) set((s) => ({ nodes: s.nodes.map((n) => (n.id === id ? updated : n)) })) }, deleteNode: async (id) => { await secNodeApi.delete(id) set((s) => ({ nodes: s.nodes.filter((n) => n.id !== id) })) }, // ── Conversations ───────────────────────────────────────────────────────── loadConversations: async (agentId) => { set({ loadingConversations: true }) try { const conversations = await secConvApi.list(agentId) set({ conversations }) } finally { set({ loadingConversations: false }) } }, selectConversation: (c) => { set({ selectedConversation: c, messages: [] }) if (c) get().loadMessages(c.id) }, createConversation: async (agentId, contactName) => { const conv = await secConvApi.create(agentId, contactName) set((s) => ({ conversations: [conv, ...s.conversations] })) return conv }, deleteConversation: async (id) => { await secConvApi.delete(id) set((s) => ({ conversations: s.conversations.filter((c) => c.id !== id), selectedConversation: s.selectedConversation?.id === id ? null : s.selectedConversation, })) }, updateConversationStatus: async (id, status) => { const updated = await secConvApi.patch(id, { status }) set((s) => ({ conversations: s.conversations.map((c) => (c.id === id ? updated : c)), selectedConversation: s.selectedConversation?.id === id ? updated : s.selectedConversation, })) }, // ── Messages ────────────────────────────────────────────────────────────── loadMessages: async (convId) => { set({ loadingMessages: true }) try { const messages = await secConvApi.messages(convId) set({ messages }) } finally { set({ loadingMessages: false }) } }, sendMessage: async (convId, text) => { // Adiciona mensagem do usuário imediatamente (optimistic) const tempId = `temp-${Date.now()}` const userMsg: SecMessage = { id: tempId, conversation_id: convId, role: 'user', content: text, created_at: new Date().toISOString(), } set((s) => ({ messages: [...s.messages, userMsg], sendingMessage: true })) try { const { reply } = await secConvApi.chat(convId, text) const aiMsg: SecMessage = { id: `ai-${Date.now()}`, conversation_id: convId, role: 'assistant', content: reply, created_at: new Date().toISOString(), } set((s) => ({ messages: [...s.messages, aiMsg] })) // Atualiza updated_at da conversa na lista set((s) => ({ conversations: s.conversations.map((c) => c.id === convId ? { ...c, updated_at: new Date().toISOString() } : c, ), })) } finally { set({ sendingMessage: false }) } }, // ── Calendar ────────────────────────────────────────────────────────────── loadCalendar: async (params) => { set({ loadingCalendar: true }) try { const calendarSlots = await secCalApi.list(params) set({ calendarSlots }) } finally { set({ loadingCalendar: false }) } }, createCalendarSlot: async (d) => { const slot = await secCalApi.create(d) set((s) => ({ calendarSlots: [...s.calendarSlots, slot].sort((a, b) => a.date.localeCompare(b.date)) })) }, updateCalendarSlot: async (id, d) => { const updated = await secCalApi.update(id, d) set((s) => ({ calendarSlots: s.calendarSlots.map((sl) => (sl.id === id ? updated : sl)) })) }, deleteCalendarSlot: async (id) => { await secCalApi.delete(id) set((s) => ({ calendarSlots: s.calendarSlots.filter((sl) => sl.id !== id) })) }, // ── Numbers ─────────────────────────────────────────────────────────────── loadNumbers: async () => { set({ loadingNumbers: true }) try { const numbers = await secNumberApi.list() set({ numbers }) } finally { set({ loadingNumbers: false }) } }, createNumber: async (d) => { const num = await secNumberApi.assign(d) set((s) => ({ // upsert: substitui se já existia o mesmo instance_id numbers: [...s.numbers.filter((n) => n.instance_id !== num.instance_id), num] .sort((a, b) => a.priority - b.priority), })) }, updateNumber: async (id, d) => { const updated = await secNumberApi.update(id, d) set((s) => ({ numbers: s.numbers.map((n) => (n.id === id ? updated : n)).sort((a, b) => a.priority - b.priority) })) }, deleteNumber: async (id) => { await secNumberApi.delete(id) set((s) => ({ numbers: s.numbers.filter((n) => n.id !== id) })) }, }))