"use client";

import { useEffect, useRef, useState } from "react";
import { useRouter } from "next/navigation";

import {
  persistExternalEntryPayload,
  resolveCheckoutIntentDestination,
  resolveExternalEntryDestination,
  resolveExternalEntryPromotionType,
  resolveExternalEntryTarget,
  shouldBindExternalFacebookIdentity,
} from "@/lib/navigation/external_entry";
import {
  clearPendingChatPromotion,
  savePendingChatPromotion,
} from "@/lib/navigation/chat_unlock_session";
import { ROUTES } from "@/router/routes";
import {
  DEFAULT_CHARACTER_ID,
  getCharacterBySlug,
} from "@/data/constants/character";
import { Logger } from "@/utils/logger";
import { useAuthDispatch, useAuthState } from "@/stores/auth/auth-context";
import { consumeTopUpHandoff } from "@/lib/auth/top_up_handoff";
import { consumeCheckoutHandoff } from "@/lib/auth/checkout_handoff";
import { Result } from "@/utils/result";
import {
  isFavoriteEntryRequest,
  persistFavoriteEntryIntent,
} from "@/lib/navigation/favorite_entry";

const log = new Logger("ExternalEntryPersist");

interface ExternalEntryPersistProps {
  deviceId: string | null;
  asid: string | null;
  psid: string | null;
  avatarUrl: string | null;
  target: string | null;
  character: string | null;
  mode: string | null;
  promotionType: string | null;
  favorite: string | null;
  handoffToken: string | null;
}

