import { createFileRoute } from "@tanstack/react-router";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";
import {
  adminListServices, adminUpdateService,
  adminSyncCatalogues, adminListCatalogue, adminUpdateCatalogueItem,
  adminCreateCatalogueItem, adminDeleteCatalogueItem,
} from "@/lib/admin.functions";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { toast } from "sonner";
import { useState } from "react";

export const Route = createFileRoute("/admin/services")({
  component: AdminServices,
});

type Svc = {
  id: string;
  name: string;
  category: string;
  is_active: boolean;
  markup_percent: number | null;
  markup_flat: number | null;
  cashback_percent: number | null;
};

function AdminServices() {
  const qc = useQueryClient();
  const fetchSvcs = useServerFn(adminListServices);
  const update = useServerFn(adminUpdateService);
  const { data, isLoading } = useQuery({ queryKey: ["admin-services"], queryFn: () => fetchSvcs() });

  const m = useMutation({
    mutationFn: (vars: { id: string; is_active?: boolean; markup_percent?: number; markup_flat?: number; cashback_percent?: number }) => update({ data: vars }),
    onSuccess: () => { qc.invalidateQueries({ queryKey: ["admin-services"] }); toast.success("Saved"); },
    onError: (e: Error) => toast.error(e.message),
  });

  if (isLoading) return <p className="text-muted-foreground">Loading…</p>;
  if (!data?.length) return (
    <div className="space-y-5">
      <CatalogueSync />
      <p className="text-muted-foreground">No services yet — run a catalogue sync above.</p>
    </div>
  );

  return (
    <div className="space-y-5">
      <CatalogueSync />
      <div className="space-y-3">
        {(data as Svc[]).map((s) => <Row key={s.id} svc={s} onSave={(v) => m.mutate({ id: s.id, ...v })} />)}
      </div>
      <CatalogueTable kind="cable" title="Cable bouquets" />
      <CatalogueTable kind="exam" title="Exam products" />
    </div>
  );
}

function CatalogueSync() {
  const qc = useQueryClient();
  const sync = useServerFn(adminSyncCatalogues);
  const m = useMutation({
    mutationFn: (categories: Array<"cable" | "exam" | "airtime">) => sync({ data: { categories } }),
    onSuccess: (r) => {
      qc.invalidateQueries();
      const summary = Object.entries(r.result).map(([k, v]) => `${k}: ${v}`).join(" · ");
      toast.success(summary ? `Synced — ${summary}` : "Sync complete");
    },
    onError: (e: Error) => toast.error(e.message),
  });
  return (
    <div className="rounded-2xl bg-card p-4 shadow-card">
      <div className="text-sm font-semibold">Catalogue sync</div>
      <p className="mt-0.5 text-xs text-muted-foreground">
        Pull the latest airtime networks, cable bouquets and exam products. Your markups and cashback settings are preserved.
      </p>
      <div className="mt-3 flex flex-wrap gap-2">
        <Button size="sm" disabled={m.isPending} onClick={() => m.mutate(["airtime", "cable", "exam"])}>
          {m.isPending ? "Syncing…" : "Sync all"}
        </Button>
        <Button size="sm" variant="outline" disabled={m.isPending} onClick={() => m.mutate(["airtime"])}>Airtime</Button>
        <Button size="sm" variant="outline" disabled={m.isPending} onClick={() => m.mutate(["cable"])}>Cable</Button>
        <Button size="sm" variant="outline" disabled={m.isPending} onClick={() => m.mutate(["exam"])}>Exam</Button>
      </div>
    </div>
  );
}

type CatItem = {
  id: string; is_active: boolean; base_price: number;
  markup_percent: number; markup_flat: number; cashback_percent: number;
  cable_name?: string; plan_name?: string; exam_code?: string; exam_name?: string;
};

