"use client";

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

import { CharacterAvatar } from "@/app/_components";
import {
  AppBottomNav,
  FavoriteEntryButton,
  MobileShell,
} from "@/app/_components/core";
import { buildGlobalPageUrl } from "@/router/global-route-context";
import { ROUTES } from "@/router/routes";
import { useAppNavigator } from "@/router/use-app-navigator";
import {
  useActiveCharacter,
  useActiveCharacterRoutes,
} from "@/providers/character-provider";
import { isPrivateAlbumLocked } from "@/lib/private-zone/private_album";
import { behaviorAnalytics } from "@/lib/analytics";
import { recordChatActionEventById } from "@/lib/chat/chat_action_events";
import { useUserSelector } from "@/stores/user/user-context";
import { useAuthDispatch, useAuthState } from "@/stores/auth/auth-context";
import {
  usePrivateZoneDispatch,
  usePrivateZoneState,
} from "@/stores/private-zone";
import {
  usePrivateZonePostDispatch,
  usePrivateZonePostState,
} from "@/stores/private-zone-posts";

import {
  PrivateAlbumCard,
  PrivateAlbumGallery,
  PrivateZoneVideoPostCard,
  StatusCard,
  UnlockConfirmDialog,
  VideoPostUnlockDialog,
} from "./components";
import styles from "./private-zone-screen.module.css";
import {
  isPrivateZoneAuthRequired,
  usePrivateZoneBootstrapFlow,
  usePrivateZoneUnlockPaywallNavigation,
  usePrivateZoneUnlockSuccessRefresh,
} from "./use-private-zone-flow";
import {
  buildPrivateAlbumGalleryUrl,
  buildPrivateZoneWithoutGalleryUrl,
  getPrivateAlbumGalleryState,
} from "./private-album-gallery-url";
import { findPrivateAlbumDisplayImage } from "./private-album-images";

