import { useState } from "react";
import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
import { useServerFn } from "@tanstack/react-start";
import { useQuery, useMutation, useQueryClient, queryOptions } from "@tanstack/react-query";
import {
  Activity, Copy, LogOut, Plus, RefreshCw, Router as RouterIcon, Trash2, Wallet, Wifi,
} from "lucide-react";
import { toast } from "sonner";

import { supabase } from "@/integrations/supabase/client";
import { BrandLogo } from "@/components/brand/brand-logo";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
import {
  Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter,
} from "@/components/ui/dialog";
import { Toaster } from "@/components/ui/sonner";
import { Badge } from "@/components/ui/badge";
import {
  getAdminOverview,
  upsertPlan, deletePlan,
  upsertRouter, deleteRouter, rotateRouterSecret,
  markPaymentPaid, promoteUser,
} from "@/lib/admin.functions";

const adminQuery = queryOptions({
  queryKey: ["admin", "overview"],
  queryFn: () => getAdminOverview(),
});

export const Route = createFileRoute("/_authenticated/admin")({
  head: () => ({
    meta: [
      { title: "Admin Console — BVANNY CONNECT" },
      { name: "robots", content: "noindex" },
    ],
  }),
  component: AdminPage,
});

function AdminPage() {
  const navigate = useNavigate();
  const qc = useQueryClient();
  const overviewFn = useServerFn(getAdminOverview);
  const { data, isLoading } = useQuery({
    queryKey: adminQuery.queryKey,
    queryFn: () => overviewFn(),
  });

  async function signOut() {
    await supabase.auth.signOut();
    navigate({ to: "/auth" });
  }

  if (isLoading || !data) {
    return (
      <main className="flex min-h-screen items-center justify-center">
        <div className="text-muted-foreground">Loading console…</div>
      </main>
    );
  }

  if (!data.isStaff) {
    return (
      <main className="flex min-h-screen items-center justify-center px-6">
        <div className="max-w-md text-center">
          <h1 className="font-display text-2xl font-bold">No console access</h1>
          <p className="mt-2 text-sm text-muted-foreground">
            Your account exists but hasn't been promoted to staff yet. Ask a super
            admin to grant you access.
          </p>
          <Button className="mt-6" onClick={signOut}>Sign out</Button>
        </div>
      </main>
    );
  }

  const stats = data.stats!;
  return (
    <main className="relative min-h-screen">
      <div aria-hidden className="pointer-events-none absolute inset-0 bg-grid opacity-30" />
      <header className="relative z-10 border-b border-border/60 bg-surface-1/40 backdrop-blur">
        <div className="mx-auto flex max-w-7xl items-center justify-between px-6 py-4">
          <div className="flex items-center gap-3">
            <BrandLogo variant="inline" size={36} compactWordmark />
            <span className="hidden text-xs font-medium text-muted-foreground sm:inline">
              Operator Console
            </span>
          </div>
          <div className="flex items-center gap-2">
            <Button variant="ghost" size="sm" asChild>
              <Link to="/portal">View portal</Link>
            </Button>
            <Button variant="outline" size="sm" onClick={signOut}>
              <LogOut className="mr-1.5 h-4 w-4" /> Sign out
            </Button>
          </div>
        </div>
      </header>

      <section className="relative z-10 mx-auto max-w-7xl px-6 py-10">
        <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
          <StatCard icon={<Activity className="h-4 w-4" />} label="Active users" value={stats.activeSubsCount} />
          <StatCard icon={<Wallet className="h-4 w-4" />} label="Revenue (KES)" value={stats.totalRevenue.toLocaleString()} />
          <StatCard icon={<Wifi className="h-4 w-4" />} label="Payments" value={stats.paymentsCount} />
          <StatCard icon={<RouterIcon className="h-4 w-4" />} label="Routers" value={data.routers.length} />
        </div>

        <Tabs defaultValue="plans" className="mt-10">
          <TabsList>
            <TabsTrigger value="plans">Plans</TabsTrigger>
            <TabsTrigger value="subs">Subscriptions</TabsTrigger>
            <TabsTrigger value="payments">Payments</TabsTrigger>
            <TabsTrigger value="routers">Routers</TabsTrigger>
            <TabsTrigger value="team">Team</TabsTrigger>
          </TabsList>

          <TabsContent value="plans"><PlansTab plans={data.plans} onChange={() => qc.invalidateQueries({ queryKey: adminQuery.queryKey })} /></TabsContent>
          <TabsContent value="subs"><SubscriptionsTab rows={data.subscriptions} /></TabsContent>
          <TabsContent value="payments"><PaymentsTab rows={data.payments} onChange={() => qc.invalidateQueries({ queryKey: adminQuery.queryKey })} /></TabsContent>
          <TabsContent value="routers"><RoutersTab rows={data.routers} onChange={() => qc.invalidateQueries({ queryKey: adminQuery.queryKey })} /></TabsContent>
          <TabsContent value="team"><TeamTab roles={data.roles} /></TabsContent>
        </Tabs>
      </section>
      <Toaster />
    </main>
  );
}