function CatalogueTable({ kind, title }: { kind: "cable" | "exam"; title: string }) {
  const qc = useQueryClient();
  const list = useServerFn(adminListCatalogue);
  const update = useServerFn(adminUpdateCatalogueItem);
  const create = useServerFn(adminCreateCatalogueItem);
  const remove = useServerFn(adminDeleteCatalogueItem);
  const { data } = useQuery({ queryKey: ["admin-catalogue", kind], queryFn: () => list({ data: { kind } }) });
  const refresh = () => qc.invalidateQueries({ queryKey: ["admin-catalogue", kind] });
  const m = useMutation({
    mutationFn: (vars: { id: string; markup_percent?: number; markup_flat?: number; cashback_percent?: number; is_active?: boolean }) =>
      update({ data: { kind, ...vars } }),
    onSuccess: () => { refresh(); toast.success("Saved"); },
    onError: (e: Error) => toast.error(e.message),
  });
  const del = useMutation({
    mutationFn: (id: string) => remove({ data: { kind, id } }),
    onSuccess: () => { refresh(); toast.success("Removed"); },
    onError: (e: Error) => toast.error(e.message),
  });

  const [name, setName] = useState("");
  const [planId, setPlanId] = useState("");
  const [group, setGroup] = useState(kind === "cable" ? "dstv" : "");
  const [price, setPrice] = useState("");
  const [newCb, setNewCb] = useState("0");

  const add = useMutation({
    mutationFn: () => create({
      data: {
        kind,
        name: name.trim(),
        plan_id: Number(planId),
        base_price: Number(price),
        cashback_percent: Number(newCb) || 0,
        markup_percent: 0,
        markup_flat: 0,
        ...(kind === "cable" ? { cable_name: group } : { exam_code: group || name.trim() }),
      },
    }),
    onSuccess: () => { refresh(); setName(""); setPlanId(""); setPrice(""); toast.success("Plan added"); },
    onError: (e: Error) => toast.error(e.message),
  });

  const items = (data ?? []) as unknown as CatItem[];

  return (
    <div className="rounded-2xl bg-card p-4 shadow-card">
      <div className="mb-2 text-sm font-semibold">{title} <span className="text-xs font-normal text-muted-foreground">({items.length})</span></div>

      <div className="mb-3 rounded-xl border border-dashed border-border p-2.5">
        <div className="mb-1.5 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground">Add new</div>
        <div className="grid grid-cols-2 gap-1.5 sm:grid-cols-5">
          {kind === "cable" ? (
            <select className="h-8 rounded-md border border-input bg-background px-2 text-xs" value={group} onChange={(e) => setGroup(e.target.value)}>
              <option value="dstv">DStv</option>
              <option value="gotv">GOtv</option>
              <option value="startimes">StarTimes</option>
            </select>
          ) : (
            <Input className="h-8 text-xs" value={group} onChange={(e) => setGroup(e.target.value)} placeholder="Exam code" />
          )}
          <Input className="h-8 text-xs" value={name} onChange={(e) => setName(e.target.value)} placeholder="Plan name" />
          <Input className="h-8 text-xs" type="number" value={planId} onChange={(e) => setPlanId(e.target.value)} placeholder="Provider plan ID" />
          <Input className="h-8 text-xs" type="number" value={price} onChange={(e) => setPrice(e.target.value)} placeholder="Cost price ₦" />
          <div className="flex gap-1.5">
            <Input className="h-8 text-xs" type="number" value={newCb} onChange={(e) => setNewCb(e.target.value)} placeholder="CB %" />
            <Button size="sm" className="h-8 shrink-0 text-xs" disabled={add.isPending || !name.trim() || !planId || !price} onClick={() => add.mutate()}>Add</Button>
          </div>
        </div>
      </div>

      {items.length === 0 ? (
        <p className="text-xs text-muted-foreground">No {kind} plans yet — add one above or run a catalogue sync.</p>
      ) : (
        <div className="max-h-80 space-y-2 overflow-y-auto pr-1">
          {items.map((it) => (
            <CatRow key={it.id} item={it} onSave={(v) => m.mutate({ id: it.id, ...v })} onDelete={() => del.mutate(it.id)} />
          ))}
        </div>
      )}
    </div>
  );
}

