"use client";

import {
  type Dispatch,
  type ReactNode,
  createContext,
  useContext,
  useMemo,
} from "react";
import { useMachine } from "@xstate/react";

import { chatMachine } from "./chat-machine";
import type { ChatEvent, ChatState as MachineContext } from "./chat-machine";

/**
 * 对外暴露的 State 形状
 *
 * isGuest 字段已删 —— 由 chat-screen 派生自 `auth.loginStatus === "guest"`。
 *   消费方（chat-screen）通过 `useAuthState()` 取 loginStatus，本地派生 isGuest。
 */
interface ChatState {
  messages: MachineContext["messages"];
  isReplyingAI: boolean;
  /** 游客剩余配额（次/天）—— 业务展示用，鉴权判断由 chat-screen 派生 loginStatus */
  guestRemainingQuota: number;
  /** 游客总配额 */
  guestTotalQuota: number;
  quotaExceededTrigger: number;
  paywallTriggered: boolean;
  paywallReason: MachineContext["paywallReason"];
  paywallDetail: MachineContext["paywallDetail"];
  isLoadingMore: boolean;
  hasMore: boolean;
  historyOffset: number;
  /** 游客配额加载完成标志（仅 guestSession 期间） —— UI 可用此显示 loading */
  quotaLoaded: boolean;
  /** history 初始加载完成标志（local → network → save 跑完） —— UI 可用此显示 loading */
  historyLoaded: boolean;
}

const ChatStateCtx = createContext<ChatState | null>(null);
const ChatDispatchCtx = createContext<Dispatch<ChatEvent> | null>(null);

export interface ChatProviderProps {
  children: ReactNode;
}

export function ChatProvider({ children }: ChatProviderProps) {
  const [state, send] = useMachine(chatMachine, {});

  // 映射 XState 状态机快照 → 原 ChatState 形状
  const chatState = useMemo<ChatState>(
    () => ({
      messages: state.context.messages,
      isReplyingAI: state.context.isReplyingAI,
      guestRemainingQuota: state.context.guestRemainingQuota,
      guestTotalQuota: state.context.guestTotalQuota,
      quotaExceededTrigger: state.context.quotaExceededTrigger,
      paywallTriggered: state.context.paywallTriggered,
      paywallReason: state.context.paywallReason,
      paywallDetail: state.context.paywallDetail,
      isLoadingMore: state.context.isLoadingMore,
      hasMore: state.context.hasMore,
      historyOffset: state.context.historyOffset,
      quotaLoaded: state.context.quotaLoaded,
      historyLoaded: state.context.historyLoaded,
    }),
    [state],
  );

  return (
    <ChatStateCtx.Provider value={chatState}>
      <ChatDispatchCtx.Provider value={send}>{children}</ChatDispatchCtx.Provider>
    </ChatStateCtx.Provider>
  );
}

export function useChatState(): ChatState {
  const ctx = useContext(ChatStateCtx);
  if (!ctx) throw new Error("useChatState must be used inside <ChatProvider>");
  return ctx;
}

export function useChatDispatch(): Dispatch<ChatEvent> {
  const ctx = useContext(ChatDispatchCtx);
  if (!ctx)
    throw new Error("useChatDispatch must be used inside <ChatProvider>");
  return ctx;
}
