import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";
import { useEffect, useState } from "react";
import { toast } from "sonner";
import { Tv, CheckCircle2, Gift } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { buyCable, verifySmartcard } from "@/lib/husmodata.functions";
import { listCablePlans } from "@/lib/catalogue.functions";
import { formatNaira } from "@/lib/format";
import { PinPromptDialog } from "@/components/PinPromptDialog";
import { cn } from "@/lib/utils";

export const Route = createFileRoute("/app/cable")({
  head: () => ({ meta: [{ title: "Cable TV — Billsline" }] }),
  component: CablePage,
});

const PROVIDERS = [
  { id: "dstv",      label: "DStv",      grad: "from-sky-600 to-blue-700" },
  { id: "gotv",      label: "GOtv",      grad: "from-emerald-500 to-green-700" },
  { id: "startimes", label: "StarTimes", grad: "from-orange-500 to-red-600" },
] as const;
type Prov = (typeof PROVIDERS)[number]["id"];

const PLANS: Record<Prov, { id: string; name: string; amount: number }[]> = {
  dstv: [
    { id: "dstv-padi",    name: "DStv Padi",    amount: 3600 },
    { id: "dstv-yanga",   name: "DStv Yanga",   amount: 5100 },
    { id: "dstv-confam",  name: "DStv Confam",  amount: 9300 },
    { id: "dstv-compact", name: "DStv Compact", amount: 15700 },
  ],
  gotv: [
    { id: "gotv-smallie", name: "GOtv Smallie", amount: 1575 },
    { id: "gotv-jinja",   name: "GOtv Jinja",   amount: 3300 },
    { id: "gotv-max",     name: "GOtv Max",     amount: 7600 },
  ],
  startimes: [
    { id: "nova",  name: "Nova",  amount: 1700 },
    { id: "basic", name: "Basic", amount: 3300 },
    { id: "smart", name: "Smart", amount: 4200 },
  ],
};

