"use client" import { useEffect, useMemo } from "react" import { useQueries } from "@tanstack/react-query" import { useAuthReady } from "@/lib/api/use-auth-ready" import { useIsDemoMail } from "@/lib/demo/demo-mail-context" import { useMailAccounts } from "@/lib/api/hooks/use-mail-queries" import { apiClient } from "@/lib/api/client" import type { ApiIdentity } from "@/lib/api/types" import { useMailSignatures } from "@/lib/api/hooks/use-mail-signatures" import { apiIdentityToCompose, dedupeComposeIdentities } from "@/lib/compose/identity-map" import type { Identity } from "@/lib/compose-context" import { useComposeIdentitiesStore } from "@/lib/stores/compose-identities-store" async function fetchIdentities(accountId: string) { const res = await apiClient.get( `/mail/accounts/${accountId}/identities` ) return Array.isArray(res) ? res : (res.identities ?? []) } /** Hydrate compose From identities from server for all mail accounts. */ export function ComposeIdentitiesSync() { const isDemoMail = useIsDemoMail() const { ready, authenticated } = useAuthReady() const { data: accounts = [], isSuccess: accountsReady } = useMailAccounts() const { data: signatures = [], isSuccess: signaturesReady } = useMailSignatures() const signaturesById = useMemo( () => new Map(signatures.map((s) => [s.id, s])), [signatures] ) const identityQueries = useQueries({ queries: accounts.map((account) => ({ queryKey: ["identities", account.id], queryFn: () => fetchIdentities(account.id), enabled: ready && authenticated && !!account.id, staleTime: 5 * 60_000, })), }) const mergedKey = identityQueries.map((q) => q.dataUpdatedAt).join("|") const merged = useMemo(() => { if (!ready || !authenticated || !accountsReady || !signaturesReady) return [] as Identity[] if (accounts.length === 0) return [] as Identity[] if (identityQueries.some((q) => q.isPending && q.fetchStatus !== "idle")) { return null } return dedupeComposeIdentities( identityQueries.flatMap((q) => (q.data ?? []).map((id) => apiIdentityToCompose(id, signaturesById)), ), ) }, [ ready, authenticated, accountsReady, signaturesReady, accounts.length, mergedKey, identityQueries, signaturesById, ]) useEffect(() => { if (isDemoMail) return if (!ready || !authenticated) { useComposeIdentitiesStore.getState().clear() return } if (merged === null) return useComposeIdentitiesStore.getState().hydrateFromApi(merged) }, [isDemoMail, ready, authenticated, merged]) return null } export function useComposeIdentities(accountId?: string | null) { const identities = useComposeIdentitiesStore((s) => s.identities) const hydrated = useComposeIdentitiesStore((s) => s.hydrated) const scoped = accountId ? identities.filter((i) => i.accountId === accountId) : identities const list = scoped.length > 0 ? scoped : identities const defaultIdentity = list.find((i) => i.isDefault) ?? list[0] ?? null return { identities: list, defaultIdentity, hydrated } }