function StatCard({ icon, label, value }: { icon: React.ReactNode; label: string; value: React.ReactNode }) {
  return (
    <div className="glass rounded-2xl p-5">
      <div className="flex items-center gap-2 text-xs text-muted-foreground">{icon}{label}</div>
      <div className="mt-3 font-display text-3xl font-bold">{value}</div>
    </div>
  );
}

// -------- Plans --------
function PlansTab({ plans, onChange }: { plans: any[]; onChange: () => void }) {
  const upsert = useServerFn(upsertPlan);
  const del = useServerFn(deletePlan);
  const [editing, setEditing] = useState<any | null>(null);
  const [open, setOpen] = useState(false);

  function edit(p: any) { setEditing(p); setOpen(true); }
  function create() {
    setEditing({ name: "", price_kes: 10, duration_minutes: 60, download_kbps: 1000, upload_kbps: 1000, device_limit: 1, is_active: true, sort_order: (plans.length + 1) * 10, description: "" });
    setOpen(true);
  }

  return (
    <div className="mt-6">
      <div className="flex justify-end">
        <Button size="sm" onClick={create} className="gradient-brand text-primary-foreground">
          <Plus className="mr-1 h-4 w-4" /> New plan
        </Button>
      </div>
      <div className="mt-4 grid gap-3 md:grid-cols-2 lg:grid-cols-3">
        {plans.map((p) => (
          <div key={p.id} className="glass rounded-xl p-4">
            <div className="flex items-start justify-between">
              <div>
                <div className="font-semibold">{p.name}</div>
                <div className="text-xs text-muted-foreground">
                  KES {p.price_kes} · {p.duration_minutes} min
                </div>
              </div>
              <Badge variant={p.is_active ? "default" : "secondary"}>
                {p.is_active ? "Active" : "Off"}
              </Badge>
            </div>
            <div className="mt-3 text-xs text-muted-foreground">
              ↓ {p.download_kbps ?? "—"} · ↑ {p.upload_kbps ?? "—"} kbps · {p.device_limit ?? 1} device(s)
            </div>
            <div className="mt-4 flex gap-2">
              <Button size="sm" variant="outline" onClick={() => edit(p)}>Edit</Button>
              <Button
                size="sm" variant="ghost"
                onClick={async () => {
                  if (!confirm(`Delete plan "${p.name}"?`)) return;
                  const r = await del({ data: { id: p.id } });
                  if ((r as any).ok) { toast.success("Deleted"); onChange(); }
                  else toast.error((r as any).error);
                }}
              ><Trash2 className="h-4 w-4" /></Button>
            </div>
          </div>
        ))}
      </div>

      <Dialog open={open} onOpenChange={setOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>{editing?.id ? "Edit plan" : "New plan"}</DialogTitle>
          </DialogHeader>
          {editing && (
            <form
              className="space-y-3"
              onSubmit={async (e) => {
                e.preventDefault();
                const payload = { ...editing };
                ["price_kes","duration_minutes","download_kbps","upload_kbps","device_limit","sort_order"].forEach((k) => {
                  if (payload[k] !== null && payload[k] !== "" && payload[k] !== undefined) payload[k] = Number(payload[k]);
                });
                const r = await upsert({ data: payload });
                if ((r as any).ok) { toast.success("Saved"); setOpen(false); onChange(); }
                else toast.error((r as any).error);
              }}
            >
              <FormField label="Name"><Input value={editing.name} onChange={(e) => setEditing({ ...editing, name: e.target.value })} /></FormField>
              <div className="grid grid-cols-2 gap-3">
                <FormField label="Price (KES)"><Input type="number" value={editing.price_kes} onChange={(e) => setEditing({ ...editing, price_kes: e.target.value })} /></FormField>
                <FormField label="Duration (min)"><Input type="number" value={editing.duration_minutes} onChange={(e) => setEditing({ ...editing, duration_minutes: e.target.value })} /></FormField>
                <FormField label="Download kbps"><Input type="number" value={editing.download_kbps ?? ""} onChange={(e) => setEditing({ ...editing, download_kbps: e.target.value })} /></FormField>
                <FormField label="Upload kbps"><Input type="number" value={editing.upload_kbps ?? ""} onChange={(e) => setEditing({ ...editing, upload_kbps: e.target.value })} /></FormField>
                <FormField label="Devices"><Input type="number" value={editing.device_limit ?? 1} onChange={(e) => setEditing({ ...editing, device_limit: e.target.value })} /></FormField>
                <FormField label="Sort order"><Input type="number" value={editing.sort_order ?? 0} onChange={(e) => setEditing({ ...editing, sort_order: e.target.value })} /></FormField>
              </div>
              <FormField label="Description"><Textarea value={editing.description ?? ""} onChange={(e) => setEditing({ ...editing, description: e.target.value })} /></FormField>
              <label className="flex items-center gap-2 text-sm">
                <input type="checkbox" checked={!!editing.is_active} onChange={(e) => setEditing({ ...editing, is_active: e.target.checked })} />
                Active (visible on portal)
              </label>
              <DialogFooter>
                <Button type="submit" className="gradient-brand text-primary-foreground">Save</Button>
              </DialogFooter>
            </form>
          )}
        </DialogContent>
      </Dialog>
    </div>
  );
}

function FormField({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <div className="space-y-1">
      <Label>{label}</Label>
      {children}
    </div>
  );
}

// -------- Subs --------
function SubscriptionsTab({ rows }: { rows: any[] }) {
  return (
    <div className="glass mt-6 overflow-x-auto rounded-xl">
      <table className="w-full text-sm">
        <thead className="text-left text-xs uppercase text-muted-foreground">
          <tr><th className="p-3">Phone</th><th className="p-3">Plan</th><th className="p-3">Status</th><th className="p-3">Expires</th><th className="p-3">MAC</th></tr>
        </thead>
        <tbody>
          {rows.map((r) => (
            <tr key={r.id} className="border-t border-border/50">
              <td className="p-3">{r.phone}</td>
              <td className="p-3">{r.plan?.name ?? "—"}</td>
              <td className="p-3"><Badge variant={r.status === "active" ? "default" : "secondary"}>{r.status}</Badge></td>
              <td className="p-3 text-xs text-muted-foreground">{r.expires_at ? new Date(r.expires_at).toLocaleString() : "—"}</td>
              <td className="p-3 font-mono text-xs">{r.mac_address ?? "—"}</td>
            </tr>
          ))}
          {rows.length === 0 && <tr><td colSpan={5} className="p-6 text-center text-muted-foreground">No subscriptions yet</td></tr>}
        </tbody>
      </table>
    </div>
  );
}

// -------- Payments --------
function PaymentsTab({ rows, onChange }: { rows: any[]; onChange: () => void }) {
  const mark = useServerFn(markPaymentPaid);
  return (
    <div className="glass mt-6 overflow-x-auto rounded-xl">
      <table className="w-full text-sm">
        <thead className="text-left text-xs uppercase text-muted-foreground">
          <tr><th className="p-3">Time</th><th className="p-3">Phone</th><th className="p-3">Amount</th><th className="p-3">Status</th><th className="p-3">Receipt</th><th className="p-3"></th></tr>
        </thead>
        <tbody>
          {rows.map((p) => (
            <tr key={p.id} className="border-t border-border/50">
              <td className="p-3 text-xs">{new Date(p.created_at).toLocaleString()}</td>
              <td className="p-3">{p.phone}</td>
              <td className="p-3">KES {p.amount_kes}</td>
              <td className="p-3"><Badge variant={p.status === "success" ? "default" : p.status === "pending" ? "secondary" : "destructive"}>{p.status}</Badge></td>
              <td className="p-3 font-mono text-xs">{p.mpesa_receipt ?? "—"}</td>
              <td className="p-3 text-right">
                {p.status === "pending" && (
                  <Button size="sm" variant="outline" onClick={async () => {
                    if (!confirm("Mark this payment as paid and activate the subscription?")) return;
                    const r = await mark({ data: { payment_id: p.id } });
                    if ((r as any).ok) { toast.success("Payment confirmed"); onChange(); }
                    else toast.error((r as any).error);
                  }}>Mark paid</Button>
                )}
              </td>
            </tr>
          ))}
          {rows.length === 0 && <tr><td colSpan={6} className="p-6 text-center text-muted-foreground">No payments yet</td></tr>}
        </tbody>
      </table>
    </div>
  );
}

// -------- Routers --------
function RoutersTab({ rows, onChange }: { rows: any[]; onChange: () => void }) {
  const upsert = useServerFn(upsertRouter);
  const rotate = useServerFn(rotateRouterSecret);
  const del = useServerFn(deleteRouter);
  const [name, setName] = useState("");
  const [location, setLocation] = useState("");
  const [reveal, setReveal] = useState<{ id: string; secret: string } | null>(null);

  async function copy(v: string) {
    try { await navigator.clipboard.writeText(v); toast.success("Copied"); }
    catch { toast.error("Copy failed"); }
  }

  return (
    <div className="mt-6 space-y-6">
      <div className="glass rounded-xl p-4">
        <div className="text-sm font-semibold">Register a router</div>
        <form
          className="mt-3 flex flex-col gap-3 sm:flex-row"
          onSubmit={async (e) => {
            e.preventDefault();
            const r = await upsert({ data: { name, location } });
            if ((r as any).ok) {
              toast.success("Router added");
              if ((r as any).agent_secret) setReveal({ id: (r as any).id, secret: (r as any).agent_secret });
              setName(""); setLocation(""); onChange();
            } else toast.error((r as any).error);
          }}
        >
          <Input placeholder="Router name" value={name} onChange={(e) => setName(e.target.value)} required />
          <Input placeholder="Location" value={location} onChange={(e) => setLocation(e.target.value)} />
          <Button type="submit" className="gradient-brand text-primary-foreground"><Plus className="mr-1 h-4 w-4" /> Add</Button>
        </form>
      </div>

      <div className="grid gap-3 md:grid-cols-2">
        {rows.map((r) => (
          <div key={r.id} className="glass rounded-xl p-4">
            <div className="flex items-start justify-between">
              <div>
                <div className="font-semibold">{r.name}</div>
                <div className="text-xs text-muted-foreground">{r.location ?? "—"}</div>
              </div>
              <Badge variant={r.is_online ? "default" : "secondary"}>{r.is_online ? "Online" : "Offline"}</Badge>
            </div>
            <div className="mt-3 space-y-1 text-xs text-muted-foreground">
              <div>ID: <span className="font-mono text-foreground">{r.id}</span> <Button size="icon" variant="ghost" className="ml-1 h-6 w-6" onClick={() => copy(r.id)}><Copy className="h-3 w-3" /></Button></div>
              <div>Last seen: {r.last_seen_at ? new Date(r.last_seen_at).toLocaleString() : "never"}</div>
            </div>
            <div className="mt-4 flex gap-2">
              <Button size="sm" variant="outline" onClick={async () => {
                if (!confirm("Rotate agent secret? The router will need the new secret.")) return;
                const rr = await rotate({ data: { id: r.id } });
                if ((rr as any).ok) setReveal({ id: r.id, secret: (rr as any).agent_secret });
                else toast.error((rr as any).error);
              }}><RefreshCw className="mr-1 h-3 w-3" /> Rotate secret</Button>
              <Button size="sm" variant="ghost" onClick={async () => {
                if (!confirm(`Delete router "${r.name}"?`)) return;
                const rr = await del({ data: { id: r.id } });
                if ((rr as any).ok) { toast.success("Deleted"); onChange(); }
                else toast.error((rr as any).error);
              }}><Trash2 className="h-4 w-4" /></Button>
            </div>
          </div>
        ))}
        {rows.length === 0 && <div className="glass rounded-xl p-6 text-center text-muted-foreground">No routers yet</div>}
      </div>

      <Dialog open={!!reveal} onOpenChange={(v) => !v && setReveal(null)}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Router agent secret</DialogTitle>
            <DialogDescription>
              Copy this now — it won't be shown again. Configure it on your MikroTik agent.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-2">
            <Label>Router ID</Label>
            <div className="flex items-center gap-2"><Input readOnly value={reveal?.id ?? ""} /><Button size="icon" variant="outline" onClick={() => reveal && copy(reveal.id)}><Copy className="h-4 w-4" /></Button></div>
            <Label>Agent secret</Label>
            <div className="flex items-center gap-2"><Input readOnly value={reveal?.secret ?? ""} /><Button size="icon" variant="outline" onClick={() => reveal && copy(reveal.secret)}><Copy className="h-4 w-4" /></Button></div>
          </div>
          <DialogFooter>
            <Button onClick={() => setReveal(null)}>Done</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}

// -------- Team --------
function TeamTab({ roles }: { roles: string[] }) {
  const promote = useServerFn(promoteUser);
  const [email, setEmail] = useState("");
  const [role, setRole] = useState<"admin" | "operator" | "customer">("operator");
  const isSuper = roles.includes("super_admin");
  return (
    <div className="mt-6 space-y-4">
      <div className="glass rounded-xl p-4">
        <div className="text-sm font-semibold">Your roles</div>
        <div className="mt-2 flex flex-wrap gap-2">
          {roles.length === 0 ? <Badge variant="secondary">none</Badge> : roles.map((r) => <Badge key={r}>{r}</Badge>)}
        </div>
      </div>

      {isSuper ? (
        <form
          className="glass rounded-xl p-4"
          onSubmit={async (e) => {
            e.preventDefault();
            const r = await promote({ data: { email, role } });
            if ((r as any).ok) { toast.success(`Promoted ${email} to ${role}`); setEmail(""); }
            else toast.error((r as any).error);
          }}
        >
          <div className="text-sm font-semibold">Promote a user</div>
          <div className="mt-3 grid gap-3 sm:grid-cols-[1fr_180px_auto]">
            <Input placeholder="user@example.com" type="email" value={email} onChange={(e) => setEmail(e.target.value)} required />
            <select className="rounded-md border border-input bg-background px-3 py-2 text-sm" value={role} onChange={(e) => setRole(e.target.value as any)}>
              <option value="operator">operator</option>
              <option value="admin">admin</option>
              <option value="customer">customer</option>
            </select>
            <Button type="submit" className="gradient-brand text-primary-foreground">Promote</Button>
          </div>
          <p className="mt-2 text-xs text-muted-foreground">The first account created should be promoted to super_admin directly in the database.</p>
        </form>
      ) : (
        <div className="glass rounded-xl p-4 text-sm text-muted-foreground">
          Only super_admin can promote users. Ask an existing super_admin to grant you access.
        </div>
      )}
    </div>
  );
}
