import { useMemo, useState } from "react";
import { createFileRoute } from "@tanstack/react-router";
import { Clock, Copy, Check, Loader2, ShieldCheck, Zap, AlertCircle } from "lucide-react";
import logoAsset from "@/assets/carding-vai-logo.png.asset.json";
import { PackageGrid } from "@/components/topup/PackageGrid";
import { PaymentPanel } from "@/components/topup/PaymentPanel";
import { SupportSection } from "@/components/topup/SupportSection";
import { SupportWidget } from "@/components/topup/SupportWidget";
import { AccountButton } from "@/components/account/AccountPanel";
import { ButterflyBonus } from "@/components/account/ButterflyBonus";
import { AccountProvider, useAccount } from "@/hooks/useAccount";
import { findPackage, formatBDT, formatDiamonds } from "@/data/packages";
import { paymentMethods, type PaymentMethodId } from "@/data/payment-methods";
import { orderService, validation, type Order } from "@/lib/orders";
import { cn } from "@/lib/utils";
import { I18nProvider, useI18n, type Lang } from "@/i18n";

export const Route = createFileRoute("/")({
  head: () => ({
    meta: [
      { title: "CARDING VAI TOP UP — Free Fire Diamond Top Up by UID" },
      {
        name: "description",
        content:
          "Order Free Fire diamonds with your UID. Pay with bKash or Nagad, submit your transaction ID, and track your pending order.",
      },
      { property: "og:title", content: "CARDING VAI TOP UP — Free Fire Diamond Top Up" },
      {
        property: "og:description",
        content:
          "50 diamond packages. Pay via bKash or Nagad and submit your UID in one step.",
      },
      { property: "og:type", content: "website" },
      { name: "twitter:card", content: "summary_large_image" },
    ],
  }),
  component: RouteComponent,
});

function RouteComponent() {
  return (
    <I18nProvider>
      <AccountProvider>
        <Index />
      </AccountProvider>
    </I18nProvider>
  );
}

type FieldErrors = {
  pack?: string | undefined;
  trx?: string | undefined;
  uid?: string | undefined;
};

function StepHeading({ step, title, hint }: { step: number; title: string; hint?: string }) {
  return (
    <div className="mb-4 flex min-w-0 items-center gap-3">
      <span className="grid size-8 shrink-0 place-items-center rounded-xl bg-primary font-display text-sm font-bold text-primary-foreground">
        {step}
      </span>
      <div className="min-w-0">
        <h2 className="truncate text-lg font-bold">{title}</h2>
        {hint && <p className="text-xs text-muted-foreground">{hint}</p>}
      </div>
    </div>
  );
}

function LanguageSwitcher() {
  const { lang, setLang, t } = useI18n();
  const options: Array<{ id: Lang; label: string }> = [
    { id: "bn", label: "বাংলা" },
    { id: "en", label: "EN" },
  ];
  return (
    <div
      role="radiogroup"
      aria-label={t("lang.aria")}
      className="flex shrink-0 items-center gap-0.5 rounded-full border border-border/70 bg-secondary/50 p-0.5"
    >
      {options.map((o) => (
        <button
          key={o.id}
          type="button"
          role="radio"
          aria-checked={lang === o.id}
          onClick={() => setLang(o.id)}
          className={cn(
            "rounded-full px-2.5 py-1 text-[11px] font-semibold transition-colors focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none",
            lang === o.id
              ? "bg-primary text-primary-foreground"
              : "text-muted-foreground hover:text-foreground",
          )}
        >
          {o.label}
        </button>
      ))}
    </div>
  );
}

function Field({
  id,
  label,
  hint,
  error,
  ...props
}: React.InputHTMLAttributes<HTMLInputElement> & {
  id: string;
  label: string;
  hint?: string;
  error?: string | undefined;
}) {
  return (
    <div>
      <label htmlFor={id} className="mb-1.5 block text-sm font-medium">
        {label}
      </label>
      <input
        id={id}
        aria-invalid={Boolean(error)}
        aria-describedby={error ? `${id}-error` : hint ? `${id}-hint` : undefined}
        className={cn(
          "h-12 w-full rounded-xl border bg-input/40 px-3.5 text-base tabular-nums placeholder:text-muted-foreground/70",
          "focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none",
          error ? "border-destructive" : "border-border",
        )}
        {...props}
      />
      {error ? (
        <p id={`${id}-error`} className="mt-1.5 flex items-center gap-1.5 text-xs text-destructive">
          <AlertCircle className="size-3.5 shrink-0" aria-hidden />
          {error}
        </p>
      ) : hint ? (
        <p id={`${id}-hint`} className="mt-1.5 text-xs text-muted-foreground">
          {hint}
        </p>
      ) : null}
    </div>
  );
}