function CatRow({ item, onSave, onDelete }: { item: CatItem; onSave: (v: { markup_percent?: number; markup_flat?: number; cashback_percent?: number; is_active?: boolean }) => void; onDelete: () => void }) {
  const [pct, setPct] = useState(Number(item.markup_percent ?? 0));
  const [flat, setFlat] = useState(Number(item.markup_flat ?? 0));
  const [cb, setCb] = useState(Number(item.cashback_percent ?? 0));
  const label = item.plan_name ?? item.exam_name ?? "—";
  const sub = item.cable_name ?? item.exam_code ?? "";
  return (
    <div className="rounded-xl border border-border/60 p-2.5">
      <div className="flex items-center justify-between gap-2">
        <div className="min-w-0">
          <div className="truncate text-xs font-semibold">{label}</div>
          <div className="text-[10px] uppercase text-muted-foreground">{sub} · ₦{Number(item.base_price).toLocaleString()}</div>
        </div>
        <div className="flex shrink-0 gap-1.5">
          <Button size="sm" variant={item.is_active ? "outline" : "default"} onClick={() => onSave({ is_active: !item.is_active })}>
            {item.is_active ? "Disable" : "Enable"}
          </Button>
          <Button size="sm" variant="ghost" className="text-destructive" onClick={onDelete}>Delete</Button>
        </div>
      </div>
      <div className="mt-2 grid grid-cols-4 gap-1.5">
        <Input className="h-8 text-xs" type="number" step="0.01" value={pct} onChange={(e) => setPct(Number(e.target.value))} placeholder="%" />
        <Input className="h-8 text-xs" type="number" step="0.01" value={flat} onChange={(e) => setFlat(Number(e.target.value))} placeholder="Flat" />
        <Input className="h-8 text-xs" type="number" step="0.01" value={cb} onChange={(e) => setCb(Number(e.target.value))} placeholder="Cashback %" />
        <Button size="sm" className="h-8 text-xs" onClick={() => onSave({ markup_percent: pct, markup_flat: flat, cashback_percent: cb })}>Save</Button>
      </div>
    </div>
  );
}


function Row({ svc, onSave }: { svc: Svc; onSave: (v: { is_active?: boolean; markup_percent?: number; markup_flat?: number; cashback_percent?: number }) => void }) {
  const [pct, setPct] = useState(svc.markup_percent ?? 0);
  const [flat, setFlat] = useState(svc.markup_flat ?? 0);
  const [cb, setCb] = useState(svc.cashback_percent ?? 0);
  return (
    <div className="rounded-2xl bg-card p-4 shadow-card">
      <div className="flex items-center justify-between">
        <div>
          <div className="font-semibold">{svc.name}</div>
          <div className="text-xs uppercase text-muted-foreground">{svc.category}</div>
        </div>
        <Button size="sm" variant={svc.is_active ? "outline" : "default"} onClick={() => onSave({ is_active: !svc.is_active })}>
          {svc.is_active ? "Disable" : "Enable"}
        </Button>
      </div>
      <div className="mt-3 grid grid-cols-4 gap-2">
        <div>
          <label className="text-xs text-muted-foreground">% markup</label>
          <Input type="number" step="0.01" value={pct} onChange={(e) => setPct(Number(e.target.value))} />
        </div>
        <div>
          <label className="text-xs text-muted-foreground">Flat (₦)</label>
          <Input type="number" step="0.01" value={flat} onChange={(e) => setFlat(Number(e.target.value))} />
        </div>
        <div>
          <label className="text-xs text-muted-foreground">Cashback %</label>
          <Input type="number" step="0.01" min={0} max={50} value={cb} onChange={(e) => setCb(Number(e.target.value))} />
        </div>
        <div className="flex items-end">
          <Button className="w-full" onClick={() => onSave({ markup_percent: pct, markup_flat: flat, cashback_percent: cb })}>Save</Button>
        </div>
      </div>
    </div>
  );
}
