"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<ApiIdentity[] | { identities: ApiIdentity[] }>(
    `/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 }
}
