import { createFileRoute } from "@tanstack/react-router";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";
import { adminListDataPlans, adminUpdateDataPlan, adminBulkMarkupDataPlans, adminSyncHusmodataPlans, adminListMarkups, adminUpsertCategoryMarkup, adminUpsertTierMarkup } from "@/lib/admin.functions";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { toast } from "sonner";
import { useState } from "react";
import { formatNaira } from "@/lib/format";

export const Route = createFileRoute("/admin/data-plans")({ component: AdminDataPlans });

function AdminDataPlans() {
  const qc = useQueryClient();
  const fetchPlans = useServerFn(adminListDataPlans);
  const update = useServerFn(adminUpdateDataPlan);
  const bulk = useServerFn(adminBulkMarkupDataPlans);
  const sync = useServerFn(adminSyncHusmodataPlans);
  const { data, isLoading } = useQuery({ queryKey: ["admin-data-plans"], queryFn: () => fetchPlans() });
  const [bulkPct, setBulkPct] = useState("");

  const mSync = useMutation({ mutationFn: () => sync(),
    onSuccess: (r) => { qc.invalidateQueries({ queryKey: ["admin-data-plans"] }); toast.success(`Synced ${r.upserted} plans`); },
    onError: (e: Error) => toast.error(e.message) });
  const mUpdate = useMutation({ mutationFn: (v: { id: string; markup_percent?: number; is_active?: boolean }) => update({ data: v }),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ["admin-data-plans"] }); toast.success("Saved"); },
    onError: (e: Error) => toast.error(e.message) });
  const mBulk = useMutation({ mutationFn: (v: { markup_percent: number }) => bulk({ data: v }),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ["admin-data-plans"] }); toast.success("Applied to all"); },
    onError: (e: Error) => toast.error(e.message) });

  return (
    <div className="space-y-4">
      <CategoryMarkups />
      <TierMarkups />
      <div className="rounded-2xl bg-card p-4 shadow-card">
        <div className="flex flex-wrap items-end gap-3">
          <Button onClick={() => mSync.mutate()} disabled={mSync.isPending}>
            {mSync.isPending ? "Syncing…" : "Sync live plans"}
          </Button>

          <div className="flex items-end gap-2">
            <div><label className="text-xs text-muted-foreground">Bulk markup % (all plans)</label>
              <Input type="number" value={bulkPct} onChange={(e) => setBulkPct(e.target.value)} className="w-32" /></div>
            <Button variant="outline" disabled={!bulkPct} onClick={() => mBulk.mutate({ markup_percent: Number(bulkPct) })}>Apply to all</Button>
          </div>
        </div>
        <p className="mt-2 text-xs text-muted-foreground">Per-plan markup overrides category markup. Sync pulls every plan from Husmodata.</p>
      </div>


      {isLoading ? <p className="text-muted-foreground">Loading…</p> : (
        <div className="overflow-x-auto rounded-2xl bg-card shadow-card">
          <table className="w-full text-sm">
            <thead className="bg-secondary text-left text-xs uppercase">
              <tr><th className="p-3">Network</th><th className="p-3">Plan</th><th className="p-3">Type</th><th className="p-3">Validity</th>
                <th className="p-3">Cost</th><th className="p-3">Markup %</th><th className="p-3">Sell @</th><th className="p-3">Active</th></tr>
            </thead>
            <tbody>
              {(data ?? []).map((p) => {
                const sell = Number(p.base_price) * (1 + Number(p.markup_percent) / 100) + Number(p.markup_flat);
                return (
                  <tr key={p.id} className="border-t">
                    <td className="p-3 uppercase">{p.network}</td>
                    <td className="p-3">{p.plan_name}</td>
                    <td className="p-3 text-xs text-muted-foreground">{p.plan_type ?? "—"}</td>
                    <td className="p-3 text-xs">{p.validity ?? "—"}</td>
                    <td className="p-3">{formatNaira(Number(p.base_price))}</td>
                    <td className="p-3">
                      <Input type="number" defaultValue={Number(p.markup_percent)} className="w-20"
                        onBlur={(e) => {
                          const v = Number(e.target.value);
                          if (v !== Number(p.markup_percent)) mUpdate.mutate({ id: p.id, markup_percent: v });
                        }} />
                    </td>
                    <td className="p-3 font-semibold text-primary">{formatNaira(sell)}</td>
                    <td className="p-3">
                      <Button size="sm" variant={p.is_active ? "outline" : "secondary"}
                        onClick={() => mUpdate.mutate({ id: p.id, is_active: !p.is_active })}>
                        {p.is_active ? "On" : "Off"}
                      </Button>
                    </td>
                  </tr>
                );
              })}
              {!data?.length && <tr><td colSpan={8} className="p-8 text-center text-muted-foreground">No plans yet. Click "Sync from Husmodata" to import.</td></tr>}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}

const CATS = ["airtime", "data", "cable", "electricity", "exam_pin"] as const;

function CategoryMarkups() {
  const qc = useQueryClient();
  const fetchMarkups = useServerFn(adminListMarkups);
  const upsert = useServerFn(adminUpsertCategoryMarkup);
  const { data } = useQuery({ queryKey: ["admin-markups"], queryFn: () => fetchMarkups() });
  const m = useMutation({
    mutationFn: (v: { category: typeof CATS[number]; percent: number; flat: number }) => upsert({ data: v }),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ["admin-markups"] }); toast.success("Markup saved"); },
    onError: (e: Error) => toast.error(e.message),
  });
  const map = new Map((data?.category ?? []).filter((r) => r.category != null).map((r) => [r.category as string, { category: r.category as string, percent: Number(r.percent), flat: Number(r.flat) }]));
  return (
    <div className="rounded-2xl bg-card p-4 shadow-card">
      <h2 className="mb-3 font-semibold">Category markups</h2>
      <p className="mb-3 text-xs text-muted-foreground">Default markup applied to every plan in a category. Per-plan overrides win when set above 0.</p>
      <div className="grid gap-3 md:grid-cols-2">
        {CATS.map((c) => {
          const row = map.get(c) as { percent: number; flat: number } | undefined;
          return <CatRow key={c} cat={c} percent={Number(row?.percent ?? 0)} flat={Number(row?.flat ?? 0)} onSave={(percent, flat) => m.mutate({ category: c, percent, flat })} />;
        })}
      </div>
    </div>
  );
}

