import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";
import { useState } from "react";
import { createPortal } from "react-dom";
import { CalendarDays, Check, Download, IndianRupee, Loader2, Users, X } from "lucide-react";
import { useBusiness } from "@/lib/business-context";
import { Card, PartnerShell, StatusPill } from "@/components/partner/PartnerShell";
import { changePlan, getBilling } from "@/lib/partner.functions";
import { PLANS } from "@/lib/partner-catalog";

export const Route = createFileRoute("/_partner/partner/billing")({
  head: () => ({
    meta: [
      { title: "Subscription & Invoices — Airfis Partner" },
      { name: "description", content: "Review your Airfis plan, usage limits and past invoices." },
      { property: "og:title", content: "Subscription & Invoices — Airfis Partner" },
      { property: "og:description", content: "Change plan and download partner invoices." },
      { property: "og:type", content: "website" },
      { name: "twitter:card", content: "summary" },
      { name: "robots", content: "noindex" },
    ],
  }),
  component: BillingPage,
});

function formatDate(value?: string | number | Date | null) {
  if (!value) return "—";
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return "—";
  return date.toLocaleDateString("en-IN", {
    day: "numeric",
    month: "short",
    year: "numeric",
  });
}

function BillingPage() {
  const qc = useQueryClient();
  const navigate = useNavigate();
  const [plansOpen, setPlansOpen] = useState(false);
  const { activeId } = useBusiness();
  const fetchBilling = useServerFn(getBilling);
  const switchPlan = useServerFn(changePlan);
  const { data, isLoading } = useQuery({
    queryKey: ["partner", "billing", activeId],
    queryFn: () => fetchBilling({ data: { businessId: activeId } }),
  });

  async function pick(plan: (typeof PLANS)[number]) {
    await switchPlan({
      data: {
        businessId: activeId,
        planName: plan.name,
        price: plan.price,
        features: plan.features,
        limits: plan.limits,
      },
    });
    await qc.invalidateQueries({ queryKey: ["partner"] });
  }

  async function downloadInvoice(invoice: NonNullable<typeof data>["invoices"][number]) {
    const { jsPDF } = await import("jspdf");
    const pdf = new jsPDF();
    const businessName = data?.partner.shop_name ?? data?.partner.business_name ?? "Business";
    const issuedDate = new Date(invoice.issued_at).toLocaleDateString("en-IN", {
      day: "numeric",
      month: "long",
      year: "numeric",
    });

    pdf.setFont("helvetica", "bold");
    pdf.setFontSize(22);
    pdf.text("AIRFIS", 20, 24);
    pdf.setFontSize(16);
    pdf.text("Subscription invoice", 20, 38);
    pdf.setDrawColor(230, 230, 230);
    pdf.line(20, 45, 190, 45);

    pdf.setFont("helvetica", "normal");
    pdf.setFontSize(11);
    pdf.text(`Invoice number: ${invoice.invoice_number}`, 20, 58);
    pdf.text(`Issued on: ${issuedDate}`, 20, 67);
    pdf.text(`Business: ${businessName}`, 20, 76);
    pdf.text(`Account ID: ${data?.partner.id.slice(0, 12) ?? ""}`, 20, 85);
    pdf.text(`Subscription ID: ${data?.subscription.id.slice(0, 12) ?? ""}`, 20, 94);

    pdf.setFont("helvetica", "bold");
    pdf.text("Plan", 20, 112);
    pdf.text("Amount", 145, 112);
    pdf.setFont("helvetica", "normal");
    pdf.text(`${data?.subscription.plan_name ?? "Airfis"} plan`, 20, 124);
    pdf.text(`INR ${Number(invoice.amount).toLocaleString("en-IN")}`, 145, 124);
    pdf.line(20, 132, 190, 132);
    pdf.setFont("helvetica", "bold");
    pdf.text(
      `Status: ${invoice.status.charAt(0).toUpperCase()}${invoice.status.slice(1)}`,
      20,
      145,
    );
    pdf.text(`Total: INR ${Number(invoice.amount).toLocaleString("en-IN")}`, 145, 145);
    pdf.setFont("helvetica", "normal");
    pdf.setFontSize(9);
    pdf.text("Airfis Solution Pvt Ltd", 20, 278);
    pdf.save(`${invoice.invoice_number}.pdf`);
  }

  return (
    <PartnerShell title="Subscription" description="Plan, usage limits and invoices">
      {isLoading ? (
        <Card className="flex justify-center py-20">
          <Loader2 className="h-5 w-5 animate-spin text-ink-3" />
        </Card>
      ) : data ? (
        <div className="space-y-6">
          <Card className="border-0">
            <div>
              <div className="flex flex-wrap items-center justify-between gap-4">
                <div className="flex items-center gap-3">
                  <h3 className="text-lg font-bold text-ink">
                    {data.partner.shop_name ?? data.partner.business_name ?? "Business"}
                  </h3>
                  <StatusPill status={data.subscription.status} />
                </div>

                <div className="flex items-center gap-2">
                  <Link
                    to="/partner/billing/checkout"
                    search={{ plan: data.subscription.plan_name, mode: "renew" }}
                    className="btn-ghost"
                  >
                    Renew Plan
                  </Link>
                  <button type="button" onClick={() => setPlansOpen(true)} className="btn-brand">
                    Upgrade Plan
                  </button>
                </div>
              </div>

              <p className="mt-2 text-sm text-ink-2 whitespace-nowrap overflow-x-auto">
                {[data.partner.city, data.partner.pincode, data.partner.email]
                  .filter(Boolean)
                  .join(" · ")}
                {" · "}Account Id:{" "}
                <span className="font-semibold text-ink">{data.partner.id.slice(0, 12)}</span>
                {" · "}Subscription Id:{" "}
                <span className="font-semibold text-ink">{data.subscription.id.slice(0, 12)}</span>
              </p>
            </div>

            <h4 className="mt-6 text-sm font-normal text-ink-2">Subscription details</h4>
            <div className="mt-3 overflow-hidden rounded-xl border border-line">
              <div className="overflow-x-auto">
                <table className="w-full min-w-[560px] border-collapse text-sm">
                  <thead>
                    <tr className="bg-[#f6f6f7] text-left text-ink-2">
                      <th className="px-4 py-2.5 font-semibold">Subscription ID</th>
                      <th className="px-4 py-2.5 font-semibold">Start date</th>
                      <th className="px-4 py-2.5 font-semibold">Renews on</th>
                      <th className="px-4 py-2.5 font-semibold">Billing cycle</th>
                    </tr>
                  </thead>
                  <tbody>
                    <tr className="border-t border-line text-ink">
                      <td className="px-4 py-2.5">
                        {data.subscription.id.slice(0, 8).toUpperCase()}
                      </td>
                      <td className="px-4 py-2.5">
                        {formatDate(data.subscription.started_at)}
                      </td>
                      <td className="px-4 py-2.5">
                        {formatDate(data.subscription.renews_at)}
                      </td>
                      <td className="px-4 py-2.5 capitalize">{data.subscription.billing_cycle}</td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>

            <p className="mt-6 text-sm text-ink-2">Current plan</p>
            <p className="mt-0.5 text-base font-bold text-ink capitalize">
              {data.subscription.plan_name}
            </p>
            <div className="mt-3 grid gap-4 sm:grid-cols-3">
              <Detail
                icon={IndianRupee}
                value={`₹${Number(data.subscription.price).toLocaleString("en-IN")}/month`}
                label="Billing"
              />
              <Detail
                icon={Users}
                value={String(
                  (data.subscription.usage_limits as { team?: number } | null)?.team ?? "—",
                )}
                label="Team members included"
              />
              <Detail
                icon={CalendarDays}
                value={formatDate(data.subscription.renews_at)}
                label="Renews at"
              />
            </div>
          </Card>

          {plansOpen &&
            createPortal(
              <div className="fixed inset-0 z-[100] flex items-start justify-center overflow-y-auto p-4 sm:p-8">
                <button
                  type="button"
                  aria-label="Close"
                  onClick={() => setPlansOpen(false)}
                  className="absolute inset-0 bg-black/40 backdrop-blur-[2px]"
                />
                <div
                  role="dialog"
                  aria-modal="true"
                  className="relative w-full max-w-5xl rounded-3xl bg-white p-6 shadow-2xl"
                >
                  <div className="flex items-start justify-between gap-3">
                    <div>
                      <h3 className="text-lg font-bold text-ink">Choose a plan</h3>
                      <p className="text-sm text-ink-2">
                        Switch anytime — changes apply to this business.
                      </p>
                    </div>
                    <button
                      type="button"
                      onClick={() => setPlansOpen(false)}
                      aria-label="Close plans"
                      className="text-ink-3 hover:text-ink"
                    >
                      <X className="h-5 w-5" />
                    </button>
                  </div>
                  <div className="mt-5 grid gap-4 md:grid-cols-3">
                    {PLANS.map((p) => {
                      const active = data.subscription.plan_name === p.name;
                      return (
                        <div
                          key={p.name}
                          className={`rounded-2xl p-5 ${active ? "bg-[#ffebe3]" : "bg-surface"}`}
                        >
                          <div className="flex items-center justify-between">
                            <h4 className="font-bold text-ink">{p.name}</h4>
                            {active && <StatusPill status="active" />}
                          </div>
                          <p className="mt-1 text-sm text-ink-2">{p.blurb}</p>
                          <p className="mt-4 text-3xl font-bold text-ink">
                            ₹{p.price.toLocaleString("en-IN")}
                            <span className="text-sm font-normal text-ink-2"> /mo</span>
                          </p>
                          <ul className="mt-4 space-y-2">
                            {p.features.map((f) => (
                              <li key={f} className="flex items-start gap-2 text-sm text-ink-2">
                                <Check className="mt-0.5 h-4 w-4 shrink-0 text-[#FF4308]" /> {f}
                              </li>
                            ))}
                          </ul>
                          <button
                            type="button"
                            disabled={active}
                            onClick={async () => {
                              setPlansOpen(false);
                              if (p.price === 0) {
                                await pick(p);
                                return;
                              }
                              await navigate({
                                to: "/partner/billing/checkout",
                                search: { plan: p.name, mode: "upgrade" },
                              });
                            }}
                            className={`mt-5 w-full ${active ? "btn-ghost opacity-60" : "btn-brand"}`}
                          >
                            {active ? "Current plan" : `Switch to ${p.name}`}
                          </button>
                        </div>
                      );
                    })}
                  </div>
                </div>
              </div>,
              document.body,
            )}

          <Card className="border-0">
            <h3 className="font-bold text-ink">Invoices</h3>
            <div className="mt-4 space-y-1">
              {data.invoices.map((inv) => (
                <div
                  key={inv.id}
                  className="flex flex-wrap items-center justify-between gap-3 py-3"
                >
                  <div>
                    <p className="text-sm font-semibold text-ink">{inv.invoice_number}</p>
                    <p className="text-xs text-ink-2">
                      {new Date(inv.issued_at).toLocaleDateString("en-IN")}
                    </p>
                  </div>
                  <div className="flex items-center gap-4">
                    <span className="text-sm font-semibold text-ink">
                      ₹{Number(inv.amount).toLocaleString("en-IN")}
                    </span>
                    <StatusPill status={inv.status} />
                    <button
                      type="button"
                      onClick={() => void downloadInvoice(inv)}
                      aria-label={`Download ${inv.invoice_number} as PDF`}
                      title="Download PDF"
                      className="inline-flex h-9 w-9 items-center justify-center rounded-full text-ink-2 transition-colors hover:bg-[#ffebe3] hover:text-[#FF4308]"
                    >
                      <Download className="h-4 w-4" />
                    </button>
                  </div>
                </div>
              ))}
            </div>
          </Card>
        </div>
      ) : null}
    </PartnerShell>
  );
}

function Detail({
  icon: Icon,
  value,
  label,
}: {
  icon: typeof Users;
  value: string;
  label: string;
}) {
  return (
    <div className="flex items-start gap-3 rounded-2xl bg-surface p-4">
      <span className="inline-flex h-9 w-9 shrink-0 items-center justify-center rounded-xl bg-[#f3f3f3] text-[#0a0a12]">
        <Icon className="h-[18px] w-[18px]" />
      </span>
      <div className="min-w-0">
        <p className="font-semibold text-ink">{value}</p>
        <p className="text-sm text-ink-2">{label}</p>
      </div>
    </div>
  );
}