export default function ExternalEntryPersist({
  deviceId,
  asid,
  psid,
  avatarUrl,
  target,
  character,
  mode,
  promotionType,
  favorite,
  handoffToken,
}: ExternalEntryPersistProps) {
  const router = useRouter();
  const authState = useAuthState();
  const authDispatch = useAuthDispatch();
  const [hasPersisted, setHasPersisted] = useState(false);
  const [handoffError, setHandoffError] = useState<string | null>(null);
  const [handoffCompleted, setHandoffCompleted] = useState(false);
  const [checkoutDestination, setCheckoutDestination] = useState<string | null>(
    null,
  );
  const hasNavigatedRef = useRef(false);
  const handoffStartedRef = useRef(false);
  const targetRoute = resolveExternalEntryTarget({ target });
  const destination = resolveExternalEntryDestination({ target, character });
  const characterId =
    getCharacterBySlug(character)?.id ?? DEFAULT_CHARACTER_ID;
  const resolvedPromotionType = resolveExternalEntryPromotionType({
    mode,
    promotionType,
  });
  const normalizedTarget = target?.trim().toLowerCase() ?? "";
  const isTopUpHandoff = normalizedTarget === "topup";
  const isCheckoutHandoff = normalizedTarget === "checkout";
  const isLoginHandoff = isTopUpHandoff || isCheckoutHandoff;
  const displayedHandoffError =
    handoffError ??
    (isLoginHandoff && !hasValue(handoffToken)
      ? "This checkout link is invalid. Please return and request a new link."
      : null);

  useEffect(() => {
    let cancelled = false;

    void (async () => {
      const results = await Promise.allSettled([
        persistExternalEntryPayload({
          deviceId,
          asid,
          psid,
          avatarUrl,
        }),
        targetRoute === ROUTES.chat && resolvedPromotionType
          ? savePendingChatPromotion(resolvedPromotionType, characterId)
          : clearPendingChatPromotion(),
      ]);
      if (isFavoriteEntryRequest(favorite)) {
        persistFavoriteEntryIntent();
      }
      for (const result of results) {
        if (result.status === "rejected") {
          log.warn(
            "[ExternalEntryPersist] failed to persist payload",
            result.reason,
          );
        }
      }
      if (!cancelled) setHasPersisted(true);
    })();

    return () => {
      cancelled = true;
    };
  }, [
    avatarUrl,
    asid,
    character,
    characterId,
    destination,
    deviceId,
    favorite,
    mode,
    promotionType,
    psid,
    resolvedPromotionType,
    targetRoute,
  ]);

  useEffect(() => {
    if (hasNavigatedRef.current || !hasPersisted) return;

    if (isLoginHandoff) {
      if (!authState.hasInitialized || authState.isLoading) return;
      if (handoffCompleted) {
        if (
          authState.loginStatus === "notLoggedIn" ||
          authState.loginStatus === "guest"
        ) {
          return;
        }
        hasNavigatedRef.current = true;
        router.replace(checkoutDestination ?? destination);
        return;
      }
      if (handoffStartedRef.current) return;
      if (!hasValue(handoffToken)) return;
      handoffStartedRef.current = true;
      void (async () => {
        if (isCheckoutHandoff) {
          const result = await consumeCheckoutHandoff(handoffToken);
          if (Result.isErr(result)) {
            log.warn(
              "[ExternalEntryPersist] checkout handoff failed",
              result.error,
            );
            window.history.replaceState(
              window.history.state,
              "",
              "/external-entry?target=checkout",
            );
            setHandoffError(
              "This checkout link is invalid, expired, or already used. Please return and request a new link.",
            );
            return;
          }
          window.history.replaceState(
            window.history.state,
            "",
            "/external-entry?target=checkout",
          );
          setCheckoutDestination(
            resolveCheckoutIntentDestination(result.data, character),
          );
        } else {
          const result = await consumeTopUpHandoff(handoffToken);
          if (Result.isErr(result)) {
            log.warn(
              "[ExternalEntryPersist] top-up handoff failed",
              result.error,
            );
            window.history.replaceState(
              window.history.state,
              "",
              "/external-entry?target=topup",
            );
            setHandoffError(
              "This top-up link is invalid or has expired. Please request a new link in Messenger.",
            );
            return;
          }
          window.history.replaceState(
            window.history.state,
            "",
            "/external-entry?target=topup",
          );
        }
        setHandoffCompleted(true);
        authDispatch({ type: "AuthInit" });
      })();
      return;
    }

    if (!authState.hasInitialized || authState.isLoading) return;
    hasNavigatedRef.current = true;

    if (
      shouldBindExternalFacebookIdentity({
        hasInitialized: authState.hasInitialized,
        isLoading: authState.isLoading,
        loginStatus: authState.loginStatus,
        asid,
        psid,
      })
    ) {
      authDispatch({
        type: "AuthExternalFacebookIdentityBindRequested",
        asid: asid ?? undefined,
        psid: psid ?? undefined,
      });
    }
    router.replace(destination);
  }, [
    asid,
    authDispatch,
    authState.hasInitialized,
    authState.isLoading,
    authState.loginStatus,
    character,
    destination,
    checkoutDestination,
    hasPersisted,
    handoffCompleted,
    handoffToken,
    isCheckoutHandoff,
    isLoginHandoff,
    isTopUpHandoff,
    psid,
    router,
  ]);

  return (
    <div
      className="flex flex-1 items-center justify-center"
      style={{ minHeight: "100dvh" }}
    >
      {displayedHandoffError ? (
        <div className="mx-6 max-w-sm text-center">
          <p className="text-sm text-[var(--color-text-secondary)]">
            {displayedHandoffError}
          </p>
          <button
            className="mt-5 rounded-full bg-[var(--color-accent)] px-5 py-2.5 text-sm font-semibold text-white"
            type="button"
            onClick={() => router.replace(ROUTES.root)}
          >
            Back to Cozsweet
          </button>
        </div>
      ) : (
        <div
          aria-label="Redirecting"
          className="size-10 animate-spin rounded-full border-4 border-t-transparent"
          style={{ borderColor: "var(--color-accent)" }}
        />
      )}
    </div>
  );
}

function hasValue(value: string | null): value is string {
  return typeof value === "string" && value.trim().length > 0;
}
