"use client";

import { useEffect, useMemo, type CSSProperties } from "react";
import Image from "next/image";
import { useRouter, useSearchParams } from "next/navigation";

import { useAuthDispatch, useAuthState } from "@/stores/auth/auth-context";
import { useChatState } from "@/stores/chat/chat-context";
import { ROUTES } from "@/router/routes";

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

import {
  BrowserHintOverlay,
  ChatArea,
  ChatHeader,
  ChatInputBar,
  ChatInsufficientCreditsBanner,
  ChatUnlockDialogs,
  FirstRechargeOfferBanner,
  FullscreenImageViewer,
  PwaInstallOverlay,
} from "./components";
import {
  buildChatImageOverlayUrl,
  buildChatWithoutImageOverlayUrl,
  getChatImageOverlayMessageId,
} from "./chat-image-overlay-url";
import {
  deriveIsGuest,
  shouldStartExternalBrowserPrompt,
} from "./chat-screen.helpers";
import { useFirstRechargeOfferBanner } from "./hooks/use-first-recharge-offer-banner";
import { useChatUnlockNavigationFlow } from "./hooks/use-chat-unlock-navigation-flow";
import { useChatGuestLogin } from "./hooks/use-chat-guest-login";
import { useChatMessageLimitBanner } from "./hooks/use-chat-message-limit-banner";
import { useChatPromotionBootstrap } from "./hooks/use-chat-promotion-bootstrap";
import { useSplashLatestMessageSync } from "./hooks/use-splash-latest-message-sync";

const chatShellStyle = {
  "--chat-message-font-size": "clamp(16px, 3.333vw, 18px)",
  "--chat-message-line-height": "1.5",
} as CSSProperties;

