"use client";

import { IconCheck, IconMinus, IconPlus, IconX } from "@tabler/icons-react";
import { useTranslations } from "next-intl";
import Link from "next/link";
import { useState, useTransition } from "react";
import { toast } from "sonner";

import { CurrencySelector } from "@/components/billing/currency-selector";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { createCheckoutSession, openCustomerPortal } from "@/lib/actions/billing";
import { formatPrice, type Currency } from "@/lib/billing/currency";
import {
  BILLABLE_PLANS,
  FREE_LIMITS,
  SEAT_ADDON,
  type BillablePlan,
  type BillingInterval,
} from "@/lib/billing/plans";
import { cn } from "@/lib/utils";

type Tier = "free" | BillablePlan;
type CellValue = string | { type: "check" } | { type: "cross" };

const CHECK: CellValue = { type: "check" };
const CROSS: CellValue = { type: "cross" };
const TIERS: readonly Tier[] = ["free", "starter", "pro", "business"] as const;
const PAID_TIERS: readonly BillablePlan[] = ["starter", "pro", "business"] as const;
const PRO_COLUMN_INDEX = 2;

type Props = {
  initialCurrency: Currency;
  locale: string;
  /* null = unauthenticated. */
  currentPlan: string | null;
};

/* Unified pricing component (replaces PricingGrid + ComparisonTable).
   - Sticky header row with per-tier price + Select CTA.
   - Currency selector + Monthly/Yearly fieldset toggle.
   - Per-tier "extra seats" stepper (paid tiers only).
   - Feature comparison rows underneath the header.

   The currency cookie + router.refresh() are handled inside
   CurrencySelector itself — we just mirror the state locally so the
   displayed prices update without waiting for the server round-trip. */