function CablePage() {
  const qc = useQueryClient();
  const navigate = useNavigate();
  const buy = useServerFn(buyCable);
  const verify = useServerFn(verifySmartcard);

  const [provider, setProvider] = useState<Prov>("dstv");
  const [smartcard, setSmartcard] = useState("");
  const fetchPlans = useServerFn(listCablePlans);
  const [plan, setPlan] = useState<{ id: string; name: string; amount: number; cashback?: number }>(PLANS.dstv[0]);
  const [customerName, setCustomerName] = useState("");
  const [pinOpen, setPinOpen] = useState(false);

  const { data: dbPlans, isLoading: plansLoading } = useQuery({
    queryKey: ["cable-plans", provider],
    queryFn: () => fetchPlans({ data: { cable_name: provider } }),
    staleTime: 30_000,
  });

  const plans = (dbPlans && dbPlans.length > 0)
    ? dbPlans.map((p) => ({
        id: String(p.plan_id),
        name: p.plan_name,
        amount: p.sell_price,
        cashback: p.cashback_percent,
      }))
    : PLANS[provider];

  useEffect(() => {
    if (plans.length && !plans.some((p) => p.id === plan.id)) setPlan(plans[0]);
  }, [plans, plan.id]);

  const v = useMutation({
    mutationFn: () => verify({ data: { provider, smartcard } }),
    onSuccess: (r: { name?: string }) => {
      if (r.name) { setCustomerName(r.name); toast.success(`Verified: ${r.name}`); }
      else toast.error("Could not verify smartcard");
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const m = useMutation({
    mutationFn: (pin: string) => buy({ data: { provider, smartcard, plan_id: plan.id, amount: plan.amount, pin } }),
    onSuccess: (r) => {
      qc.invalidateQueries();
      navigate({ to: "/app/tx/$ref", params: { ref: r.reference } });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  return (
    <div className="space-y-4 p-4">
      <h1 className="text-lg font-bold text-foreground">Cable TV</h1>

      <div className="grid grid-cols-3 gap-2">
        {PROVIDERS.map((p) => {
          const active = provider === p.id;
          return (
            <button key={p.id}
              onClick={() => { setProvider(p.id); setCustomerName(""); }}
              className={cn(
                "relative rounded-2xl p-3 text-center text-xs font-bold uppercase transition shadow-sm",
                active ? `bg-gradient-to-br ${p.grad} text-white shadow-md` : "bg-card text-muted-foreground hover:text-foreground",
              )}>
              <Tv className="mx-auto mb-1 h-4 w-4" />
              {p.label}
              {active && <CheckCircle2 className="absolute right-1.5 top-1.5 h-3.5 w-3.5" />}
            </button>
          );
        })}
      </div>

      <div className="space-y-3 rounded-2xl bg-card p-4 shadow-card">
        <div>
          <Label htmlFor="sc" className="text-[10px] uppercase tracking-wider text-muted-foreground">Smartcard / IUC</Label>
          <div className="mt-1 flex gap-2">
            <Input id="sc" inputMode="numeric" value={smartcard} placeholder="Enter number"
              onChange={(e) => { setSmartcard(e.target.value.replace(/\D/g, "").slice(0, 14)); setCustomerName(""); }}
              className="h-11 font-mono text-base tracking-wider" />
            <Button variant="outline" onClick={() => v.mutate()} disabled={v.isPending || smartcard.length < 8} className="h-11 shrink-0">
              {v.isPending ? "…" : "Verify"}
            </Button>
          </div>
          {customerName && (
            <p className="mt-1.5 flex items-center gap-1 text-xs font-medium text-success">
              <CheckCircle2 className="h-3 w-3" /> {customerName}
            </p>
          )}
        </div>
      </div>

      <div>
        <div className="mb-2 flex items-center justify-between">
          <h2 className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">Bouquets</h2>
          <span className="text-[10px] text-muted-foreground">{plansLoading ? "loading…" : `${plans.length} plans`}</span>
        </div>
        <div className="grid grid-cols-2 gap-2.5">
          {plans.map((p) => {
            const active = plan.id === p.id;
            return (
              <button key={p.id} onClick={() => setPlan(p)}
                className={cn(
                  "relative overflow-hidden rounded-2xl border p-3 text-left transition",
                  active ? "border-primary bg-primary/5 ring-2 ring-primary/20" : "border-border bg-card hover:border-primary/40",
                )}>
                {active && <CheckCircle2 className="absolute right-2 top-2 h-4 w-4 text-primary" />}
                <div className="truncate text-sm font-bold text-foreground">{p.name}</div>
                <div className="mt-2 text-base font-extrabold text-primary">{formatNaira(p.amount)}</div>
                {Number((p as { cashback?: number }).cashback ?? 0) > 0 ? (
                  <div className="mt-1 inline-flex items-center gap-1 rounded-full bg-success/10 px-2 py-0.5 text-[10px] font-semibold text-success">
                    <Gift className="h-3 w-3" /> {Number((p as { cashback?: number }).cashback)}% cashback
                  </div>
                ) : null}
              </button>
            );
          })}
        </div>
      </div>

      <div className="sticky bottom-20 z-10 -mx-4 border-t border-border/50 bg-background/85 px-4 py-3 backdrop-blur">
        <Button className="h-11 w-full bg-gradient-primary text-sm font-semibold"
          disabled={m.isPending || smartcard.length < 8}
          onClick={() => setPinOpen(true)}>
          {m.isPending ? "Processing…" : `Pay ${formatNaira(plan.amount)}`}
        </Button>
      </div>

      <PinPromptDialog
        open={pinOpen} onOpenChange={setPinOpen}
        title="Confirm cable subscription"
        description="Enter your 4-digit PIN to authorize this subscription."
        amount={plan.amount}
        summary={[
          { label: "Service", value: "Cable TV subscription" },
          { label: "Provider", value: provider.toUpperCase() },
          { label: "Package", value: plan.name },
          { label: "Smartcard number", value: smartcard || "—" },
          { label: "Paid from", value: "Billsline Wallet" },
        ]}
        onVerified={(pin) => m.mutate(pin)}
      />
    </div>
  );
}
