"use client";

/**
 * Data layer for the on-site МЕРА support chat (issue: "окно чата поддержки на
 * сайте МЕРА"). Talks to `feat/tradein-web-chat-backend` (app/api/v1/support.py,
 * not yet in main at the time this was written — contract is stable/reviewed):
 *
 *   POST /api/v1/trade-in/support/messages  {text}      -> SupportMessage
 *   GET  /api/v1/trade-in/support/messages?since=<id>    -> SupportMessage[]
 *   GET  /api/v1/trade-in/support/unread                 -> {unread}
 *   POST /api/v1/trade-in/support/read                   -> {status:"ok"}
 *
 * Thread is resolved server-side from X-Authenticated-User (injected by Caddy
 * basic_auth upstream) — no thread_id is ever sent from the client.
 *
 * Polling model (see SupportChatPanel.tsx / SupportButton.tsx for the two call
 * sites):
 *   - Messages: polled only while the chat panel is OPEN (`enabled` gate below)
 *     — no point polling a transcript nobody is looking at.
 *   - Unread count: polled only while the panel is CLOSED — it feeds the badge
 *     on the floating button; once open, the transcript itself is the "seen"
 *     signal (see markSupportRead below) and the badge doesn't render.
 *   - Tab-inactive pause is NOT reimplemented here — `refetchInterval`'s
 *     `refetchIntervalInBackground` defaults to `false` in TanStack Query, so
 *     polling already stops while `document` is hidden/backgrounded without
 *     any extra visibilitychange plumbing. Only the panel-open/closed gate
 *     above is bespoke.
 *
 * Always re-fetches the FULL thread (`since=0`) rather than incrementally
 * merging `since=<lastId>` pages into the query cache: at MVP support-chat
 * volume (a handful to a few dozen messages per thread) the bandwidth cost of
 * refetching everything every 6s is negligible, and it avoids a manual
 * setQueryData-merge path that would be pure incidental complexity here.
 */

import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";

import { apiFetch, HTTPError } from "@/lib/api";

const BASE = "/api/v1/trade-in/support";

// Mirrors backend `MAX_MESSAGE_LENGTH` (app/api/v1/support.py) — enforced
// client-side too so the send button disables before the round-trip 422/400.
export const MAX_SUPPORT_MESSAGE_LENGTH = 4000;

export type SupportMessageDirection = "in" | "out";

export interface SupportMessage {
  id: number;
  direction: SupportMessageDirection;
  text_body: string;
  operator_tg_id: number | null;
  created_at: string;
}

export interface SupportUnread {
  unread: number;
}

const SUPPORT_MESSAGES_KEY = ["trade-in", "support", "messages"] as const;
const SUPPORT_UNREAD_KEY = ["trade-in", "support", "unread"] as const;

const MESSAGES_POLL_MS = 6_000;
const UNREAD_POLL_MS = 20_000;

/**
 * Polls the caller's own thread. `enabled` should be the chat-panel `open`
 * flag — see module docstring.
 */
export function useSupportMessages(enabled: boolean) {
  return useQuery<SupportMessage[]>({
    queryKey: SUPPORT_MESSAGES_KEY,
    queryFn: () => apiFetch<SupportMessage[]>(`${BASE}/messages?since=0`),
    enabled,
    staleTime: 0,
    refetchInterval: enabled ? MESSAGES_POLL_MS : false,
  });
}

/**
 * Feeds the unread badge on the closed floating button. `enabled` should be
 * `!open` — see module docstring.
 */
export function useSupportUnread(enabled: boolean) {
  return useQuery<SupportUnread>({
    queryKey: SUPPORT_UNREAD_KEY,
    queryFn: () => apiFetch<SupportUnread>(`${BASE}/unread`),
    enabled,
    staleTime: 0,
    refetchInterval: enabled ? UNREAD_POLL_MS : false,
  });
}

export function useSendSupportMessage() {
  const queryClient = useQueryClient();
  return useMutation<SupportMessage, Error, string>({
    mutationFn: (text) =>
      apiFetch<SupportMessage>(`${BASE}/messages`, {
        method: "POST",
        body: JSON.stringify({ text }),
      }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: SUPPORT_MESSAGES_KEY });
    },
  });
}

/**
 * Marks the thread read (moves backend `last_read_at` forward). Called on the
 * open->closed AND closed->open transition (see SupportChatPanel) so the
 * unread badge never counts messages the visitor demonstrably already saw
 * while the panel was open.
 */
export function useMarkSupportRead() {
  const queryClient = useQueryClient();
  return useMutation<void, Error, void>({
    mutationFn: async () => {
      await apiFetch<{ status: string }>(`${BASE}/read`, { method: "POST" });
    },
    onSuccess: () => {
      queryClient.setQueryData<SupportUnread>(SUPPORT_UNREAD_KEY, { unread: 0 });
    },
  });
}

/**
 * Human-readable error text for both the messages-query error state and the
 * send-mutation error banner. Backend already returns RU human text in
 * `detail` for 429/503/502 (SERVICE_UNAVAILABLE_TEXT / rate-limit message) —
 * `HTTPError.message` is that `detail` (see lib/api.ts). A non-HTTPError means
 * `fetch` itself threw (offline / DNS / CORS) — apiFetch never got a response.
 */
export function describeSupportError(error: unknown): string {
  if (error instanceof HTTPError) {
    return error.message;
  }
  return "Не удалось связаться с сервером. Проверьте подключение и повторите.";
}