export function PricingTable({ initialCurrency, locale, currentPlan }: Props) {
  const t = useTranslations("Pricing");
  const tBilling = useTranslations("Settings.billing");

  const [currency, setCurrency] = useState<Currency>(initialCurrency);
  const [interval, setInterval] = useState<BillingInterval>("month");
  const [extraSeats, setExtraSeats] = useState<Record<BillablePlan, number>>({
    starter: 0,
    pro: 0,
    business: 0,
  });
  const [isPending, startTransition] = useTransition();

  const isAuth = currentPlan !== null;
  const isMonthly = interval === "month";

  /* --- Tier metadata ---------------------------------------------------- */

  const tierMeta: Record<Tier, { name: string; description: string }> = {
    free: { name: "Free", description: t("freeDescription") },
    starter: { name: BILLABLE_PLANS.starter.name, description: t("starterDescription") },
    pro: { name: BILLABLE_PLANS.pro.name, description: t("proDescription") },
    business: { name: BILLABLE_PLANS.business.name, description: t("businessDescription") },
  };

  function priceFor(tier: Tier): string {
    if (tier === "free") return formatPrice(0, currency, locale);
    return formatPrice(BILLABLE_PLANS[tier].prices[currency][interval], currency, locale);
  }

  function limitFor(
    tier: Tier,
    key: "testsPerMonth" | "sites" | "seats" | "retentionDays",
  ): number {
    if (tier === "free") return FREE_LIMITS[key];
    return BILLABLE_PLANS[tier].limits[key];
  }

  /* --- CTA resolution --------------------------------------------------- */

  type CTA = {
    label: string;
    onClick?: () => void;
    href?: string;
    disabled?: boolean;
  };

  function ctaForTier(tier: Tier): CTA {
    const name = tierMeta[tier].name;

    if (!isAuth) {
      if (tier === "free") {
        return { label: t("ctaSignupFree"), href: `/${locale}/signup` };
      }
      const seats = extraSeats[tier];
      const qs = new URLSearchParams({
        plan: tier,
        interval,
        currency,
        seats: String(seats),
      });
      return {
        label: t("select"),
        href: `/${locale}/signup?${qs.toString()}`,
      };
    }

    if (tier === currentPlan) {
      return { label: tBilling("ctaCurrent"), disabled: true };
    }

    if (tier === "free") {
      return {
        label: t("ctaDowngradeFree"),
        onClick: () =>
          startTransition(async () => {
            try {
              const { url } = await openCustomerPortal();
              window.location.href = url;
            } catch {
              toast.error(tBilling("portalError"));
            }
          }),
      };
    }

    return {
      label: tBilling("ctaUpgrade", { tier: name }),
      onClick: () =>
        startTransition(async () => {
          try {
            const { url } = await createCheckoutSession({
              plan: tier,
              interval,
              currency,
              extraSeats: extraSeats[tier],
            });
            window.location.href = url;
          } catch {
            toast.error(tBilling("checkoutError"));
          }
        }),
    };
  }

  /* --- Feature rows (ported from comparison-table.tsx) ------------------ */

  const rows: { label: string; values: [CellValue, CellValue, CellValue, CellValue] }[] = [
    {
      label: t("comparisonRows.testsPerMonth"),
      values: [
        String(FREE_LIMITS.testsPerMonth),
        String(BILLABLE_PLANS.starter.limits.testsPerMonth),
        String(BILLABLE_PLANS.pro.limits.testsPerMonth),
        String(BILLABLE_PLANS.business.limits.testsPerMonth),
      ],
    },
    {
      label: t("comparisonRows.sites"),
      values: [
        String(FREE_LIMITS.sites),
        String(BILLABLE_PLANS.starter.limits.sites),
        String(BILLABLE_PLANS.pro.limits.sites),
        String(BILLABLE_PLANS.business.limits.sites),
      ],
    },
    {
      label: t("comparisonRows.seats"),
      values: [
        String(FREE_LIMITS.seats),
        String(BILLABLE_PLANS.starter.limits.seats),
        String(BILLABLE_PLANS.pro.limits.seats),
        String(BILLABLE_PLANS.business.limits.seats),
      ],
    },
    {
      label: t("comparisonRows.retention"),
      values: [
        `${FREE_LIMITS.retentionDays}d`,
        `${BILLABLE_PLANS.starter.limits.retentionDays}d`,
        `${BILLABLE_PLANS.pro.limits.retentionDays}d`,
        `${BILLABLE_PLANS.business.limits.retentionDays}d`,
      ],
    },
    {
      label: t("comparisonRows.api"),
      values: [CROSS, CHECK, CHECK, CHECK],
    },
    {
      label: t("comparisonRows.emailAlerts"),
      values: [CROSS, CHECK, CHECK, CHECK],
    },
    {
      label: t("comparisonRows.slackAlerts"),
      values: [CROSS, t("comparisonValues.webhookOnly"), CHECK, CHECK],
    },
    {
      label: t("comparisonRows.whiteLabel"),
      values: [CROSS, CROSS, CROSS, CHECK],
    },
    {
      label: t("comparisonRows.support"),
      values: [
        CROSS,
        t("comparisonValues.supportEmail"),
        t("comparisonValues.supportStandard"),
        t("comparisonValues.supportPriority"),
      ],
    },
  ];

  /* --- Seat stepper ----------------------------------------------------- */

  function clampSeats(n: number): number {
    if (Number.isNaN(n)) return 0;
    if (n < 0) return 0;
    if (n > 100) return 100;
    return Math.floor(n);
  }

  function setSeats(tier: BillablePlan, next: number) {
    setExtraSeats((prev) => ({ ...prev, [tier]: clampSeats(next) }));
  }

  const seatPrice = formatPrice(SEAT_ADDON.prices[currency][interval], currency, locale);

  /* --- Render ----------------------------------------------------------- */

  return (
    <section className="flex flex-col gap-6">
      {/* Top bar — interval toggle + currency selector */}
      <div className="flex flex-col items-center justify-between gap-4 md:flex-row">
        <fieldset aria-label="Payment frequency">
          <div className="grid grid-cols-2 gap-x-1 rounded-full p-1 text-center text-xs/5 font-semibold inset-ring inset-ring-border">
            <label className="group relative cursor-pointer rounded-full px-2.5 py-1 has-checked:bg-primary">
              <input
                checked={isMonthly}
                onChange={() => setInterval("month")}
                value="monthly"
                name="frequency"
                type="radio"
                className="absolute inset-0 cursor-pointer appearance-none rounded-full"
              />
              <span className="text-muted-foreground group-has-checked:text-primary-foreground">
                {tBilling("monthly")}
              </span>
            </label>
            <label className="group relative cursor-pointer rounded-full px-2.5 py-1 has-checked:bg-primary">
              <input
                checked={!isMonthly}
                onChange={() => setInterval("year")}
                value="annually"
                name="frequency"
                type="radio"
                className="absolute inset-0 cursor-pointer appearance-none rounded-full"
              />
              <span className="text-muted-foreground group-has-checked:text-primary-foreground">
                {tBilling("yearly")}
              </span>
            </label>
          </div>
        </fieldset>

        <div className="flex items-center gap-3">
          {!isMonthly && (
            <Badge variant="secondary" className="text-xs">
              {t("yearlyHint")}
            </Badge>
          )}
          <span className="sr-only" id="currency-label">
            {t("currencyLabel")}
          </span>
          <div aria-labelledby="currency-label">
            <CurrencySelector value={currency} onChange={setCurrency} />
          </div>
        </div>
      </div>

      {/* Unified pricing + features table. min-w-[720px] forces a
          horizontal scroll on narrow viewports — the parent
          <Table> already wraps the element in `overflow-x-auto`. */}
      <Table className="min-w-[720px]">
        <TableHeader className="sticky top-0 z-10 bg-background">
          <TableRow>
            <TableHead scope="col" className="w-[28%] align-top">
              <span className="sr-only">{t("comparisonRows.feature")}</span>
            </TableHead>
            {TIERS.map((tier, idx) => {
              const meta = tierMeta[tier];
              const cta = ctaForTier(tier);
              const featured = tier === "pro";
              const button = (
                <Button
                  type="button"
                  variant={featured ? "default" : "outline"}
                  size="sm"
                  onClick={cta.onClick}
                  disabled={cta.disabled || isPending}
                  aria-describedby={`tier-${tier}`}
                  className="mt-3 w-full"
                >
                  {cta.label}
                </Button>
              );
              return (
                <TableHead
                  key={tier}
                  scope="col"
                  className={cn(
                    "relative text-center align-top whitespace-normal",
                    idx === PRO_COLUMN_INDEX && "bg-primary/5",
                  )}
                >
                  {featured && (
                    <Badge
                      variant="default"
                      className="absolute -top-2 left-1/2 -translate-x-1/2 text-[10px] tracking-wide uppercase"
                    >
                      {t("recommended")}
                    </Badge>
                  )}
                  <div className="flex flex-col items-center gap-1 pt-3 pb-2">
                    <span
                      id={`tier-${tier}`}
                      className={cn(
                        "text-base font-semibold",
                        featured ? "text-primary" : "text-foreground",
                      )}
                    >
                      {meta.name}
                    </span>
                    <span className="text-xl font-bold tracking-tight text-foreground tabular-nums">
                      {priceFor(tier)}
                    </span>
                    <span className="text-[11px] font-normal text-muted-foreground">
                      {isMonthly ? "/ month" : "/ year"}
                    </span>
                  </div>
                  {cta.href ? (
                    <Link href={cta.href} className="block">
                      {button}
                    </Link>
                  ) : (
                    button
                  )}
                </TableHead>
              );
            })}
          </TableRow>
        </TableHeader>

        <TableBody>
          {/* Feature rows */}
          {rows.map((row) => (
            <TableRow key={row.label}>
              <th
                scope="row"
                className="p-2 text-left align-middle text-sm font-medium whitespace-normal"
              >
                {row.label}
              </th>
              {row.values.map((v, idx) => (
                <TableCell
                  key={idx}
                  className={cn("text-center text-sm", idx === PRO_COLUMN_INDEX && "bg-primary/5")}
                >
                  <CellContent value={v} />
                </TableCell>
              ))}
            </TableRow>
          ))}

          {/* Extra seats row — stepper per paid tier */}
          <TableRow>
            <th
              scope="row"
              className="p-2 text-left align-middle text-sm font-medium whitespace-normal"
            >
              <span className="block">{t("rows.extraSeats")}</span>
              <span className="block text-[11px] font-normal text-muted-foreground">
                {t("extraSeats.perSeat", { price: seatPrice })}
              </span>
            </th>
            {TIERS.map((tier, idx) => {
              if (tier === "free") {
                return (
                  <TableCell key={tier} className="text-center text-muted-foreground">
                    {t("extraSeats.notAvailable")}
                  </TableCell>
                );
              }
              const paidTier = tier as BillablePlan;
              const value = extraSeats[paidTier];
              const tierName = tierMeta[paidTier].name;
              return (
                <TableCell
                  key={tier}
                  className={cn("text-center", idx === PRO_COLUMN_INDEX && "bg-primary/5")}
                >
                  <div className="inline-flex items-center gap-1">
                    <Button
                      type="button"
                      variant="outline"
                      size="icon-xs"
                      onClick={() => setSeats(paidTier, value - 1)}
                      disabled={value <= 0}
                      aria-label={`Decrease seats for ${tierName}`}
                    >
                      <IconMinus className="size-3" aria-hidden="true" />
                    </Button>
                    <input
                      type="number"
                      min={0}
                      max={100}
                      value={value}
                      onChange={(e) => setSeats(paidTier, Number(e.target.value))}
                      aria-label={t("extraSeats.ariaLabel", { tier: tierName })}
                      className="h-7 w-12 [appearance:textfield] rounded-md border border-input bg-background px-1 text-center text-xs tabular-nums focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none"
                    />
                    <Button
                      type="button"
                      variant="outline"
                      size="icon-xs"
                      onClick={() => setSeats(paidTier, value + 1)}
                      disabled={value >= 100}
                      aria-label={`Increase seats for ${tierName}`}
                    >
                      <IconPlus className="size-3" aria-hidden="true" />
                    </Button>
                  </div>
                </TableCell>
              );
            })}
          </TableRow>
        </TableBody>
      </Table>

      {/* Hidden but accessible: enumerate paid tiers explicitly for screen
          readers listing the seats controls (no-op visually). */}
      <ul className="sr-only" aria-hidden="true">
        {PAID_TIERS.map((tier) => (
          <li key={tier}>{tierMeta[tier].name}</li>
        ))}
      </ul>
    </section>
  );
}

function CellContent({ value }: { value: CellValue }) {
  if (typeof value === "string") {
    return <span className="text-sm text-foreground">{value}</span>;
  }
  if (value.type === "check") {
    return <IconCheck className="mx-auto size-5 text-primary" aria-label="Included" />;
  }
  return <IconX className="mx-auto size-5 text-muted-foreground/40" aria-label="Not included" />;
}
