"use client";
/**
 * ChatScreen 编排层
 *
 * 原始 Dart: lib/ui/chat/chat_screen.dart（172 行）
 *
 * 职责（本文件）：
 *   - **订阅 auth 状态机**（loginStatus）—— 派生 isGuest / **派鉴权生命周期事件**给 chat 机器
 *   - 屏幕生命周期事件（init / visible / invisible）
 *   - 配额告警监听（**仅**游客 —— "非游客无消息限制"业务事实）
 *   - **不**直接管理 WebSocket / **不**直接读 AuthStorage（除 token 取值）
 *
 * 子组件职责：
 *   - ChatHeader：顶部栏（游客 banner / 菜单按钮）
 *   - ChatArea：消息列表
 *   - ChatInputBar：输入栏（文字 + 发送 + More）
 *   - QuotaDialog：配额告警弹窗（**仅**游客）
 *   - PwaInstallOverlay：PWA 安装提示触发器
 *   - BrowserHintOverlay：浏览器提示
 *   - CharacterIntro：角色介绍卡片（首屏）
 *
 * **鉴权解耦**（**事件驱动**）：
 *   - chat 机器**不**感知鉴权 / **不**管 WebSocket —— 由 chat-screen 派生 loginStatus
 *   - chat-screen **只**派 3 个事件：
 *     - `ChatGuestLogin` → 游客会话（**断** WS = 不连）
 *     - `ChatNonGuestLogin { token }` → 非游客会话（**连** WS）
 *     - `ChatLogout` → 登出（机器自动 cleanup WS actor）
 *   - chat 机器**内部**用 fromCallback actor 完整管理 WS 生命周期
 */
import { useEffect, useRef, useState } from "react";
import Image from "next/image";

import { useAuthState } from "@/stores/auth/auth-context";
import type { LoginStatus } from "@/models/auth/login-status";
import { AuthStorage } from "@/data/storage/auth/auth_storage";
import { useChatDispatch, useChatState } from "@/stores/chat/chat-context";
import { GuestChatQuota } from "@/stores/chat";

import { MobileShell } from "@/app/_components/core/mobile-shell";

import { BrowserHintOverlay } from "./browser-hint-overlay";
import { ChatArea } from "./chat-area";
import { ChatHeader } from "./chat-header";
import { ChatInputBar } from "./chat-input-bar";
import { PwaInstallOverlay } from "./pwa-install-overlay";
import { QuotaDialog } from "./quota-dialog";
import styles from "./chat-screen.module.css";

/**
 * 派生 isGuest —— 单一来源：`auth.loginStatus`
 */
function deriveIsGuest(loginStatus: LoginStatus): boolean {
  return loginStatus === "guest";
}

/**
 * 按 loginStatus 派鉴权生命周期事件（chat 机器**不**感知 loginStatus —— 这层转换在此）
 *
 * 设计：**不**直接管理 WS / **不**读 AuthStorage（除取 token）
 */
function dispatchAuthLifecycle(
  loginStatus: LoginStatus,
  chatDispatch: ReturnType<typeof useChatDispatch>,
): void {
  if (loginStatus === "guest") {
    // 游客：派 ChatGuestLogin（chat 机器**不**连 WS —— 业务事实"断 WS"）
    chatDispatch({ type: "ChatGuestLogin" });
    return;
  }
  if (loginStatus === "notLoggedIn") {
    // 登出：派 ChatLogout（chat 机器自动 cleanup WS actor + 清消息）
    chatDispatch({ type: "ChatLogout" });
    return;
  }
  // 非游客：拿 loginToken → 派 ChatNonGuestLogin { token }
  void (async () => {
    const tokenR = await AuthStorage.getInstance().getLoginToken();
    if (tokenR.success && tokenR.data) {
      chatDispatch({ type: "ChatNonGuestLogin", token: tokenR.data });
    }
  })();
}

