"use client";

import { useEffect, useMemo, useRef } from "react";
import Image from "next/image";
import { ArrowLeft, Heart, Sparkles } from "lucide-react";

import { CharacterAvatar } from "@/app/_components";
import { MobileShell } from "@/app/_components/core";
import { usePaymentOrderLifecycle } from "@/app/_hooks/use-payment-order-lifecycle";
import { usePaymentPlanAnalytics } from "@/app/_hooks/use-payment-plan-analytics";
import type { PayChannel } from "@/data/dto/payment";
import {
  behaviorAnalytics,
  type PaymentAnalyticsContext,
} from "@/lib/analytics";
import {
  buildTipCoffeePath,
  DEFAULT_TIP_COFFEE_TYPE,
  getTipCoffeeOption,
  type TipCoffeeType,
} from "@/lib/tip/tip_coffee";
import { useAppNavigator } from "@/router/use-app-navigator";
import { useAuthState } from "@/stores/auth/auth-context";
import {
  usePaymentDispatch,
  usePaymentState,
} from "@/stores/payment/payment-context";

import { TipCheckoutButton } from "./tip-checkout-button";
import {
  findTipCoffeePlan,
  formatTipPrice,
  isRealLoginStatus,
} from "./tip-screen.helpers";
import styles from "./tip-screen.module.css";

const TIP_ANALYTICS_CONTEXT: PaymentAnalyticsContext = {
  entryPoint: "tip_page",
  triggerReason: "ad_landing",
};

export interface TipScreenProps {
  coffeeType?: TipCoffeeType;
  shouldResumePendingOrder?: boolean;
  initialPayChannel?: PayChannel | null;
}

