"use client";

import { usePoll } from "@/lib/use-poll";
import { StatCard } from "@/components/stat-card";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { StatusBadge } from "@/components/status-badge";
import { Badge } from "@/components/ui/badge";
import { DataTable, Column } from "@/components/data-table";
import type { CloudflareStats, AuthentikStats, GiteaActivity } from "@/lib/types";
import { CardSkeleton } from "@/components/skeleton";
import { Copyable } from "@/components/copyable";

interface AdGuardStats {
  total_queries?: number;
  num_dns_queries?: number;
  blocked?: number;
  num_blocked_filtering?: number;
  avg_time?: number;
  avg_processing_time?: number;
}

interface HeadscaleNode {
  id: string;
  name: string;
  ip_addresses?: string[];
  ip?: string;
  online: boolean;
  last_seen?: string;
}

interface DnsRewrite {
  domain: string;
  answer: string;
}

const nodeColors: Record<string, string> = {
  atlantis: "text-blue-400",
  calypso: "text-violet-400",
  olares: "text-emerald-400",
  nuc: "text-amber-400",
  rpi5: "text-cyan-400",
  "homelab-vm": "text-green-400",
  "matrix-ubuntu": "text-pink-400",
  guava: "text-orange-400",
  seattle: "text-teal-400",
  jellyfish: "text-indigo-400",
};

function getNodeColor(name: string): string {
  const lower = name.toLowerCase();
  for (const [key, cls] of Object.entries(nodeColors)) {
    if (lower.includes(key)) return cls;
  }
  return "text-foreground";
}

function formatTime(ts: string): string {
  try {
    return new Date(ts).toLocaleString("en-US", {
      month: "short",
      day: "numeric",
      hour: "2-digit",
      minute: "2-digit",
    });
  } catch {
    return ts;
  }
}

const dnsTypeColors: Record<string, string> = {
  A: "text-blue-400",
  AAAA: "text-violet-400",
  CNAME: "text-cyan-400",
  MX: "text-amber-400",
  TXT: "text-green-400",
  SRV: "text-pink-400",
  NS: "text-teal-400",
};

