"use client";

import { type Dispatch, useEffect, useRef } from "react";

import type { LoginStatus } from "@/data/schemas/auth";
import { useGuestLoginBootstrap } from "@/hooks/use-guest-login-bootstrap";
import { behaviorAnalytics } from "@/lib/analytics";
import {
  useActiveCharacter,
  useActiveCharacterRoutes,
} from "@/providers/character-provider";
import { useAppNavigator } from "@/router/use-app-navigator";
import type { AuthEvent } from "@/stores/auth/auth-events";
import type { PrivateZoneEvent } from "@/stores/private-zone";
import type { PrivateZoneUnlockPaywallRequest } from "@/stores/private-zone/private-zone-state";
import { useUserDispatch } from "@/stores/user/user-context";
import { recordChatActionEventById } from "@/lib/chat/chat_action_events";

export interface UsePrivateZoneBootstrapFlowInput {
  authDispatch: Dispatch<AuthEvent>;
  hasInitialized: boolean;
  isAuthLoading: boolean;
  loginStatus: LoginStatus;
  roomDispatch: Dispatch<PrivateZoneEvent>;
  roomStatus: string;
}

export interface UsePrivateZoneUnlockPaywallNavigationInput {
  loginStatus: LoginStatus;
  roomDispatch: Dispatch<PrivateZoneEvent>;
  unlockPaywallRequest: PrivateZoneUnlockPaywallRequest | null;
  isVip: boolean;
}

export function isPrivateZoneAuthRequired(loginStatus: LoginStatus): boolean {
  return loginStatus === "guest" || loginStatus === "notLoggedIn";
}

export function usePrivateZoneBootstrapFlow({
  authDispatch,
  hasInitialized,
  isAuthLoading,
  loginStatus,
  roomDispatch,
  roomStatus,
}: UsePrivateZoneBootstrapFlowInput): void {
  const previousLoginStatusRef = useRef(loginStatus);

  useGuestLoginBootstrap({
    dispatch: authDispatch,
    hasInitialized,
    isLoading: isAuthLoading,
    loginStatus,
  });

  useEffect(() => {
    if (!hasInitialized || isAuthLoading) return;
    if (loginStatus === "notLoggedIn") return;

    const previousLoginStatus = previousLoginStatusRef.current;
    previousLoginStatusRef.current = loginStatus;

    if (roomStatus === "idle") {
      roomDispatch({ type: "PrivateZoneInit" });
      return;
    }

    if (previousLoginStatus !== loginStatus && roomStatus !== "loading") {
      roomDispatch({ type: "PrivateZoneRefresh" });
    }
  }, [
    hasInitialized,
    isAuthLoading,
    loginStatus,
    roomDispatch,
    roomStatus,
  ]);
}

export function usePrivateZoneUnlockPaywallNavigation({
  loginStatus,
  roomDispatch,
  unlockPaywallRequest,
  isVip,
}: UsePrivateZoneUnlockPaywallNavigationInput): void {
  const navigator = useAppNavigator();
  const character = useActiveCharacter();
  const characterRoutes = useActiveCharacterRoutes();

  useEffect(() => {
    if (!unlockPaywallRequest) return;

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

export function usePrivateZoneUnlockSuccessRefresh(
  unlockSuccessNonce: number,
): void {
  const userDispatch = useUserDispatch();
  const lastUnlockSuccessNonceRef = useRef(0);

  useEffect(() => {
    if (unlockSuccessNonce <= lastUnlockSuccessNonceRef.current) return;
    lastUnlockSuccessNonceRef.current = unlockSuccessNonce;
    userDispatch({ type: "UserFetch" });
  }, [unlockSuccessNonce, userDispatch]);
}
