"use client";

import Link from "next/link";
import { usePathname, useRouter } from "next/navigation";
import { useEffect, useMemo, useState, useTransition } from "react";
import { emitBillingRefreshSignal } from "@/components/billing-refresh-listener";
import { QRCodeSVG } from "@/components/vendor/qrcode-react";

type ApiResponse = {
  ok: boolean;
  data?: {
    message?: string;
    trade_no?: string;
    url?: string;
    code_url?: string;
    status?: string;
  };
  error?: {
    message?: string;
  };
};

export function BillingPurchaseActions({
  kind,
  itemId,
  labels,
}: {
  kind: "subscription" | "points";
  itemId: number;
  labels: {
    alipay: string;
    wxpay: string;
    creating: string;
    tradeNo: string;
    openLink: string;
    codeUrl: string;
    invalid: string;
    pending: string;
    success: string;
    failed: string;
    paymentStatus: string;
    qrTitle: string;
    openConsole: string;
    openBilling: string;
  };
}) {
  const pathname = usePathname();
  const router = useRouter();
  const [result, setResult] = useState<(ApiResponse["data"] & { provider?: string; kind?: string }) | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [status, setStatus] = useState<string>("");
  const [pendingProvider, setPendingProvider] = useState<string | null>(null);
  const [isPending, startTransition] = useTransition();
  const locale = useMemo(() => pathname.split("/")[1] || "zh", [pathname]);

  function checkout(provider: "alipay" | "wxpay") {
    startTransition(async () => {
      setPendingProvider(provider);
      setError(null);
      setResult(null);
      setStatus("");
      try {
        const response = await fetch("/api/billing/checkout", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            kind,
            provider,
            plan_id: kind === "subscription" ? itemId : undefined,
            package_id: kind === "points" ? itemId : undefined,
            return_url: typeof window !== "undefined" ? `${window.location.origin}${pathname}` : "",
          }),
        });
        const payload = (await response.json()) as ApiResponse;
        if (!response.ok || !payload.ok) {
          setError(payload.error?.message ?? labels.invalid);
          return;
        }
        setResult({ ...(payload.data ?? null), provider, kind });
        setStatus(labels.pending);
      } catch (requestError) {
        setError(requestError instanceof Error ? requestError.message : labels.invalid);
      } finally {
        setPendingProvider(null);
      }
    });
  }

  useEffect(() => {
    if (!result?.trade_no || !result.provider || !result.kind) {
      return;
    }
    const currentResult = result;
    const currentKind = currentResult.kind ?? "";
    const currentProvider = currentResult.provider ?? "";
    if (!currentKind || !currentProvider) {
      return;
    }
    let cancelled = false;
    let attempts = 0;

    async function poll() {
      attempts += 1;
      try {
        const query = new URLSearchParams();
        query.set("kind", currentKind);
        query.set("provider", currentProvider);
        query.set("trade_no", currentResult.trade_no ?? "");
        const response = await fetch(`/api/billing/checkout?${query.toString()}`);
        const payload = (await response.json()) as ApiResponse;
        if (!response.ok || !payload.ok) {
          if (!cancelled) {
            setError(payload.error?.message ?? labels.invalid);
          }
          return;
        }
        const nextStatus = payload.data?.status ?? "";
        if (!cancelled && nextStatus) {
          setStatus(nextStatus);
        }
        if (cancelled) {
          return;
        }
        if (nextStatus === "SUCCESS" || nextStatus === "TRADE_SUCCESS") {
          setStatus(labels.success);
          emitBillingRefreshSignal();
          window.setTimeout(() => {
            router.push(
              `/${locale}/billing/success?kind=${encodeURIComponent(currentKind)}&provider=${encodeURIComponent(currentProvider)}&trade_no=${encodeURIComponent(currentResult.trade_no ?? "")}`,
            );
          }, 1200);
          return;
        }
        if (nextStatus === "FAILED" || nextStatus === "CLOSED" || nextStatus === "TRADE_CLOSED") {
          setStatus(labels.failed);
          return;
        }
        if (attempts < 20) {
          window.setTimeout(poll, 3000);
        }
      } catch (requestError) {
        if (!cancelled) {
          setError(requestError instanceof Error ? requestError.message : labels.invalid);
        }
      }
    }

    const timer = window.setTimeout(poll, 2000);
    return () => {
      cancelled = true;
      window.clearTimeout(timer);
    };
  }, [labels.failed, labels.invalid, labels.success, locale, result, router]);

  return (
    <div className="billing-purchase-stack">
      <div className="billing-purchase-actions">
        <button className="button button-dark" disabled={isPending} onClick={() => checkout("alipay")} type="button">
          {isPending && pendingProvider === "alipay" ? labels.creating : labels.alipay}
        </button>
        <button className="button button-light" disabled={isPending} onClick={() => checkout("wxpay")} type="button">
          {isPending && pendingProvider === "wxpay" ? labels.creating : labels.wxpay}
        </button>
      </div>
      {error ? <div className="status-banner status-banner-error">{error}</div> : null}
      {result ? (
        <div className="status-banner billing-purchase-result">
          {result.trade_no ? (
            <span>
              {labels.tradeNo}: {result.trade_no}
            </span>
          ) : null}
          {status ? (
            <span>
              {labels.paymentStatus}: {status}
            </span>
          ) : null}
          {result.url ? (
            <a href={result.url} rel="noreferrer" target="_blank">
              {labels.openLink}
            </a>
          ) : null}
          {result.code_url ? <span>{labels.codeUrl}: {result.code_url}</span> : null}
          {result.code_url ? (
            <div className="billing-qr-block">
              <strong>{labels.qrTitle}</strong>
              <div className="billing-qr-image">
                <QRCodeSVG level="M" size={160} value={result.code_url} />
              </div>
            </div>
          ) : null}
          {status === labels.success ? (
            <div className="billing-success-links">
              <Link className="button button-light button-small" href={`/${locale}/console`}>
                {labels.openConsole}
              </Link>
              <Link className="button button-light button-small" href={`/${locale}/billing`}>
                {labels.openBilling}
              </Link>
            </div>
          ) : null}
        </div>
      ) : null}
    </div>
  );
}