function CatRow({ cat, percent, flat, onSave }: { cat: string; percent: number; flat: number; onSave: (p: number, f: number) => void }) {
  const [p, setP] = useState(String(percent));
  const [f, setF] = useState(String(flat));
  return (
    <div className="flex items-end gap-2 rounded-xl border p-3">
      <div className="flex-1"><div className="text-xs font-semibold uppercase text-muted-foreground">{cat}</div></div>
      <div><label className="text-xs">%</label><Input className="w-20" type="number" value={p} onChange={(e) => setP(e.target.value)} /></div>
      <div><label className="text-xs">flat ₦</label><Input className="w-24" type="number" value={f} onChange={(e) => setF(e.target.value)} /></div>
      <Button size="sm" onClick={() => onSave(Number(p) || 0, Number(f) || 0)}>Save</Button>
    </div>
  );
}

const TIERS = ["bronze", "silver", "gold", "platinum"] as const;
type Tier = typeof TIERS[number];

function TierMarkups() {
  const qc = useQueryClient();
  const fetchMarkups = useServerFn(adminListMarkups);
  const upsert = useServerFn(adminUpsertTierMarkup);
  const { data } = useQuery({ queryKey: ["admin-markups"], queryFn: () => fetchMarkups() });
  const m = useMutation({
    mutationFn: (v: { tier: Tier; category: typeof CATS[number] | null; percent: number; flat: number }) => upsert({ data: v }),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ["admin-markups"] }); toast.success("Tier price saved"); },
    onError: (e: Error) => toast.error(e.message),
  });
  const rows = data?.tier ?? [];
  const key = (t: string, c: string | null) => `${t}::${c ?? "*"}`;
  const map = new Map(rows.map((r) => [key(String(r.tier), r.category), { percent: Number(r.percent), flat: Number(r.flat) }]));
  const [tier, setTier] = useState<Tier>("bronze");

  return (
    <div className="rounded-2xl bg-card p-4 shadow-card">
      <h2 className="mb-1 font-semibold">Reseller tier pricing</h2>
      <p className="mb-3 text-xs text-muted-foreground">
        Overrides category markups for users on a tier. Use a negative percent to give resellers a discount. Leave a row at 0 to fall back to the category rule.
      </p>
      <div className="mb-3 flex flex-wrap gap-2">
        {TIERS.map((t) => (
          <button
            key={t}
            onClick={() => setTier(t)}
            className={`rounded-full px-3 py-1 text-xs font-semibold capitalize transition ${tier === t ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"}`}
          >
            {t}
          </button>
        ))}
      </div>
      <div className="grid gap-3 md:grid-cols-2">
        <CatRow
          key={`${tier}-all`}
          cat="all services"
          percent={map.get(key(tier, null))?.percent ?? 0}
          flat={map.get(key(tier, null))?.flat ?? 0}
          onSave={(percent, flat) => m.mutate({ tier, category: null, percent, flat })}
        />
        {CATS.map((c) => (
          <CatRow
            key={`${tier}-${c}`}
            cat={c}
            percent={map.get(key(tier, c))?.percent ?? 0}
            flat={map.get(key(tier, c))?.flat ?? 0}
            onSave={(percent, flat) => m.mutate({ tier, category: c, percent, flat })}
          />
        ))}
      </div>
    </div>
  );
}
