"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 {
  useChatDispatch,
  useChatState,
} from "@/stores/chat/chat-context";
import {
  useActiveCharacter,
  useActiveCharacterRoutes,
} from "@/providers/character-provider";
import { useCharacterCatalog } from "@/providers/character-catalog-provider";
import { clearPendingChatNavigation } from "@/lib/navigation/chat_unlock_session";
import { getCharacterRoutes } from "@/router/routes";

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

import {
  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 { useChatUnlockCoordinator } from "./hooks/use-chat-unlock-coordinator";
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 character = useActiveCharacter();
  const characterCatalog = useCharacterCatalog();
  const refreshCharacterCatalog = characterCatalog.refresh;
  const defaultCharacterSlug = characterCatalog.defaultCharacter.slug;
  const characterRoutes = useActiveCharacterRoutes();
  const searchParams = useSearchParams();
  const state = useChatState();
  const chatDispatch = useChatDispatch();
  const authState = useAuthState();
  const authDispatch = useAuthDispatch();
  useSplashLatestMessageSync({
    characterId: state.characterId,
    historyLoaded: state.historyLoaded,
    loginStatus: authState.loginStatus,
    messages: state.historyMessages,
  });
  const isPromotionBootstrapReady = useChatPromotionBootstrap(
    state.characterId,
  );
  const visibleMessages = isPromotionBootstrapReady
    ? state.messages
    : state.historyMessages;
  const imageMessageId = getChatImageOverlayMessageId(searchParams);
  const imageReturnUrl = imageMessageId
    ? buildChatImageOverlayUrl(imageMessageId, characterRoutes.chat)
    : characterRoutes.chat;
  const unlockCoordinator = useChatUnlockCoordinator({
    defaultReturnUrl: characterRoutes.chat,
    imageMessageId,
    imageReturnUrl,
    promotion: state.promotion,
    enabled: isPromotionBootstrapReady,
  });
  const selectedImageMessage = useMemo(
    () =>
      imageMessageId
        ? visibleMessages.find(
            (item) =>
              (item.displayId === imageMessageId ||
                item.remoteId === imageMessageId) &&
              item.imageUrl,
          ) ?? null
        : null,
    [imageMessageId, visibleMessages],
  );

  // Guest status belongs to auth state and is not duplicated in the Chat actor.
  const isGuest = deriveIsGuest(authState.loginStatus);

  // 发送能力由后端统一返回，当前只处理积分不足引导。
  const messageLimitBanner = useChatMessageLimitBanner({
    upgradePromptVisible: state.upgradePromptVisible,
    upgradeReason: state.upgradeReason,
  });
  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, characterRoutes.chat),
      { scroll: false },
    );
  }, [
    characterRoutes.chat,
    imageMessageId,
    router,
    searchParams,
    selectedImageMessage,
    state.historyLoaded,
  ]);

  useEffect(() => {
    const errorCode = state.characterErrorCode;
    if (errorCode === "CHARACTER_MISMATCH") {
      chatDispatch({ type: "ChatHistoryRefreshRequested" });
      return;
    }
    if (
      errorCode !== "CHARACTER_DISABLED" &&
      errorCode !== "CHARACTER_NOT_FOUND"
    ) {
      return;
    }

    let cancelled = false;
    void (async () => {
      if (errorCode === "CHARACTER_NOT_FOUND") {
        await clearPendingChatNavigation();
      }
      await refreshCharacterCatalog();
      if (!cancelled) {
        router.replace(
          getCharacterRoutes(defaultCharacterSlug).splash,
        );
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [
    chatDispatch,
    defaultCharacterSlug,
    refreshCharacterCatalog,
    router,
    state.characterErrorCode,
  ]);

  function handleUnlockPrivateMessage(
    displayMessageId: string,
    remoteMessageId?: string,
  ): void {
    unlockCoordinator.requestMessageUnlock({
      displayMessageId,
      remoteMessageId,
      kind: "private",
    });
  }

  function handleUnlockVoiceMessage(
    displayMessageId: string,
    remoteMessageId?: string,
  ): void {
    unlockCoordinator.requestMessageUnlock({
      displayMessageId,
      remoteMessageId,
      kind: "voice",
    });
  }

  function handleUnlockImageMessage(
    displayMessageId: string,
    remoteMessageId?: string,
  ): void {
    unlockCoordinator.requestMessageUnlock({
      displayMessageId,
      remoteMessageId,
      kind: "image",
    });
  }

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

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

  function handleUnlockImagePaywall(): void {
    if (!selectedImageMessage) return;
    unlockCoordinator.requestMessageUnlock({
      displayMessageId: selectedImageMessage.displayId,
      remoteMessageId: selectedImageMessage.remoteId,
      kind: "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={character.assets.chatBackground}
            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">
          <ChatHeader
            isGuest={isGuest}
            showBrowserHint={shouldShowBrowserHint}
            offerBanner={
              <FirstRechargeOfferBanner
                visible={firstRechargeOfferBanner.visible}
                discountPercent={firstRechargeOfferBanner.discountPercent}
                onClick={firstRechargeOfferBanner.claim}
                onClose={firstRechargeOfferBanner.close}
              />
            }
          />

          <ChatArea
            characterId={state.characterId}
            messages={visibleMessages}
            isReplyingAI={state.isReplyingAI}
            scrollToBottomSignal={state.outgoingMessageRevision}
            initialScrollReady={
              state.historyLoaded && isPromotionBootstrapReady
            }
            canLoadMoreHistory={state.hasMoreHistory}
            isLoadingMoreHistory={state.isLoadingMoreHistory}
            isUnlockingMessage={state.isUnlockingMessage}
            unlockingMessageId={state.unlockingMessageId}
            onUnlockPrivateMessage={handleUnlockPrivateMessage}
            onUnlockVoiceMessage={handleUnlockVoiceMessage}
            onUnlockImageMessage={handleUnlockImageMessage}
            onOpenImage={handleOpenImage}
            onLoadMoreHistory={() => {
              chatDispatch({ type: "ChatLoadMoreHistoryRequested" });
            }}
          />

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

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

        <ChatUnlockDialogs model={unlockCoordinator.dialogs} />

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