export function ChatScreen() {
  const state = useChatState();
  const authState = useAuthState();
  const chatDispatch = useChatDispatch();

  // isGuest 派生（chat-screen 是**唯一**知道这个值的地方 —— chat 机器无 isGuest 字段）
  const isGuest = deriveIsGuest(authState.loginStatus);

  const [quotaDialogOpen, setQuotaDialogOpen] = useState(false);
  const [quotaExhausted, setQuotaExhausted] = useState(false);

  // ─────────────────────────────────────────────────────────────
  // 屏幕生命周期 + 派初次鉴权生命周期事件
  // ─────────────────────────────────────────────────────────────
  useEffect(() => {
    chatDispatch({ type: "ChatScreenVisible" });
    dispatchAuthLifecycle(authState.loginStatus, chatDispatch);
    return () => {
      chatDispatch({ type: "ChatScreenInvisible" });
    };
    // 注：mount useEffect 故意**不**依赖 loginStatus —— 首次 mount 时机是固定的
    //     （"用户进 /chat 那一刻"），loginStatus 由 splash/auth-screen 提前 settle。
    //     loginStatus 后续变化由下方"副作用 ②" 统一处理。
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [chatDispatch]);

  // ─────────────────────────────────────────────────────────────
  // 副作用 ②：loginStatus 变化 → 派对应鉴权生命周期事件
  //
  // 规则：
  //   - 首次 mount（prev === null）→ 由 mount useEffect 统一处理
  //   - "notLoggedIn" → 派 ChatLogout
  //   - 登录态变化（guest→email 等）→ 派 ChatGuestLogin 或 ChatNonGuestLogin
  // ─────────────────────────────────────────────────────────────
  const prevLoginStatusRef = useRef<LoginStatus | null>(null);
  useEffect(() => {
    const prev = prevLoginStatusRef.current;
    prevLoginStatusRef.current = authState.loginStatus;
    if (prev === null) return; // 首次 mount 由 mount useEffect 处理
    if (prev === authState.loginStatus) return; // 登录态**没**变
    dispatchAuthLifecycle(authState.loginStatus, chatDispatch);
  }, [authState.loginStatus, chatDispatch]);

  // ─────────────────────────────────────────────────────────────
  // 配额耗尽触发器（**仅**游客 —— "非游客无消息限制"）
  // ─────────────────────────────────────────────────────────────
  const prevTriggerRef = useRef(state.quotaExceededTrigger);
  useEffect(() => {
    if (!isGuest) return; // ← 防御：非游客 backend 不会发 ChatQuotaExceeded
    if (
      state.quotaExceededTrigger !== prevTriggerRef.current &&
      state.quotaExceededTrigger > 0
    ) {
      setQuotaExhausted(true);
      setQuotaDialogOpen(true);
    }
    prevTriggerRef.current = state.quotaExceededTrigger;
  }, [state.quotaExceededTrigger, isGuest]);

  // 配额警告（剩余 = 5）—— **仅**游客
  const prevRemainingRef = useRef(state.guestRemainingQuota);
  useEffect(() => {
    if (
      isGuest && // ← 派生自 auth.loginStatus
      state.guestRemainingQuota === GuestChatQuota.warningThreshold &&
      prevRemainingRef.current !== state.guestRemainingQuota
    ) {
      setQuotaExhausted(false);
      setQuotaDialogOpen(true);
    }
    prevRemainingRef.current = state.guestRemainingQuota;
  }, [state.guestRemainingQuota, isGuest]);

  return (
    <MobileShell>
      <div className={styles.shell}>
        {/* 背景图（与原 Dart MobileLayout 一致） */}
        <div className={styles.background}>
          <Image
            src="/images/chat/bg-chatpage.png"
            alt=""
            fill
            priority
            sizes="(max-width: 500px) 100vw, 500px"
          />
        </div>

        <div className={styles.layout}>
          {/* isGuest 派生自 auth.loginStatus */}
          <ChatHeader isGuest={isGuest} />

          <ChatArea
            messages={state.messages}
            isReplyingAI={state.isReplyingAI}
            isGuest={isGuest}
          />

          <ChatInputBar disabled={state.isReplyingAI} />
        </div>

        {/* 浏览器提示（应用内浏览器检测） */}
        <BrowserHintOverlay />

        {/* PWA 安装提示触发器（无可见 UI，3.5s 后弹 dialog） */}
        <PwaInstallOverlay />

        {/* 配额告警弹窗（**仅**游客，gate 在 isGuest） */}
        <QuotaDialog
          open={quotaDialogOpen}
          onClose={() => setQuotaDialogOpen(false)}
          isExhausted={quotaExhausted}
        />
      </div>
    </MobileShell>
  );
}