function Index() {
  const { t } = useI18n();
  const { recordOrder } = useAccount();
  const [packageId, setPackageId] = useState<number | null>(null);
  const [methodId, setMethodId] = useState<PaymentMethodId>("bkash");
  const [transactionId, setTransactionId] = useState("");
  const [uid, setUid] = useState("");
  const [errors, setErrors] = useState<FieldErrors>({});
  const [submitting, setSubmitting] = useState(false);
  const [order, setOrder] = useState<Order | null>(null);
  const [copiedOrderId, setCopiedOrderId] = useState(false);

  const selectedPackage = useMemo(() => findPackage(packageId), [packageId]);
  const method = paymentMethods.find((m) => m.id === methodId) ?? paymentMethods[0]!;
  const packageLabel = selectedPackage
    ? `${formatDiamonds(selectedPackage.diamonds)} ${t("packs.diamonds")}`
    : null;

  function validate(): FieldErrors {
    const next: FieldErrors = {};
    if (!selectedPackage) next.pack = t("err.pack");
    const trxError = validation.transactionId(transactionId);
    if (trxError) next.trx = t(trxError);
    const uidError = validation.uid(uid);
    if (uidError) next.uid = t(uidError);
    return next;
  }

  async function handleSubmit(event: React.FormEvent) {
    event.preventDefault();
    if (submitting) return;
    const next = validate();
    setErrors(next);
    if (Object.keys(next).length > 0 || !selectedPackage) return;

    setSubmitting(true);
    try {
      const created = await orderService.createOrder({
        packageId: selectedPackage.id,
        packageLabel: `${formatDiamonds(selectedPackage.diamonds)} Diamonds`,
        amount: selectedPackage.price,
        paymentMethod: method.id,
        payTo: method.number,
        transactionId: transactionId.trim(),
        freeFireUid: uid.trim(),
      });
      setOrder(created);
      void recordOrder({
        orderCode: created.orderId,
        packageId: selectedPackage.id,
        diamonds: selectedPackage.diamonds,
        price: selectedPackage.price,
        uid: uid.trim(),
        paymentMethod: method.id,
        transactionId: transactionId.trim(),
      });
      window.scrollTo({ top: 0, behavior: "smooth" });
    } finally {
      setSubmitting(false);
    }
  }

  function resetFlow() {
    setOrder(null);
    setPackageId(null);
    setTransactionId("");
    setUid("");
    setErrors({});
  }

  async function copyOrderId(value: string) {
    try {
      await navigator.clipboard.writeText(value);
      setCopiedOrderId(true);
      window.setTimeout(() => setCopiedOrderId(false), 1800);
    } catch {
      setCopiedOrderId(false);
    }
  }

  const orderPack = order
    ? (findPackage(order.packageId) ?? null)
    : null;

  return (
    <div className="min-h-screen pb-24">
      <header className="sticky top-0 z-20 border-b border-border/70 bg-background/80 backdrop-blur-lg">
        <div className="mx-auto grid max-w-3xl grid-cols-[minmax(0,1fr)_auto] items-center gap-2 px-4 py-3">
          <div className="flex min-w-0 items-center gap-3">
            <img
              src={logoAsset.url}
              alt="CARDING VAI logo"
              className="size-11 shrink-0 rounded-xl object-cover"
            />
            <div className="min-w-0">
              <p className="truncate font-display text-base font-bold">{t("brand.name")}</p>
              <p className="truncate text-[11px] text-muted-foreground">{t("brand.tag")}</p>
            </div>
          </div>
          <div className="flex shrink-0 items-center gap-2">
            <AccountButton />
            <LanguageSwitcher />
            <span className="hidden shrink-0 items-center gap-1.5 rounded-full border border-primary/40 px-2.5 py-1 text-[11px] font-semibold text-primary sm:flex">
              <Zap className="size-3.5" aria-hidden /> {t("badge.manual")}
            </span>
          </div>
        </div>
      </header>

      <main className="mx-auto max-w-3xl px-4">
        {order ? (
          <section className="mt-8" aria-live="polite">
            <div className="panel neon-glow rounded-3xl p-6 text-center">
              <span className="mx-auto grid size-14 place-items-center rounded-2xl bg-primary/15">
                <Clock className="size-7 text-primary" aria-hidden />
              </span>
              <h1 className="mt-4 font-display text-2xl font-bold">{t("ok.title")}</h1>
              <p className="mt-2 text-sm text-muted-foreground">{t("ok.sub")}</p>

              <div className="mt-5 grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 rounded-2xl bg-secondary/60 p-3 text-left">
                <div className="min-w-0">
                  <p className="text-[11px] tracking-wide text-muted-foreground uppercase">
                    {t("ok.orderId")}
                  </p>
                  <p className="neon-text truncate font-display text-xl font-bold">
                    {order.orderId}
                  </p>
                </div>
                <button
                  type="button"
                  onClick={() => copyOrderId(order.orderId)}
                  aria-label={t("ok.copyAria")}
                  className="flex shrink-0 items-center gap-1.5 rounded-xl bg-primary px-3 py-2 text-sm font-semibold text-primary-foreground hover:opacity-90 focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none"
                >
                  {copiedOrderId ? (
                    <Check className="size-4" aria-hidden />
                  ) : (
                    <Copy className="size-4" aria-hidden />
                  )}
                  {copiedOrderId ? t("pay.copied") : t("pay.copy")}
                </button>
              </div>

              <dl className="mt-4 space-y-2 text-left text-sm">
                {[
                  [
                    t("summary.package"),
                    orderPack
                      ? `${formatDiamonds(orderPack.diamonds)} ${t("packs.diamonds")}`
                      : order.packageLabel,
                  ],
                  [t("summary.total"), formatBDT(order.amount)],
                  [
                    t("ok.paidWith"),
                    `${order.paymentMethod === "bkash" ? "bKash" : "Nagad"} → ${order.payTo}`,
                  ],
                  [t("field.trx"), order.transactionId],
                  [t("field.uid"), order.freeFireUid],
                  [t("ok.status"), t("ok.statusValue")],
                ].map(([label, value]) => (
                  <div
                    key={label}
                    className="grid grid-cols-[minmax(0,auto)_minmax(0,1fr)] gap-3 border-b border-border/60 pb-2 last:border-0"
                  >
                    <dt className="text-muted-foreground">{label}</dt>
                    <dd className="truncate text-right font-medium">{value}</dd>
                  </div>
                ))}
              </dl>

              <p className="mt-4 text-xs text-muted-foreground">{t("ok.note")}</p>

              <button
                type="button"
                onClick={resetFlow}
                className="mt-5 h-12 w-full rounded-xl border border-primary/50 font-display font-semibold text-primary hover:bg-primary/10 focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none"
              >
                {t("ok.again")}
              </button>
            </div>
          </section>
        ) : (
          <>
            <section className="pt-8 pb-6 text-center">
              <h1 className="font-display text-3xl leading-tight font-bold sm:text-4xl">
                {t("hero.title.a")} <span className="neon-text">{t("hero.title.b")}</span>{" "}
                {t("hero.title.c")}
              </h1>
              <p className="mx-auto mt-3 max-w-md text-sm text-muted-foreground">
                {t("hero.sub")}
              </p>
              <div className="mt-5 flex flex-wrap justify-center gap-2 text-xs">
                {[
                  { icon: ShieldCheck, text: t("chip.review") },
                  { icon: Zap, text: t("chip.packs") },
                  { icon: Clock, text: t("chip.track") },
                ].map(({ icon: Icon, text }) => (
                  <span
                    key={text}
                    className="panel flex items-center gap-1.5 rounded-full px-3 py-1.5 text-muted-foreground"
                  >
                    <Icon className="size-3.5 text-primary" aria-hidden /> {text}
                  </span>
                ))}
              </div>
            </section>

            <form onSubmit={handleSubmit} noValidate className="space-y-8">
              <section aria-labelledby="step-1">
                <div id="step-1">
                  <StepHeading step={1} title={t("step1.title")} hint={t("step1.hint")} />
                </div>
                <PackageGrid selectedId={packageId} onSelect={setPackageId} />
                {errors.pack && (
                  <p className="mt-3 flex items-center gap-1.5 text-xs text-destructive">
                    <AlertCircle className="size-3.5" aria-hidden />
                    {errors.pack}
                  </p>
                )}
              </section>

              <section aria-labelledby="step-2">
                <div id="step-2">
                  <StepHeading step={2} title={t("step2.title")} hint={t("step2.hint")} />
                </div>
                <PaymentPanel
                  selectedMethodId={methodId}
                  onSelectMethod={setMethodId}
                  amountLabel={selectedPackage ? formatBDT(selectedPackage.price) : null}
                />
              </section>

              <section aria-labelledby="step-3">
                <div id="step-3">
                  <StepHeading step={3} title={t("step3.title")} hint={t("step3.hint")} />
                </div>
                <div className="panel space-y-4 rounded-2xl p-4">
                  <Field
                    id="trx"
                    label={t("field.trx")}
                    placeholder="9K2XA7B4CD"
                    inputMode="text"
                    autoComplete="off"
                    maxLength={20}
                    value={transactionId}
                    error={errors.trx}
                    hint={t("field.trx.hint")}
                    onChange={(e) => {
                      setTransactionId(e.target.value.toUpperCase());
                      if (errors.trx) setErrors((p) => ({ ...p, trx: undefined }));
                    }}
                  />
                  <Field
                    id="uid"
                    label={t("field.uid")}
                    placeholder="1234567890"
                    inputMode="numeric"
                    autoComplete="off"
                    maxLength={12}
                    value={uid}
                    error={errors.uid}
                    hint={t("field.uid.hint")}
                    onChange={(e) => {
                      setUid(e.target.value.replace(/\D/g, ""));
                      if (errors.uid) setErrors((p) => ({ ...p, uid: undefined }));
                    }}
                  />

                  <div className="rounded-2xl bg-secondary/50 p-3.5">
                    <p className="mb-2 text-[11px] tracking-wide text-muted-foreground uppercase">
                      {t("summary.title")}
                    </p>
                    <dl className="space-y-1.5 text-sm">
                      <div className="flex items-center justify-between gap-3">
                        <dt className="text-muted-foreground">{t("summary.package")}</dt>
                        <dd className="truncate font-medium">
                          {packageLabel ?? t("summary.none")}
                        </dd>
                      </div>
                      <div className="flex items-center justify-between gap-3">
                        <dt className="text-muted-foreground">{t("summary.payment")}</dt>
                        <dd className="truncate font-medium">{method.name}</dd>
                      </div>
                      <div className="flex items-center justify-between gap-3">
                        <dt className="text-muted-foreground">{t("summary.uid")}</dt>
                        <dd className="truncate font-medium tabular-nums">{uid || "—"}</dd>
                      </div>
                      <div className="flex items-center justify-between gap-3 border-t border-border/60 pt-2">
                        <dt className="font-semibold">{t("summary.total")}</dt>
                        <dd className="neon-text font-display text-lg font-bold">
                          {selectedPackage ? formatBDT(selectedPackage.price) : "৳0"}
                        </dd>
                      </div>
                    </dl>
                  </div>

                  <button
                    type="submit"
                    disabled={submitting}
                    className="flex h-13 w-full items-center justify-center gap-2 rounded-xl bg-primary py-3.5 font-display text-base font-bold text-primary-foreground transition-opacity hover:opacity-90 focus-visible:ring-2 focus-visible:ring-ring focus-visible:outline-none disabled:opacity-60"
                  >
                    {submitting ? (
                      <>
                        <Loader2 className="size-5 animate-spin" aria-hidden /> {t("submitting")}
                      </>
                    ) : (
                      t("submit")
                    )}
                  </button>
                  <p className="text-center text-xs text-muted-foreground">{t("submit.note")}</p>
                </div>
              </section>
            </form>
          </>
        )}

        <SupportSection />
      </main>

      <footer className="mx-auto mt-12 max-w-3xl px-4 text-center text-xs text-muted-foreground">
        <p>{t("footer.a")}</p>
        <p className="mt-1">{t("footer.b")}</p>
      </footer>

      <SupportWidget />
      <ButterflyBonus />
    </div>
  );
}