export function TipScreen({
  coffeeType = DEFAULT_TIP_COFFEE_TYPE,
  shouldResumePendingOrder = false,
  initialPayChannel = null,
}: TipScreenProps) {
  const navigator = useAppNavigator();
  const authState = useAuthState();
  const payment = usePaymentState();
  const paymentDispatch = usePaymentDispatch();
  const initialPayChannelAppliedRef = useRef(false);
  const coffeeOption = getTipCoffeeOption(coffeeType);
  const returnPath = buildTipCoffeePath(coffeeType);
  const resolvedInitialPayChannel =
    initialPayChannel ?? navigator.getDefaultPayChannel();

  const coffeePlan = useMemo(
    () => findTipCoffeePlan(payment.plans, coffeeType),
    [coffeeType, payment.plans],
  );
  const priceLabel = formatTipPrice(coffeePlan, coffeeType);
  usePaymentPlanAnalytics(coffeePlan ? [coffeePlan] : [], TIP_ANALYTICS_CONTEXT);
  const isPaymentBusy =
    payment.isCreatingOrder || payment.isPollingOrder || payment.isPaid;
  const canCreateOrder =
    coffeePlan !== null &&
    payment.selectedPlanId === coffeePlan.planId &&
    payment.agreed &&
    !payment.autoRenew &&
    !payment.isLoadingPlans &&
    !isPaymentBusy;
  const showMissingPlan =
    payment.status === "ready" && !payment.isLoadingPlans && coffeePlan === null;
  const isAuthLoading = !authState.hasInitialized || authState.isLoading;

  usePaymentOrderLifecycle({
    payment,
    paymentDispatch,
    paymentType: "tip",
    shouldResumePendingOrder,
  });

  useEffect(() => {
    if (payment.status === "idle") {
      initialPayChannelAppliedRef.current = true;
      paymentDispatch({
        type: "PaymentInit",
        catalog: "tip",
        payChannel: resolvedInitialPayChannel,
      });
      return;
    }

    if (!initialPayChannelAppliedRef.current && payment.status === "ready") {
      initialPayChannelAppliedRef.current = true;
      if (payment.payChannel === resolvedInitialPayChannel) return;
      paymentDispatch({
        type: "PaymentPayChannelChanged",
        payChannel: resolvedInitialPayChannel,
      });
    }
  }, [
    payment.payChannel,
    payment.status,
    paymentDispatch,
    resolvedInitialPayChannel,
  ]);

  useEffect(() => {
    if (payment.isLoadingPlans || payment.isCreatingOrder || payment.isPollingOrder) {
      return;
    }
    if (!coffeePlan) return;

    if (payment.selectedPlanId !== coffeePlan.planId) {
      paymentDispatch({
        type: "PaymentPlanSelected",
        planId: coffeePlan.planId,
      });
      return;
    }

    if (payment.autoRenew) {
      paymentDispatch({ type: "PaymentAutoRenewChanged", autoRenew: false });
      return;
    }

    if (!payment.agreed) {
      paymentDispatch({ type: "PaymentAgreementChanged", agreed: true });
    }
  }, [
    coffeePlan,
    payment.agreed,
    payment.autoRenew,
    payment.isCreatingOrder,
    payment.isLoadingPlans,
    payment.isPollingOrder,
    payment.selectedPlanId,
    paymentDispatch,
  ]);

  const handleOrder = () => {
    if (isAuthLoading) return;
    if (coffeePlan) {
      behaviorAnalytics.planClick(coffeePlan, TIP_ANALYTICS_CONTEXT);
    }
    if (!isRealLoginStatus(authState.loginStatus)) {
      navigator.openAuth(returnPath);
      return;
    }
    if (!canCreateOrder) return;

    paymentDispatch({ type: "PaymentCreateOrderSubmitted" });
  };

  const handleBack = () => {
    navigator.back();
  };

  const handleResetPaidState = () => {
    paymentDispatch({ type: "PaymentReset" });
  };

  return (
    <MobileShell background="#fff5ed">
      <main className={styles.shell}>
        <div className={styles.bgImage} aria-hidden="true" />
        <div className={styles.bgGlowOne} aria-hidden="true" />
        <div className={styles.bgGlowTwo} aria-hidden="true" />

        <header className={styles.header}>
          <button
            type="button"
            data-analytics-key="tip.back"
            data-analytics-label="Go back from tip"
            className={styles.backButton}
            aria-label="Go back"
            onClick={handleBack}
          >
            <ArrowLeft size={19} aria-hidden="true" />
          </button>
          <span className={styles.headerPill}>Tip Elio</span>
        </header>

        <section className={styles.hero} aria-labelledby="tip-title">
          <div className={styles.avatarRing}>
            <CharacterAvatar
              alt="Elio Silvestri"
              size="100%"
              imageSize={88}
              priority
            />
          </div>
          <p className={styles.eyebrow}>A little sweetness for today</p>
          <h1 id="tip-title" className={styles.title}>
            Buy Elio a coffee
          </h1>
          <p className={styles.subtitle}>
            Send a warm coffee tip and keep the private moments glowing.
          </p>
        </section>

        <section className={styles.productCard} aria-label="Coffee tip product">
          <div className={styles.coffeeStage} aria-hidden="true">
            <Image
              src="/images/tip/coffee.jpg"
              alt=""
              width={736}
              height={736}
              sizes="(max-width: 380px) 220px, 211px"
              className={styles.coffeeImage}
            />
          </div>

          <div className={styles.productCopy}>
            <span className={styles.productBadge}>
              <Sparkles size={14} aria-hidden="true" />
              Coffee Gift
            </span>
            <h2 className={styles.productName}>
              {coffeePlan?.planName || coffeeOption.fallbackName}
            </h2>
            <p className={styles.productPrice}>{priceLabel}</p>
          </div>
        </section>

        {showMissingPlan ? (
          <p className={styles.statusMessage} role="alert">
            Coffee tip is not available yet. Please try again later.
          </p>
        ) : null}

        {payment.isPaid ? (
          <section className={styles.successCard} aria-live="polite">
            <Heart size={18} aria-hidden="true" />
            <div>
              <p className={styles.successTitle}>Coffee sent</p>
              <p className={styles.successText}>
                Thank you. Your payment has been confirmed.
              </p>
            </div>
            <button
              type="button"
              className={styles.successButton}
              onClick={handleResetPaidState}
            >
              Send again
            </button>
          </section>
        ) : null}

        <div className={styles.checkoutSlot}>
          <TipCheckoutButton
            coffeeType={coffeeType}
            disabled={
              showMissingPlan ||
              (!canCreateOrder && isRealLoginStatus(authState.loginStatus))
            }
            isAuthLoading={isAuthLoading}
            onOrder={handleOrder}
            returnPath={returnPath}
          />
        </div>
      </main>
    </MobileShell>
  );
}
