import { ref, watch, type ComputedRef } from "vue"; import { useQuery, useMutation } from "@vue/apollo-composable"; import { FeedQueryDocument, UpdateFeedDecisionMutationDocument, CreateCalendarEventMutationDocument, CreateCommunicationMutationDocument, LogPilotNoteMutationDocument, CalendarQueryDocument, CommunicationsQueryDocument, ContactInboxesQueryDocument, ChatMessagesQueryDocument, ChatConversationsQueryDocument, } from "~~/graphql/generated"; import type { FeedCard, CalendarEvent } from "~/composables/crm-types"; import { dayKey, formatDay, formatTime } from "~/composables/crm-types"; export function useFeed(opts: { apolloAuthReady: ComputedRef; onCreateFollowup: (card: FeedCard, event: CalendarEvent) => void; onOpenComm: (card: FeedCard) => void; }) { const { result: feedResult, refetch: refetchFeed } = useQuery( FeedQueryDocument, null, { enabled: opts.apolloAuthReady }, ); const { mutate: doUpdateFeedDecision } = useMutation(UpdateFeedDecisionMutationDocument, { refetchQueries: [{ query: FeedQueryDocument }], }); const { mutate: doCreateCalendarEvent } = useMutation(CreateCalendarEventMutationDocument, { refetchQueries: [{ query: CalendarQueryDocument }], }); const { mutate: doCreateCommunication } = useMutation(CreateCommunicationMutationDocument, { refetchQueries: [{ query: CommunicationsQueryDocument }, { query: ContactInboxesQueryDocument }], }); const { mutate: doLogPilotNote } = useMutation(LogPilotNoteMutationDocument); const feedCards = ref([]); watch(() => feedResult.value?.feed, (v) => { if (v) feedCards.value = v as FeedCard[]; }, { immediate: true }); function pushPilotNote(text: string) { doLogPilotNote({ text }) .then(() => {}) .catch(() => {}); } async function executeFeedAction(card: FeedCard) { const key = card.proposal.key; if (key === "create_followup") { const start = new Date(); start.setMinutes(start.getMinutes() + 30); start.setSeconds(0, 0); const end = new Date(start); end.setMinutes(end.getMinutes() + 30); const res = await doCreateCalendarEvent({ input: { title: `Follow-up: ${card.contact.split(" ")[0] ?? "Contact"}`, start: start.toISOString(), end: end.toISOString(), contact: card.contact, note: "Created from feed action.", }, }); const created = res?.data?.createCalendarEvent as CalendarEvent | undefined; if (created) { opts.onCreateFollowup(card, created); } return `Event created: Follow-up · ${formatDay(start.toISOString())} ${formatTime(start.toISOString())} · ${card.contact}`; } if (key === "open_comm") { opts.onOpenComm(card); return `Opened ${card.contact} communication thread.`; } if (key === "call") { await doCreateCommunication({ input: { contact: card.contact, channel: "Phone", kind: "call", direction: "out", text: "Call started from feed", durationSec: 0, }, }); opts.onOpenComm(card); return `Call event created and ${card.contact} chat opened.`; } if (key === "draft_message") { await doCreateCommunication({ input: { contact: card.contact, channel: "Email", kind: "message", direction: "out", text: "Draft: onboarding plan + two slots for tomorrow.", }, }); opts.onOpenComm(card); return `Draft message added to ${card.contact} communications.`; } if (key === "run_summary") { return "Call summary prepared: 5 next steps sent to Pilot."; } if (key === "prepare_question") { await doCreateCommunication({ input: { contact: card.contact, channel: "Telegram", kind: "message", direction: "out", text: "Draft: can you confirm your decision date for this cycle?", }, }); opts.onOpenComm(card); return `Question about decision date added to ${card.contact} chat.`; } return "Action completed."; } async function decideFeedCard(card: FeedCard, decision: "accepted" | "rejected") { card.decision = decision; if (decision === "rejected") { const note = "Rejected. Nothing created."; card.decisionNote = note; await doUpdateFeedDecision({ id: card.id, decision: "rejected", decisionNote: note }); pushPilotNote(`[${card.contact}] recommendation rejected: ${card.proposal.title}`); return; } const result = await executeFeedAction(card); card.decisionNote = result; await doUpdateFeedDecision({ id: card.id, decision: "accepted", decisionNote: result }); pushPilotNote(`[${card.contact}] ${result}`); } return { feedCards, decideFeedCard, executeFeedAction, pushPilotNote, refetchFeed, }; }