"use client"

import {
  useQuery,
  useMutation,
  useQueryClient,
} from "@tanstack/react-query"
import { api } from "@/lib/api-client"
import { useAuthStore } from "@/stores/auth-store"
import { useChatStore } from "@/stores/chat-store"
import type { ChatAgentInfo, ChatSessionResponse, ChatHistoryResponse } from "@/types/chat"
import type { ChatRuntime } from "@/lib/chat/runtime"
import type { ChatModelSummary } from "@/lib/chat/model-summary"

// ─── Query Key Factory ───────────────────────────────────────────────

export const chatKeys = {
  all: ["chat"] as const,
  agents: () => [...chatKeys.all, "agents"] as const,
  sessions: () => [...chatKeys.all, "sessions"] as const,
  model: (
    instanceId: string | null | undefined,
    agentId: string | null | undefined,
    runtime: ChatRuntime,
    sessionId: string | null | undefined,
  ) => [...chatKeys.all, "model", instanceId, agentId, runtime, sessionId ?? null] as const,
  history: (sessionId: string | null) =>
    [...chatKeys.all, "history", sessionId] as const,
}

// ─── Agents ──────────────────────────────────────────────────────────

export function useChatAgents() {
  const user = useAuthStore((s) => s.user)
  return useQuery({
    queryKey: chatKeys.agents(),
    queryFn: () =>
      api.get<{ agents: ChatAgentInfo[] }>("/api/v1/chat/agents"),
    enabled: !!user,
    staleTime: 60_000,
    select: (data) => data.agents,
  })
}

export function useChatModel(params: {
  agent: ChatAgentInfo | null
  runtime: ChatRuntime
  sessionId: string | null
}) {
  const user = useAuthStore((s) => s.user)
  const isStreaming = useChatStore((s) => s.isStreaming)
  const remoteStreaming = useChatStore((s) => s.remoteStreaming)
  const instanceId = params.agent?.instanceId
  const agentId = params.agent?.agentId

  return useQuery({
    queryKey: chatKeys.model(instanceId, agentId, params.runtime, params.sessionId),
    queryFn: () => {
      const qs = new URLSearchParams({
        instanceId: instanceId ?? '',
        agentId: agentId ?? '',
        runtime: params.runtime,
      })
      if (params.sessionId) qs.set('sessionId', params.sessionId)
      return api.get<{ model: ChatModelSummary | null }>(
        `/api/v1/chat/model?${qs.toString()}`,
      )
    },
    enabled: !!user && !!instanceId && !!agentId,
    staleTime: 15_000,
    refetchInterval: isStreaming || remoteStreaming ? 5_000 : false,
    select: (data) => data.model,
  })
}

// ─── Sessions ────────────────────────────────────────────────────────

export function useChatSessions() {
  const user = useAuthStore((s) => s.user)
  return useQuery({
    queryKey: chatKeys.sessions(),
    queryFn: () =>
      api.get<{ sessions: ChatSessionResponse[] }>("/api/v1/chat/sessions"),
    enabled: !!user,
    staleTime: 30_000,
    select: (data) => data.sessions,
  })
}

// ─── History ────────────────────────────────────────────────────────

export function useChatHistory(sessionId: string | null) {
  return useQuery({
    queryKey: chatKeys.history(sessionId),
    queryFn: () =>
      api.get<ChatHistoryResponse>(
        `/api/v1/chat/sessions/${sessionId}/history`,
      ),
    enabled: !!sessionId,
    refetchInterval: (query) => {
      // Don't poll when the tab is hidden — saves battery and bandwidth
      if (typeof document !== "undefined" && document.hidden) return false
      const data = query.state.data as ChatHistoryResponse | undefined
      if (!data?.isActive) return false
      // During remote streaming (agent running but we're not SSE-connected),
      // poll frequently to show progress
      if (useChatStore.getState().remoteStreaming) return 5_000
      // Idle active sessions: poll infrequently for session-lost detection
      if (!useChatStore.getState().isStreaming) return 30_000
      return false
    },
  })
}

// ─── Delete Session ──────────────────────────────────────────────────

export function useDeleteChatSession() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (id: string) => api.delete(`/api/v1/chat/sessions/${id}`),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: chatKeys.sessions() })
    },
  })
}

// ─── Clear Context ──────────────────────────────────────────────────

export function useClearContext() {
  const qc = useQueryClient()
  return useMutation({
    mutationFn: (sessionId: string) =>
      api.post(`/api/v1/chat/sessions/${sessionId}/clear-context`),
    onSuccess: (_data, sessionId) => {
      useChatStore.getState().setKbSources([])
      qc.invalidateQueries({ queryKey: chatKeys.history(sessionId) })
      qc.invalidateQueries({ queryKey: chatKeys.sessions() })
    },
  })
}

// ─── New Conversation ───────────────────────────────────────────────

export function useNewConversation() {
  const qc = useQueryClient()
  return useMutation<
    { session: ChatSessionResponse },
    Error,
    { instanceId: string; agentId: string; runtime?: ChatRuntime }
  >({
    mutationFn: (body: { instanceId: string; agentId: string; runtime?: ChatRuntime }) =>
      api.post<{ session: ChatSessionResponse }>(
        "/api/v1/chat/conversations/new",
        body,
      ),
    onSuccess: (data) => {
      qc.setQueryData<{ sessions: ChatSessionResponse[] }>(chatKeys.sessions(), (old) => ({
        sessions: [
          data.session,
          ...(old?.sessions ?? []).filter((session) => session.id !== data.session.id),
        ],
      }))
      qc.invalidateQueries({ queryKey: chatKeys.sessions() })
    },
  })
}
