import { ref, computed, watch } from "vue"; import { useQuery, useMutation } from "@vue/apollo-composable"; import { MeQueryDocument, LogoutMutationDocument } from "~~/graphql/generated"; type TelegramConnectStatus = | "not_connected" | "pending_link" | "pending_business_connection" | "connected" | "disabled" | "no_reply_rights"; type TelegramConnectionSummary = { businessConnectionId: string; isEnabled: boolean | null; canReply: boolean | null; updatedAt: string; }; export function useAuth() { // ------------------------------------------------------------------------- // Auth state // ------------------------------------------------------------------------- const authMe = ref<{ user: { id: string; phone: string; name: string }; team: { id: string; name: string }; conversation: { id: string; title: string }; } | null>(null); const authResolved = ref(false); const apolloAuthReady = computed(() => !!authMe.value); // ------------------------------------------------------------------------- // Apollo: Me query // ------------------------------------------------------------------------- const { result: meResult, refetch: refetchMe, loading: meLoading } = useQuery( MeQueryDocument, null, { fetchPolicy: "network-only" }, ); watch(() => meResult.value?.me, (me) => { if (me) authMe.value = me as typeof authMe.value; }, { immediate: true }); // ------------------------------------------------------------------------- // Apollo: Logout mutation // ------------------------------------------------------------------------- const { mutate: doLogout } = useMutation(LogoutMutationDocument); // ------------------------------------------------------------------------- // loadMe / logout // ------------------------------------------------------------------------- async function loadMe() { const result = await refetchMe(); const me = result?.data?.me; if (me) authMe.value = me as typeof authMe.value; } async function logout() { await doLogout(); authMe.value = null; telegramConnectStatus.value = "not_connected"; telegramConnections.value = []; telegramConnectUrl.value = ""; if (process.client) { await navigateTo("/login", { replace: true }); } } // ------------------------------------------------------------------------- // Telegram connect state // ------------------------------------------------------------------------- const telegramConnectStatus = ref("not_connected"); const telegramConnectStatusLoading = ref(false); const telegramConnectBusy = ref(false); const telegramConnectUrl = ref(""); const telegramConnections = ref([]); const telegramConnectNotice = ref(""); const telegramStatusLabel = computed(() => { if (telegramConnectStatusLoading.value) return "Checking"; if (telegramConnectStatus.value === "connected") return "Connected"; if (telegramConnectStatus.value === "pending_link") return "Pending link"; if (telegramConnectStatus.value === "pending_business_connection") return "Waiting business connect"; if (telegramConnectStatus.value === "disabled") return "Disabled"; if (telegramConnectStatus.value === "no_reply_rights") return "No reply rights"; return "Not connected"; }); const telegramStatusBadgeClass = computed(() => { if (telegramConnectStatus.value === "connected") return "badge-success"; if (telegramConnectStatus.value === "pending_link" || telegramConnectStatus.value === "pending_business_connection") return "badge-warning"; if (telegramConnectStatus.value === "disabled" || telegramConnectStatus.value === "no_reply_rights") return "badge-error"; return "badge-ghost"; }); // ------------------------------------------------------------------------- // Telegram connect functions // ------------------------------------------------------------------------- async function loadTelegramConnectStatus() { if (!authMe.value) { telegramConnectStatus.value = "not_connected"; telegramConnections.value = []; telegramConnectUrl.value = ""; return; } telegramConnectStatusLoading.value = true; try { const result = await $fetch<{ ok: boolean; status: TelegramConnectStatus; connections?: TelegramConnectionSummary[]; }>("/api/omni/telegram/business/connect/status", { method: "GET", }); telegramConnectStatus.value = result?.status ?? "not_connected"; telegramConnections.value = result?.connections ?? []; } catch { telegramConnectStatus.value = "not_connected"; telegramConnections.value = []; } finally { telegramConnectStatusLoading.value = false; } } async function startTelegramBusinessConnect() { if (telegramConnectBusy.value) return; telegramConnectBusy.value = true; try { const result = await $fetch<{ ok: boolean; status: TelegramConnectStatus; connectUrl: string; expiresAt: string; }>("/api/omni/telegram/business/connect/start", { method: "POST" }); telegramConnectStatus.value = result?.status ?? "pending_link"; telegramConnectUrl.value = String(result?.connectUrl ?? "").trim(); if (telegramConnectUrl.value && process.client) { window.location.href = telegramConnectUrl.value; } } catch { telegramConnectStatus.value = "not_connected"; } finally { telegramConnectBusy.value = false; await loadTelegramConnectStatus(); } } async function completeTelegramBusinessConnectFromToken(token: string) { const t = String(token || "").trim(); if (!t) return; try { const result = await $fetch<{ ok: boolean; status: string; businessConnectionId?: string; }>("/api/omni/telegram/business/connect/complete", { method: "POST", body: { token: t }, }); if (result?.ok) { telegramConnectStatus.value = "connected"; telegramConnectNotice.value = "Telegram успешно привязан."; await loadTelegramConnectStatus(); return; } if (result?.status === "awaiting_telegram_start") { telegramConnectNotice.value = "Сначала нажмите Start в Telegram, затем нажмите кнопку в боте снова."; } else if (result?.status === "invalid_or_expired_token") { telegramConnectNotice.value = "Ссылка привязки истекла. Нажмите Connect в CRM заново."; } else { telegramConnectNotice.value = "Не удалось завершить привязку. Запустите Connect заново."; } } catch { telegramConnectNotice.value = "Ошибка завершения привязки. Попробуйте снова."; } } return { authMe, authResolved, apolloAuthReady, meLoading, loadMe, logout, // telegram telegramConnectStatus, telegramConnectStatusLoading, telegramConnectBusy, telegramConnectUrl, telegramConnections, telegramConnectNotice, telegramStatusLabel, telegramStatusBadgeClass, loadTelegramConnectStatus, startTelegramBusinessConnect, completeTelegramBusinessConnectFromToken, }; }