export function ChatScreen() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const state = useChatState();
  const authState = useAuthState();
  const authDispatch = useAuthDispatch();
  useSplashLatestMessageSync({
    historyLoaded: state.historyLoaded,
    loginStatus: authState.loginStatus,
    messages: state.historyMessages,
  });
  const isPromotionBootstrapReady = useChatPromotionBootstrap();
  const visibleMessages = isPromotionBootstrapReady
    ? state.messages
    : state.historyMessages;
  const imageMessageId = getChatImageOverlayMessageId(searchParams);
  const imageReturnUrl = imageMessageId
    ? buildChatImageOverlayUrl(imageMessageId)
    : ROUTES.chat;
  const {
    unlockPaywallRequest,
    requestMessageUnlock,
    closeInsufficientCreditsDialog,
    confirmInsufficientCreditsDialog,
  } = useChatUnlockNavigationFlow({
    returnUrl: ROUTES.chat,
    ignoredKind: "image",
    promotionScope: "exclude",
    enabled: isPromotionBootstrapReady,
  });
  const {
    unlockPaywallRequest: imageUnlockPaywallRequest,
    requestMessageUnlock: requestImageUnlock,
    closeInsufficientCreditsDialog: closeImageInsufficientCreditsDialog,
    confirmInsufficientCreditsDialog: confirmImageInsufficientCreditsDialog,
  } = useChatUnlockNavigationFlow({
    returnUrl: imageReturnUrl,
    expectedKind: "image",
    expectedMessageId: imageMessageId ?? undefined,
    promotionScope: "exclude",
    enabled: isPromotionBootstrapReady && imageMessageId !== null,
  });
  const {
    unlockPaywallRequest: promotionUnlockPaywallRequest,
    requestMessageUnlock: requestPromotionUnlock,
    closeInsufficientCreditsDialog: closePromotionInsufficientCreditsDialog,
    confirmInsufficientCreditsDialog:
      confirmPromotionInsufficientCreditsDialog,
  } = useChatUnlockNavigationFlow({
    returnUrl: ROUTES.chat,
    promotionScope: "only",
    enabled: isPromotionBootstrapReady && state.promotion !== null,
  });
  const selectedImageMessage = useMemo(
    () =>
      imageMessageId
        ? visibleMessages.find(
            (item) => item.id === imageMessageId && item.imageUrl,
          ) ?? null
        : null,
    [imageMessageId, visibleMessages],
  );

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

  // 发送能力由后端统一返回，当前只处理积分不足引导。
  const messageLimitBanner = useChatMessageLimitBanner({
    upgradePromptVisible: state.upgradePromptVisible,
    upgradeReason: state.upgradeReason,
    loginStatus: authState.loginStatus,
  });
  const firstRechargeOfferBanner = useFirstRechargeOfferBanner({
    historyLoaded: state.historyLoaded,
    loginStatus: authState.loginStatus,
  });
  const shouldShowPwaInstall =
    state.historyLoaded && state.historyMessages.length >= 10;
  const shouldShowBrowserHint = shouldStartExternalBrowserPrompt({
    hasInitialized: authState.hasInitialized,
    isLoading: authState.isLoading,
    loginStatus: authState.loginStatus,
  });

  useChatGuestLogin({
    dispatch: authDispatch,
    hasInitialized: authState.hasInitialized,
    isLoading: authState.isLoading,
    loginStatus: authState.loginStatus,
  });

  useEffect(() => {
    if (!imageMessageId || !state.historyLoaded || selectedImageMessage) {
      return;
    }
    router.replace(buildChatWithoutImageOverlayUrl(searchParams), {
      scroll: false,
    });
  }, [
    imageMessageId,
    router,
    searchParams,
    selectedImageMessage,
    state.historyLoaded,
  ]);

  function handleUnlockPrivateMessage(messageId: string): void {
    if (requestPromotionMessageUnlock(messageId, "private")) return;
    requestMessageUnlock(messageId, "private");
  }

  function handleUnlockVoiceMessage(messageId: string): void {
    if (requestPromotionMessageUnlock(messageId, "voice")) return;
    requestMessageUnlock(messageId, "voice");
  }

  function handleUnlockImageMessage(messageId: string): void {
    if (requestPromotionMessageUnlock(messageId, "image")) return;
    requestMessageUnlock(messageId, "image");
  }

  function requestPromotionMessageUnlock(
    messageId: string,
    kind: "private" | "voice" | "image",
  ): boolean {
    const promotion = state.promotion;
    if (!promotion || promotion.message.id !== messageId) return false;

    const temporaryMessageId = `promotion:${promotion.session.clientLockId}`;
    requestPromotionUnlock(messageId, kind, {
      remoteMessageId:
        messageId === temporaryMessageId ? undefined : messageId,
      lockType: promotion.session.lockType,
      clientLockId: promotion.session.clientLockId,
      promotion: promotion.session,
    });
    return true;
  }

  function handleOpenImage(messageId: string): void {
    router.push(buildChatImageOverlayUrl(messageId), { scroll: false });
  }

  function handleCloseImageViewer(): void {
    router.replace(buildChatWithoutImageOverlayUrl(searchParams), {
      scroll: false,
    });
  }

  function handleUnlockImagePaywall(): void {
    if (!imageMessageId) return;
    requestImageUnlock(imageMessageId, "image");
  }

  return (
    <MobileShell>
      <div
        className="relative flex h-(--app-viewport-height,100dvh) flex-col overflow-hidden bg-(--color-dark-background,#111) text-(--color-text-primary,#fff)"
        style={chatShellStyle}
      >
        <div className="pointer-events-none absolute inset-0 z-0">
          <Image
            src="/images/chat/bg-chatpage.png"
            alt=""
            fill
            priority
            sizes="(max-width: 540px) 100vw, 540px"
          />
        </div>

        <div className="relative z-1 flex min-h-0 flex-[1_1_auto] flex-col">
          {/* isGuest 派生自 auth.loginStatus */}
          <ChatHeader
            isGuest={isGuest}
            offerBanner={
              <FirstRechargeOfferBanner
                visible={firstRechargeOfferBanner.visible}
                discountPercent={firstRechargeOfferBanner.discountPercent}
                onClick={firstRechargeOfferBanner.claim}
                onClose={firstRechargeOfferBanner.close}
              />
            }
          />

          <ChatArea
            messages={visibleMessages}
            isReplyingAI={state.isReplyingAI}
            initialScrollReady={
              state.historyLoaded && isPromotionBootstrapReady
            }
            isUnlockingMessage={state.isUnlockingMessage}
            unlockingMessageId={state.unlockingMessageId}
            onUnlockPrivateMessage={handleUnlockPrivateMessage}
            onUnlockVoiceMessage={handleUnlockVoiceMessage}
            onUnlockImageMessage={handleUnlockImageMessage}
            onOpenImage={handleOpenImage}
          />

          {messageLimitBanner.visible ? (
            <ChatInsufficientCreditsBanner
              title={messageLimitBanner.title}
              description={messageLimitBanner.description}
              ctaLabel={messageLimitBanner.ctaLabel}
              onUnlock={messageLimitBanner.unlock}
            />
          ) : (
            <ChatInputBar disabled={!state.historyLoaded} />
          )}
        </div>

        {/* 浏览器提示（应用内浏览器检测） */}
        {shouldShowBrowserHint ? <BrowserHintOverlay forceShow /> : null}

        {/* PWA 安装提示触发器（聊天消息数量达到阈值后才允许弹出） */}
        <PwaInstallOverlay enabled={shouldShowPwaInstall} />

        <ChatUnlockDialogs
          unlockPaywallRequest={unlockPaywallRequest}
          onCloseInsufficientCreditsDialog={closeInsufficientCreditsDialog}
          onConfirmInsufficientCreditsDialog={confirmInsufficientCreditsDialog}
        />
        <ChatUnlockDialogs
          unlockPaywallRequest={promotionUnlockPaywallRequest}
          includeHistoryUnlock={false}
          onCloseInsufficientCreditsDialog={
            closePromotionInsufficientCreditsDialog
          }
          onConfirmInsufficientCreditsDialog={
            confirmPromotionInsufficientCreditsDialog
          }
        />
        <ChatUnlockDialogs
          unlockPaywallRequest={imageUnlockPaywallRequest}
          includeHistoryUnlock={false}
          onCloseInsufficientCreditsDialog={closeImageInsufficientCreditsDialog}
          onConfirmInsufficientCreditsDialog={
            confirmImageInsufficientCreditsDialog
          }
        />

        {selectedImageMessage?.imageUrl ? (
          <FullscreenImageViewer
            messageId={selectedImageMessage.id}
            imageUrl={selectedImageMessage.imageUrl}
            imagePaywalled={selectedImageMessage.imagePaywalled === true}
            isUnlockingImagePaywall={
              state.isUnlockingMessage &&
              state.unlockingMessageId === selectedImageMessage.id
            }
            onUnlockImagePaywall={handleUnlockImagePaywall}
            onClose={handleCloseImageViewer}
          />
        ) : null}
      </div>
    </MobileShell>
  );
}