export default function NetworkPage() {
  const { data: adguard } = usePoll<AdGuardStats>("/api/network/adguard", 60000);
  const { data: nodesRaw } = usePoll<HeadscaleNode[] | { nodes: HeadscaleNode[] }>("/api/network/headscale", 30000);
  const { data: rewritesRaw } = usePoll<DnsRewrite[] | { rewrites: DnsRewrite[] }>("/api/network/adguard/rewrites", 120000);
  const { data: cloudflare } = usePoll<CloudflareStats>("/api/network/cloudflare", 120000);
  const { data: authentik } = usePoll<AuthentikStats & { users?: Array<{ username: string; last_login: string; active: boolean }> }>("/api/network/authentik", 60000);
  const { data: gitea } = usePoll<GiteaActivity>("/api/network/gitea", 60000);

  const nodes = Array.isArray(nodesRaw) ? nodesRaw : (nodesRaw?.nodes ?? []);
  const rewrites = Array.isArray(rewritesRaw) ? rewritesRaw : (rewritesRaw?.rewrites ?? []);

  const rewriteColumns: Column<DnsRewrite>[] = [
    {
      key: "domain",
      label: "Domain",
      render: (row) => <span className="font-medium text-cyan-400">{row.domain}</span>,
    },
    {
      key: "answer",
      label: "Answer",
      render: (row) => <Copyable text={row.answer} className="text-amber-400 font-mono" />,
    },
  ];

  return (
    <div className="space-y-8">
      <h1 className="text-lg font-semibold">Network</h1>

      {/* Top row: AdGuard stats */}
      <div className="grid grid-cols-1 sm:grid-cols-3 lg:grid-cols-3 gap-5">
        <StatCard
          label="Total Queries"
          value={(() => { const v = adguard?.total_queries ?? adguard?.num_dns_queries; return v != null ? v.toLocaleString() : "--"; })()}
          sub="DNS queries"
        />
        <StatCard
          label="Blocked"
          value={(() => { const v = adguard?.blocked ?? adguard?.num_blocked_filtering; return v != null ? v.toLocaleString() : "--"; })()}
          sub="blocked by filters"
        />
        <StatCard
          label="Avg Response"
          value={(() => { const v = adguard?.avg_time ?? adguard?.avg_processing_time; return v != null ? `${(v * 1000).toFixed(1)}ms` : "--"; })()}
          sub="processing time"
        />
      </div>

      {/* Middle: Headscale nodes grid */}
      <Card>
        <CardHeader className="pb-2 flex flex-row items-center justify-between">
          <CardTitle className="text-base font-semibold text-cyan-400">Headscale Nodes</CardTitle>
          {nodes.length > 0 && (
            <Badge variant="secondary" className="text-xs bg-cyan-500/10 border border-cyan-500/20 text-cyan-400">
              {nodes.filter(n => n.online).length}/{nodes.length} online
            </Badge>
          )}
        </CardHeader>
        <CardContent>
          {nodes.length === 0 ? (
            (nodesRaw as Record<string,unknown>)?.error ? <p className="text-sm text-red-400">{String((nodesRaw as Record<string,unknown>).error)}</p> : <CardSkeleton lines={4} />
          ) : (
            <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4">
              {nodes.map((node) => (
                <Card key={node.id} className="overflow-hidden">
                  <CardContent className="pt-3 pb-3 px-4">
                    <div className="flex items-center gap-2 mb-1">
                      <span className={`w-2 h-2 rounded-full shrink-0 ${node.online ? "bg-green-500 glow-green" : "bg-red-500 glow-red"}`} />
                      <span className={`text-sm font-medium truncate ${getNodeColor(node.name)}`}>{node.name}</span>
                    </div>
                    <p className="text-xs text-muted-foreground/70 font-mono">
                      <Copyable text={node.ip_addresses?.[0] ?? node.ip ?? "--"} />
                    </p>
                    {node.last_seen && (
                      <p className="text-xs text-muted-foreground/60 mt-0.5">
                        {new Date(node.last_seen).toLocaleString("en-US", {
                          month: "short", day: "numeric", hour: "2-digit", minute: "2-digit",
                        })}
                      </p>
                    )}
                  </CardContent>
                </Card>
              ))}
            </div>
          )}
        </CardContent>
      </Card>

      {/* Cloudflare DNS — full width */}
      <Card>
        <CardHeader className="pb-2 flex flex-row items-center justify-between">
          <CardTitle className="text-base font-semibold text-orange-400">Cloudflare DNS</CardTitle>
          <div className="flex items-center gap-2">
            {cloudflare && (
              <>
                <Badge variant="secondary" className="text-xs bg-orange-500/10 border border-orange-500/20 text-orange-400">
                  {cloudflare.proxied} proxied
                </Badge>
                <Badge variant="secondary" className="text-xs bg-white/[0.06] border border-white/[0.08] text-muted-foreground">
                  {cloudflare.dns_only} DNS only
                </Badge>
                <Badge variant="secondary" className="text-xs bg-white/[0.04] border border-white/[0.06]">
                  {cloudflare.total} total
                </Badge>
              </>
            )}
          </div>
        </CardHeader>
        <CardContent>
          {!cloudflare ? (
            <CardSkeleton lines={6} />
          ) : (
            <div className="space-y-4">
              {/* Type badges */}
              <div className="flex flex-wrap gap-2">
                {Object.entries(cloudflare.types).map(([type, count]) => (
                  <Badge
                    key={type}
                    variant="secondary"
                    className={`text-xs bg-white/[0.04] border border-white/[0.08] ${dnsTypeColors[type] ?? "text-foreground"}`}
                  >
                    {type}: {count}
                  </Badge>
                ))}
              </div>
              {/* Records table */}
              {(cloudflare as CloudflareStats & { records?: { name: string; type: string; content: string; proxied: boolean; ttl: number }[] }).records && (
                <div className="rounded-lg border border-white/[0.06] overflow-hidden">
                  <table className="w-full text-sm">
                    <thead>
                      <tr className="bg-white/[0.04] text-xs text-muted-foreground uppercase tracking-wider">
                        <th className="text-left px-3 py-2 font-medium">Name</th>
                        <th className="text-left px-3 py-2 font-medium w-16">Type</th>
                        <th className="text-left px-3 py-2 font-medium">Content</th>
                        <th className="text-center px-3 py-2 font-medium w-20">Proxy</th>
                      </tr>
                    </thead>
                    <tbody>
                      {((cloudflare as CloudflareStats & { records?: { name: string; type: string; content: string; proxied: boolean; ttl: number }[] }).records ?? []).map((rec, i) => (
                        <tr key={i} className="border-t border-white/[0.04] hover:bg-white/[0.03] transition-colors">
                          <td className="px-3 py-1.5 text-cyan-400 font-mono text-xs truncate max-w-[220px]">{rec.name}</td>
                          <td className="px-3 py-1.5">
                            <span className={`text-xs font-medium ${dnsTypeColors[rec.type] ?? ""}`}>{rec.type}</span>
                          </td>
                          <td className="px-3 py-1.5 text-amber-400/80 font-mono text-xs truncate max-w-[200px]"><Copyable text={rec.content} /></td>
                          <td className="px-3 py-1.5 text-center">
                            {rec.proxied ? (
                              <span className="inline-block w-2 h-2 rounded-full bg-orange-400" style={{ boxShadow: "0 0 6px rgba(251,146,60,0.5)" }} title="Proxied" />
                            ) : (
                              <span className="inline-block w-2 h-2 rounded-full bg-gray-500" title="DNS Only" />
                            )}
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              )}
            </div>
          )}
        </CardContent>
      </Card>

      {/* Authentik, Gitea -- 2 columns */}
      <div className="grid grid-cols-1 md:grid-cols-2 gap-5">

        {/* Authentik SSO */}
        <Card>
          <CardHeader className="pb-2 flex flex-row items-center justify-between">
            <CardTitle className="text-base font-semibold text-violet-400">Authentik SSO</CardTitle>
            {authentik && (
              <Badge variant="secondary" className="text-xs bg-violet-500/10 border border-violet-500/20 text-violet-400">
                {authentik.active_sessions} sessions
              </Badge>
            )}
          </CardHeader>
          <CardContent>
            {!authentik ? (
              <CardSkeleton lines={4} />
            ) : (
              <div className="space-y-4">
                {/* Users */}
                {authentik.users && authentik.users.length > 0 && (
                  <div>
                    <p className="text-xs uppercase tracking-wider text-muted-foreground/70 font-medium mb-2">Users</p>
                    <div className="space-y-2">
                      {authentik.users.map((u, i) => (
                        <div key={i} className="flex items-center justify-between text-sm">
                          <div className="flex items-center gap-2">
                            <StatusBadge color={u.active ? "green" : "red"} />
                            <span className="text-violet-400 font-medium">{u.username}</span>
                          </div>
                          <span className="text-xs text-muted-foreground/60">
                            {u.last_login === "never" ? "never" : u.last_login.slice(0, 10)}
                          </span>
                        </div>
                      ))}
                    </div>
                  </div>
                )}
                {(authentik.recent_events ?? []).length > 0 && (
                  <div>
                    <p className="text-xs uppercase tracking-wider text-muted-foreground/70 font-medium mb-2">Recent Events</p>
                    <div className="space-y-2">
                      {(authentik.recent_events ?? []).slice(0, 6).map((evt, i) => (
                        <div key={i} className="flex items-center justify-between text-sm">
                          <div className="flex items-center gap-2 min-w-0">
                            <StatusBadge
                              color={String(evt.action).includes("login") ? "green" : String(evt.action).includes("fail") ? "red" : "blue"}
                              label={String(evt.action)}
                            />
                            <span className="text-xs text-muted-foreground/60 truncate">{String(evt.user ?? "")}</span>
                          </div>
                          <span className="text-xs text-muted-foreground/50 shrink-0 ml-2">
                            {String(evt.created ?? "").slice(11, 16)}
                          </span>
                        </div>
                      ))}
                    </div>
                  </div>
                )}
                {(authentik.recent_events ?? []).length === 0 && !(authentik.users?.length) && (
                  <p className="text-sm text-muted-foreground/60">No recent activity</p>
                )}
              </div>
            )}
          </CardContent>
        </Card>

        {/* Gitea Activity */}
        <Card>
          <CardHeader className="pb-2 flex flex-row items-center justify-between">
            <CardTitle className="text-base font-semibold text-green-400">Gitea</CardTitle>
            {gitea && gitea.open_prs.length > 0 && (
              <Badge variant="secondary" className="text-xs bg-green-500/10 border border-green-500/20 text-green-400">
                {gitea.open_prs.length} open PR{gitea.open_prs.length !== 1 ? "s" : ""}
              </Badge>
            )}
          </CardHeader>
          <CardContent>
            {!gitea ? (
              <CardSkeleton lines={4} />
            ) : (
              <div className="space-y-4">
                {gitea.commits.length > 0 && (
                  <div>
                    <p className="text-xs uppercase tracking-wider text-muted-foreground/70 font-medium mb-2">Recent Commits</p>
                    <div className="space-y-2">
                      {gitea.commits.slice(0, 6).map((c, i) => (
                        <div key={i} className="text-sm">
                          <div className="flex items-center gap-2">
                            <span className="text-amber-400 font-mono text-xs shrink-0">{c.sha.slice(0, 7)}</span>
                            <span className="text-foreground truncate">{c.message.split("\n")[0]}</span>
                          </div>
                          <div className="flex items-center gap-2 mt-0.5">
                            <span className="text-xs text-muted-foreground/60">{c.author}</span>
                            <span className="text-xs text-muted-foreground/40">{formatTime(c.date)}</span>
                          </div>
                        </div>
                      ))}
                    </div>
                  </div>
                )}
                {gitea.open_prs.length > 0 && (
                  <div>
                    <p className="text-xs uppercase tracking-wider text-muted-foreground/70 font-medium mb-2">Open PRs</p>
                    <div className="space-y-1.5">
                      {gitea.open_prs.map((pr, i) => (
                        <div key={i} className="flex items-center justify-between text-sm">
                          <div className="flex items-center gap-2 min-w-0">
                            <span className="text-green-400 font-mono text-xs shrink-0">#{pr.number}</span>
                            <span className="text-foreground truncate">{pr.title}</span>
                          </div>
                          <span className="text-xs text-muted-foreground/60 shrink-0 ml-2">{pr.author}</span>
                        </div>
                      ))}
                    </div>
                  </div>
                )}
              </div>
            )}
          </CardContent>
        </Card>
      </div>

      {/* Bottom: DNS rewrites table */}
      <Card>
        <CardHeader className="pb-2">
          <CardTitle className="text-base font-semibold">DNS Rewrites</CardTitle>
        </CardHeader>
        <CardContent>
          <DataTable<DnsRewrite>
            data={rewrites}
            columns={rewriteColumns}
            searchKey="domain"
          />
        </CardContent>
      </Card>
    </div>
  );
}
