import { useEffect, useState } from "react";
import { Link, useNavigate, useSearchParams } from "react-router-dom";
import { PageHeader } from "../components/layout/PageHeader";
import { Button, Card } from "../components/ui";
import { useData, useRepos } from "../data/DataContext";
import type { BillingCheckoutStatus } from "../data/repos";
import { useI18n } from "../i18n/I18nContext";
import {
  billingErrorMessage,
  isSafeBillingUrl,
  pollCheckout,
  startBillingRedirect,
  type CheckoutPollResult,
} from "../lib/billingCheckout";
import { getPlanRights, planCtaLabel } from "../lib/planRights";
import { PLANS, type PlanId } from "../lib/usageMeter";

const PENDING_CHECKOUT_KEY = "harbor.billing.pending-checkout";

function isPlanId(value: string | null): value is PlanId {
  return value === "free" || value === "starter" || value === "pro";
}

function checkoutIdFromReturn(value: string | null): string {
  if (value && !/[{}<>]/.test(value) && value !== "checkout_id") return value;
  return sessionStorage.getItem(PENDING_CHECKOUT_KEY) ?? "";
}

export function PlanCheckoutPage() {
  const repos = useRepos();
  const { refresh } = useData();
  const { t, formatPlanPrice } = useI18n();
  const navigate = useNavigate();
  const [params] = useSearchParams();
  const result = params.get("result");
  const planParam = params.get("plan");
  const planId = isPlanId(planParam) ? planParam : null;
  const plan = planId ? PLANS[planId] : null;
  const rights = planId ? getPlanRights(planId, t, formatPlanPrice) : null;

  const [currentId, setCurrentId] = useState<PlanId | null>(null);
  const [loadingError, setLoadingError] = useState("");
  const [busy, setBusy] = useState(false);
  const [redirecting, setRedirecting] = useState(false);
  const [error, setError] = useState("");
  const [pollResult, setPollResult] = useState<CheckoutPollResult | null>(null);
  const [lastCheckout, setLastCheckout] = useState<BillingCheckoutStatus | null>(null);
  const [pollAttempt, setPollAttempt] = useState(0);

  const checkoutId = result === "success" ? checkoutIdFromReturn(params.get("checkout_id")) : "";

  useEffect(() => {
    if (result) return;
    void repos.usage
      .getBillingSubscription()
      .then((subscription) => {
        setCurrentId(subscription.plan_id);
        setLoadingError("");
      })
      .catch((e: unknown) => setLoadingError(billingErrorMessage(e, t, "plans.loadFail")));
  }, [repos.usage, result, t]);

  useEffect(() => {
    if (result !== "success" || !checkoutId) return;
    let stopped = false;
    setBusy(true);
    setError("");
    setPollResult(null);
    void pollCheckout(() => repos.usage.getCheckoutSession(checkoutId), {
      stopped: () => stopped,
    })
      .then((outcome) => {
        if (!outcome || stopped) return;
        setLastCheckout(outcome.checkout);
        setPollResult(outcome);
        if (outcome.outcome === "fulfilled") {
          sessionStorage.removeItem(PENDING_CHECKOUT_KEY);
          refresh();
          navigate("/app/usage", {
            replace: true,
            state: { purchaseOk: outcome.checkout.plan_id },
          });
        }
      })
      .catch((e: unknown) => {
        if (!stopped) setError(billingErrorMessage(e, t, "checkout.pollFail"));
      })
      .finally(() => {
        if (!stopped) setBusy(false);
      });
    return () => {
      stopped = true;
    };
  }, [checkoutId, navigate, pollAttempt, refresh, repos.usage, result, t]);

  async function startCheckout() {
    if (!planId || !currentId || (planId === "free" && currentId === "free")) return;
    setBusy(true);
    setRedirecting(false);
    setError("");
    try {
      if (planId === "free" || planId === currentId) {
        const portal = await repos.usage.createBillingPortalSession();
        if (!isSafeBillingUrl(portal.url)) {
          setError(t("checkout.invalidUrl"));
          setBusy(false);
          return;
        }
        beginRedirect(portal.url);
        return;
      }
      const checkout = await repos.usage.createCheckoutSession(planId, crypto.randomUUID());
      if (!checkout.id || !isSafeBillingUrl(checkout.url)) {
        setError(t("checkout.invalidUrl"));
        setBusy(false);
        return;
      }
      sessionStorage.setItem(PENDING_CHECKOUT_KEY, checkout.id);
      beginRedirect(checkout.url);
    } catch (e) {
      setError(billingErrorMessage(e, t, "checkout.fail"));
      setBusy(false);
    }
  }

  function beginRedirect(url: string) {
    setRedirecting(true);
    startBillingRedirect(
      () => window.location.assign(url),
      () => {
        setRedirecting(false);
        setBusy(false);
        setError(t("checkout.redirectFailed"));
      },
    );
  }

  function retryPoll() {
    setPollAttempt((attempt) => attempt + 1);
  }

  if (result === "cancel") {
    return (
      <>
        <PageHeader title={t("checkout.title")} />
        <Card>
          <h2>{t("checkout.canceledTitle")}</h2>
          <p className="text-muted">{t("checkout.canceledBody")}</p>
          <Link to="/app/usage/plans" className="hb-btn hb-btn--primary">
            {t("checkout.viewPlans")}
          </Link>
        </Card>
      </>
    );
  }

  if (result === "success") {
    const status = lastCheckout
      ? `${lastCheckout.checkout_status} / ${lastCheckout.payment_status} / ${lastCheckout.fulfillment_status}`
      : "";
    return (
      <>
        <PageHeader title={t("checkout.title")} />
        <Card>
          {!checkoutId ? <p className="hb-form-error" role="alert">{t("checkout.missingId")}</p> : null}
          {busy ? <p role="status">{t("checkout.verifying")}</p> : null}
          {error ? <p className="hb-form-error" role="alert">{error}</p> : null}
          {pollResult?.outcome === "failed" ? (
            <p className="hb-form-error" role="alert">{t("checkout.terminalFail", { status })}</p>
          ) : null}
          {pollResult?.outcome === "timeout" ? (
            <p className="hb-banner-warn" role="status">{t("checkout.timeout")}</p>
          ) : null}
          {(error || pollResult) && checkoutId ? (
            <Button type="button" onClick={retryPoll}>{t("checkout.retry")}</Button>
          ) : null}
          <div className="hb-checkout__links">
            <Link to="/app/usage">{t("plans.usageLink")}</Link>
          </div>
        </Card>
      </>
    );
  }

  if (!plan || !planId || !rights) {
    return (
      <>
        <PageHeader title={t("checkout.title")} />
        <Card>
          <p className="text-muted">{t("checkout.pickFirst")}</p>
          <Link to="/app/usage/plans" className="hb-btn hb-btn--primary">{t("checkout.viewPlans")}</Link>
        </Card>
      </>
    );
  }

  if (!currentId) {
    return (
      <>
        <PageHeader title={t("checkout.title")} />
        {loadingError ? <p className="hb-form-error" role="alert">{loadingError}</p> : <p>{t("common.loading")}</p>}
      </>
    );
  }

  const already = currentId === planId;
  const currentFree = planId === "free" && currentId === "free";
  const portalAction = (planId === "free" && currentId !== "free") || (already && currentId !== "free");
  const actionLabel = portalAction
    ? t("plans.manage")
    : t("checkout.payAndAction", {
        action: planCtaLabel(currentId, planId, t),
        price: formatPlanPrice(plan.price_twd),
      });

  return (
    <>
      <PageHeader title={t("checkout.title")} />
      {error ? <p className="hb-form-error" role="alert">{error}</p> : null}
      {redirecting ? <p role="status">{t("checkout.redirecting")}</p> : null}
      <div className="hb-checkout">
        <div className="hb-checkout__main hb-stack">
          <Card>
            <div className="hb-checkout__order">
              <div>
                <p className="hb-usage-checkout__label">{t("checkout.subscribe")}</p>
                <p className="hb-usage-checkout__name">{plan.name}</p>
                <p className="text-muted">{rights.headline}</p>
              </div>
              <div className="hb-checkout__price-block">
                <p className="hb-checkout__big-price">{formatPlanPrice(plan.price_twd)}<span className="hb-checkout__period">{t("checkout.perMonth")}</span></p>
                <p className="text-muted">{t("checkout.monthlyCredits", { n: plan.monthly_credits })}</p>
              </div>
            </div>
            <div className="hb-usage-checkout__rights">
              <section className="hb-usage-checkout__block"><h3 className="hb-usage-checkout__h">{t("checkout.youGet")}</h3><ul className="hb-usage-checkout__list">{rights.rights.map((line) => <li key={line}>{line}</li>)}</ul></section>
              <section className="hb-usage-checkout__block"><h3 className="hb-usage-checkout__h">{t("checkout.quota")}</h3><ul className="hb-usage-checkout__list">{rights.quota.map((line) => <li key={line}>{line}</li>)}</ul></section>
              <section className="hb-usage-checkout__block"><h3 className="hb-usage-checkout__h">{t("checkout.notes")}</h3><ul className="hb-usage-checkout__list hb-usage-checkout__list--notes">{rights.notes.map((line) => <li key={line}>{line}</li>)}</ul></section>
            </div>
          </Card>
        </div>
        <aside className="hb-checkout__aside">
          <Card>
            <p className="hb-usage-checkout__label">{t("checkout.amountDue")}</p>
            <p className="hb-checkout__big-price">{formatPlanPrice(plan.price_twd)}<span className="hb-checkout__period">{t("checkout.perMonth")}</span></p>
            {portalAction ? <p className="hb-banner-warn">{t("checkout.manageInstead")}</p> : null}
            <Button type="button" disabled={busy || currentFree} onClick={() => void startCheckout()}>
              {busy ? t("checkout.processing") : actionLabel}
            </Button>
            <div className="hb-checkout__links"><Link to="/app/usage/plans">{t("checkout.pickOther")}</Link><Link to="/app/usage">{t("checkout.cancel")}</Link></div>
          </Card>
        </aside>
      </div>
    </>
  );
}
