"use client";

import { useEffect, useRef } from "react";

import { behaviorAnalytics } from "@/lib/analytics";
import { useAppNavigator } from "@/router/use-app-navigator";
import type { ChatUpgradeReason } from "@/stores/chat/chat-state";
import type { PaymentGuidance } from "@/data/schemas/chat";
import { recordChatActionEventById } from "@/lib/chat/chat_action_events";
import { useActiveCharacter } from "@/providers/character-provider";
import { useUserSelector } from "@/stores/user/user-context";

import {
  getInsufficientCreditsMessageLimitView,
  getInsufficientCreditsSubscriptionType,
  shouldShowMessageLimitBanner,
  type InsufficientCreditsMessageLimitView,
} from "../chat-screen.helpers";

export interface UseChatMessageLimitBannerInput {
  upgradePromptVisible: boolean;
  upgradeReason: ChatUpgradeReason | null;
  paymentGuidance: PaymentGuidance | null;
}

export interface ChatMessageLimitBannerView {
  title: string;
  description: string;
  ctaLabel: string | null;
  guidance: PaymentGuidance | null;
  visible: boolean;
  unlock: () => void;
}

export function useChatMessageLimitBanner({
  upgradePromptVisible,
  upgradeReason,
  paymentGuidance,
}: UseChatMessageLimitBannerInput): ChatMessageLimitBannerView {
  const navigator = useAppNavigator();
  const character = useActiveCharacter();
  const isVip = useUserSelector((state) => state.context.isVip);
  const fallbackView = getInsufficientCreditsMessageLimitView();
  const guidance =
    paymentGuidance?.characterId === character.id ? paymentGuidance : null;
  const view: InsufficientCreditsMessageLimitView = {
    title: guidance?.title ?? fallbackView.title,
    description: guidance?.copy ?? fallbackView.description,
    ctaLabel: guidance?.ctaLabel ?? fallbackView.ctaLabel,
  };
  const visible = shouldShowMessageLimitBanner({
    upgradePromptVisible,
    upgradeReason,
  });
  const trackedVisibleRef = useRef(false);

  useEffect(() => {
    if (!visible) {
      trackedVisibleRef.current = false;
      return;
    }
    if (trackedVisibleRef.current) return;
    trackedVisibleRef.current = true;
    behaviorAnalytics.paywallShown(
      {
        entryPoint: "chat_input",
        triggerReason: "insufficient_credits",
      },
      { isVip },
    );
    if (guidance) {
      void recordChatActionEventById(
        guidance.guidanceId,
        character.id,
        "viewed",
      ).catch(() => undefined);
    }
  }, [character.id, guidance, isVip, visible]);

  function unlock(): void {
    if (guidance?.mode !== "guide" && guidance !== null) return;
    if (guidance) {
      void recordChatActionEventById(
        guidance.guidanceId,
        character.id,
        "opened",
      ).catch(() => undefined);
    }
    navigator.openSubscription({
      type:
        isVip || (guidance && !guidance.purchaseOptions.includes("vip"))
          ? "topup"
          : getInsufficientCreditsSubscriptionType(isVip),
      returnTo: "chat",
      ...(guidance ? { chatActionId: guidance.guidanceId } : {}),
      analytics: {
        entryPoint: "chat_input",
        triggerReason: "insufficient_credits",
      },
    });
  }

  return {
    ...view,
    ctaLabel:
      guidance && guidance.mode !== "guide" ? null : view.ctaLabel,
    guidance,
    visible,
    unlock,
  };
}