export function PrivateZoneScreen() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const navigator = useAppNavigator();
  const character = useActiveCharacter();
  const characterRoutes = useActiveCharacterRoutes();
  const authState = useAuthState();
  const authDispatch = useAuthDispatch();
  const state = usePrivateZoneState();
  const dispatch = usePrivateZoneDispatch();
  const postState = usePrivateZonePostState();
  const postDispatch = usePrivateZonePostDispatch();
  const isVip = useUserSelector((user) => user.context.isVip);
  const [activeTab, setActiveTab] = useState<"moments" | "albums">("albums");
  const openedGalleryInPageRef = useRef(false);
  const previousPostLoginStatusRef = useRef(authState.loginStatus);
  const galleryState = useMemo(
    () => getPrivateAlbumGalleryState(searchParams),
    [searchParams],
  );
  const visibleTab = galleryState ? "albums" : activeTab;

  usePrivateZoneBootstrapFlow({
    authDispatch,
    hasInitialized: authState.hasInitialized,
    isAuthLoading: authState.isLoading,
    loginStatus: authState.loginStatus,
    roomDispatch: dispatch,
    roomStatus: state.status,
  });
  usePrivateZoneUnlockPaywallNavigation({
    loginStatus: authState.loginStatus,
    roomDispatch: dispatch,
    unlockPaywallRequest: state.unlockPaywallRequest,
    isVip,
  });
  usePrivateZoneUnlockSuccessRefresh(state.unlockSuccessNonce);
  usePrivateZoneUnlockSuccessRefresh(postState.unlockSuccessNonce);

  useEffect(() => {
    if (!authState.hasInitialized || authState.isLoading) return;
    if (authState.loginStatus === "notLoggedIn") return;

    const previous = previousPostLoginStatusRef.current;
    previousPostLoginStatusRef.current = authState.loginStatus;
    if (postState.status === "idle") {
      postDispatch({ type: "PrivateZonePostInit" });
      return;
    }
    if (previous !== authState.loginStatus && postState.status !== "loading") {
      postDispatch({ type: "PrivateZonePostRefresh" });
    }
  }, [
    authState.hasInitialized,
    authState.isLoading,
    authState.loginStatus,
    postDispatch,
    postState.status,
  ]);

  useEffect(() => {
    const request = postState.unlockPaywallRequest;
    if (!request) return;
    if (isPrivateZoneAuthRequired(authState.loginStatus)) {
      navigator.openAuth(characterRoutes.privateZone);
    } else {
      behaviorAnalytics.paywallShown({
        entryPoint: "private_zone",
        triggerReason: "insufficient_credits",
      });
      const guidance =
        request.paymentGuidance?.characterId === character.id
          ? request.paymentGuidance
          : null;
      if (guidance) {
        void recordChatActionEventById(
          guidance.guidanceId,
          character.id,
          "opened",
        ).catch(() => undefined);
      }
      navigator.openSubscription({
        type:
          isVip || (guidance && !guidance.purchaseOptions.includes("vip"))
            ? "topup"
            : "vip",
        returnTo: "private-zone",
        ...(guidance ? { chatActionId: guidance.guidanceId } : {}),
        analytics: {
          entryPoint: "private_zone",
          triggerReason: "insufficient_credits",
        },
      });
    }
    postDispatch({ type: "PrivateZonePostUnlockPaywallConsumed" });
  }, [
    authState.loginStatus,
    characterRoutes.privateZone,
    character.id,
    isVip,
    navigator,
    postDispatch,
    postState.unlockPaywallRequest,
  ]);

  const displayName = character.displayName;
  const avatarUrl = character.assets.avatar;
  const title = character.copy.privateZoneTitle;
  const subtitle = character.copy.privateZoneSubtitle;
  const pendingAlbum = useMemo(
    () =>
      state.items.find(
        (album) => album.albumId === state.pendingConfirmAlbumId,
      ) ?? null,
    [state.items, state.pendingConfirmAlbumId],
  );
  const pendingPost = useMemo(
    () =>
      postState.items.find(
        (post) => post.postId === postState.pendingConfirmPostId,
      ) ?? null,
    [postState.items, postState.pendingConfirmPostId],
  );
  const galleryAlbum = useMemo(
    () =>
      galleryState
        ? state.items.find((album) => album.albumId === galleryState.albumId) ??
          null
        : null,
    [galleryState, state.items],
  );
  const galleryImage = useMemo(
    () =>
      galleryAlbum && galleryState
        ? findPrivateAlbumDisplayImage(
            galleryAlbum,
            galleryState.imageIndex,
          )
        : null,
    [galleryAlbum, galleryState],
  );

  useEffect(() => {
    if (!galleryState || state.isLoading) return;
    if (
      !galleryAlbum ||
      isPrivateAlbumLocked(galleryAlbum) ||
      !galleryImage
    ) {
      router.replace(
        buildPrivateZoneWithoutGalleryUrl(
          searchParams,
          characterRoutes.privateZone,
        ),
        { scroll: false },
      );
    }
  }, [
    characterRoutes.privateZone,
    galleryAlbum,
    galleryImage,
    galleryState,
    router,
    searchParams,
    state.isLoading,
  ]);

  const handleTopUpClick = () => {
    if (isPrivateZoneAuthRequired(authState.loginStatus)) {
      navigator.openAuth(characterRoutes.privateZone);
      return;
    }
    navigator.openSubscription({
      type: isVip ? "topup" : "vip",
      returnTo: "private-zone",
      analytics: {
        entryPoint: "private_zone",
        triggerReason: "vip_cta",
      },
    });
  };

  const handleOpenGallery = (albumId: string, imageIndex: number) => {
    openedGalleryInPageRef.current = true;
    router.push(
      buildPrivateAlbumGalleryUrl(
        albumId,
        imageIndex,
        characterRoutes.privateZone,
      ),
      { scroll: false },
    );
  };

  const handlePostUnlock = (postId: string) => {
    if (isPrivateZoneAuthRequired(authState.loginStatus)) {
      navigator.openAuth(characterRoutes.privateZone);
      return;
    }
    postDispatch({ type: "PrivateZonePostUnlockRequested", postId });
  };

  const handleCloseGallery = () => {
    if (openedGalleryInPageRef.current) {
      openedGalleryInPageRef.current = false;
      router.back();
      return;
    }
    router.replace(
      buildPrivateZoneWithoutGalleryUrl(
        searchParams,
        characterRoutes.privateZone,
      ),
      { scroll: false },
    );
  };

  const handleGalleryIndexChange = (imageIndex: number) => {
    if (!galleryAlbum) return;
    router.replace(
      buildPrivateAlbumGalleryUrl(
        galleryAlbum.albumId,
        imageIndex,
        characterRoutes.privateZone,
      ),
      { scroll: false },
    );
  };

  return (
    <MobileShell background="#f3f4f2">
      <main className={styles.shell}>
        <div className={styles.backgroundGlowOne} />
        <div className={styles.backgroundGlowTwo} />
        <div className={styles.favoriteAction}>
          <FavoriteEntryButton
            characterSlug={character.slug}
            tone="dark"
          />
        </div>

        <section className={styles.hero} aria-label={title}>
          <div className={styles.heroCover}>
            <Image
              src={character.assets.privateZoneBanner}
              alt=""
              width={2048}
              height={1152}
              className={styles.heroBanner}
              priority
              sizes="(max-width: 540px) 100vw, 540px"
            />

            <div className={styles.identity}>
              <div className={styles.avatarFrame}>
                <CharacterAvatar
                  src={avatarUrl}
                  alt={displayName}
                  size="100%"
                  imageSize={32}
                  priority
                />
              </div>

              <p className={styles.identityName}>{displayName}</p>
            </div>
          </div>

          <button
            type="button"
            data-analytics-key="private_zone.primary_cta"
            data-analytics-label="Open private zone top up"
            className={styles.primaryCta}
            onClick={handleTopUpClick}
          >
            <span>{subtitle}</span>
          </button>
        </section>

        <section className={styles.postsSection} aria-labelledby="posts-title">
          <div className={styles.contentTabs} role="tablist" aria-label="Private Zone content">
            <button
              type="button"
              role="tab"
              aria-selected={visibleTab === "albums"}
              className={`${styles.contentTab} ${visibleTab === "albums" ? styles.contentTabActive : ""}`}
              onClick={() => setActiveTab("albums")}
            >
              Albums
            </button>
            <button
              type="button"
              role="tab"
              aria-selected={visibleTab === "moments"}
              className={`${styles.contentTab} ${visibleTab === "moments" ? styles.contentTabActive : ""}`}
              onClick={() => setActiveTab("moments")}
            >
              Moments
            </button>
          </div>

          <div className={styles.sectionHeader}>
            <div>
              <p className={styles.kicker}>{visibleTab === "moments" ? "Moments" : "Albums"}</p>
              <h2 id="posts-title" className={styles.sectionTitle}>
                {visibleTab === "moments" ? "Private moments" : "Private albums"}
              </h2>
            </div>
            <span className={styles.postCount}>
              {visibleTab === "moments" ? postState.items.length : state.items.length}
            </span>
          </div>

          {visibleTab === "moments" ? (
            <>
              {postState.errorMessage ? (
                <StatusCard
                  message={postState.errorMessage}
                  actionLabel="Retry"
                  onAction={() => postDispatch({ type: "PrivateZonePostRefresh" })}
                />
              ) : null}
              {postState.isLoading && postState.items.length === 0 ? (
                <StatusCard message="Loading private moments..." />
              ) : null}
              {!postState.isLoading && !postState.errorMessage && postState.items.length === 0 ? (
                <StatusCard message="No private moments yet." />
              ) : null}
              <div className={styles.timeline}>
                {postState.items.map((post, index) => (
                  <PrivateZoneVideoPostCard
                    key={post.postId}
                    post={post}
                    displayName={displayName}
                    avatarUrl={avatarUrl}
                    index={index}
                    isUnlocking={postState.unlockingPostId === post.postId}
                    onUnlock={() => handlePostUnlock(post.postId)}
                    onPlaybackError={() =>
                      postDispatch({ type: "PrivateZonePostRefresh" })
                    }
                  />
                ))}
              </div>
              {postState.hasMore ? (
                <button
                  type="button"
                  className={styles.loadMoreButton}
                  disabled={postState.isLoadingMore}
                  onClick={() => postDispatch({ type: "PrivateZonePostLoadMore" })}
                >
                  {postState.isLoadingMore ? "Loading..." : "Load more"}
                </button>
              ) : null}
            </>
          ) : (
            <>
              {state.errorMessage ? (
                <StatusCard
                  message={state.errorMessage}
                  actionLabel="Retry"
                  onAction={() => dispatch({ type: "PrivateZoneRefresh" })}
                />
              ) : null}
              {state.isLoading && state.items.length === 0 ? (
                <StatusCard message="Loading private albums..." />
              ) : null}
              <div className={styles.timeline}>
                {state.items.map((album, index) => (
                  <PrivateAlbumCard
                    key={album.albumId}
                    album={album}
                    displayName={displayName}
                    avatarUrl={avatarUrl}
                    index={index}
                    isUnlocking={state.unlockingAlbumId === album.albumId}
                    onOpenGallery={(imageIndex) =>
                      handleOpenGallery(album.albumId, imageIndex)
                    }
                    onUnlock={() =>
                      dispatch({
                        type: "PrivateZoneUnlockRequested",
                        albumId: album.albumId,
                      })
                    }
                  />
                ))}
              </div>
            </>
          )}
        </section>

        <AppBottomNav
          activeItem="privateZone"
          privateZoneLabel={character.copy.privateZoneTitle}
          onChatClick={() =>
            navigator.push(characterRoutes.splash, { scroll: false })
          }
          onPrivateZoneClick={() => undefined}
          onMenuClick={() =>
            navigator.push(
              buildGlobalPageUrl(ROUTES.profile, characterRoutes.chat),
              { scroll: false },
            )
          }
        />

        {pendingAlbum ? (
          <UnlockConfirmDialog
            album={pendingAlbum}
            isUnlocking={state.isUnlocking}
            errorMessage={state.unlockErrorMessage}
            onCancel={() => dispatch({ type: "PrivateZoneUnlockCancelled" })}
            onConfirm={() => dispatch({ type: "PrivateZoneUnlockConfirmed" })}
          />
        ) : state.unlockErrorMessage ? (
          <div className={styles.toast} role="status">
            {state.unlockErrorMessage}
          </div>
        ) : null}

        {pendingPost ? (
          <VideoPostUnlockDialog
            post={pendingPost}
            isUnlocking={postState.isUnlocking}
            errorMessage={postState.unlockErrorMessage}
            onCancel={() =>
              postDispatch({ type: "PrivateZonePostUnlockCancelled" })
            }
            onConfirm={() =>
              postDispatch({ type: "PrivateZonePostUnlockConfirmed" })
            }
          />
        ) : postState.unlockErrorMessage ? (
          <div className={styles.toast} role="status">
            {postState.unlockErrorMessage}
          </div>
        ) : null}

        {galleryAlbum &&
        galleryState &&
        !isPrivateAlbumLocked(galleryAlbum) &&
        galleryImage ? (
          <PrivateAlbumGallery
            album={galleryAlbum}
            imageIndex={galleryState.imageIndex}
            onClose={handleCloseGallery}
            onImageIndexChange={handleGalleryIndexChange}
          />
        ) : null}
      </main>
    </MobileShell>
  );
}
