"use client";

import React, { useState } from "react";
import { usePathname } from "next/navigation";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useTheme } from "next-themes";
import { toast } from "sonner";
import { cn } from "@/lib/utils";
import {
  Moon,
  Sun,
  Bell,
  Play,
  Square,
  RotateCcw,
  Loader2,
  ChevronDown,
  Settings,
  LogOut,
} from "lucide-react";
import { Button } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { authClient } from "@/lib/auth/client";
import { useRouter } from "next/navigation";

// ---------------------------------------------------------------------------
// Page title map
// ---------------------------------------------------------------------------
const PAGE_TITLES: Record<string, string> = {
  "/dashboard": "Dashboard",
  "/console": "Console",
  "/monitoring": "Monitoring",
  "/scheduler": "Scheduler",
  "/players": "Players",
  "/map": "World Map",
  "/plugins": "Plugins",
  "/files": "File Manager",
  "/backups": "Backups",
  "/settings": "Server Settings",
  "/updates": "Updates",
  "/team": "Team",
  "/audit": "Audit Log",
};

function usePageTitle(): string {
  const pathname = usePathname();
  // Exact match first
  if (PAGE_TITLES[pathname]) return PAGE_TITLES[pathname];
  // Find the longest matching prefix
  const match = Object.keys(PAGE_TITLES)
    .filter((key) => pathname.startsWith(key + "/"))
    .sort((a, b) => b.length - a.length)[0];
  return match ? PAGE_TITLES[match] : "CubeAdmin";
}

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------
interface ServerStatus {
  online: boolean;
  status: "online" | "offline" | "starting" | "stopping";
  playerCount?: number;
  maxPlayers?: number;
}

type ServerAction = "start" | "stop" | "restart";

// ---------------------------------------------------------------------------
// Status badge
// ---------------------------------------------------------------------------
function ServerStatusBadge({ status }: { status: ServerStatus | undefined }) {
  if (!status) {
    return (
      <span className="inline-flex items-center gap-1.5 rounded-full border border-zinc-700/50 bg-zinc-800/50 px-2 py-0.5 text-xs font-medium text-zinc-400">
        <span className="h-1.5 w-1.5 rounded-full bg-zinc-500" />
        Unknown
      </span>
    );
  }

  const config = {
    online: {
      dot: "bg-emerald-500",
      text: "Online",
      className: "border-emerald-500/20 bg-emerald-500/10 text-emerald-400",
    },
    offline: {
      dot: "bg-red-500",
      text: "Offline",
      className: "border-red-500/20 bg-red-500/10 text-red-400",
    },
    starting: {
      dot: "bg-yellow-500 animate-pulse",
      text: "Starting…",
      className: "border-yellow-500/20 bg-yellow-500/10 text-yellow-400",
    },
    stopping: {
      dot: "bg-orange-500 animate-pulse",
      text: "Stopping…",
      className: "border-orange-500/20 bg-orange-500/10 text-orange-400",
    },
  }[status.status];

  return (
    <span
      className={cn(
        "inline-flex items-center gap-1.5 rounded-full border px-2 py-0.5 text-xs font-medium",
        config.className
      )}
    >
      <span className={cn("h-1.5 w-1.5 rounded-full", config.dot)} />
      {config.text}
      {status.online && status.playerCount !== undefined && (
        <span className="text-[10px] opacity-70">
          {status.playerCount}/{status.maxPlayers}
        </span>
      )}
    </span>
  );
}

// ---------------------------------------------------------------------------
// Server action button with confirmation dialog
// ---------------------------------------------------------------------------
interface ActionButtonProps {
  action: ServerAction;
  disabled?: boolean;
  isLoading?: boolean;
  onConfirm: () => void;
  serverStatus: ServerStatus | undefined;
}

const ACTION_CONFIG: Record<
  ServerAction,
  {
    label: string;
    icon: React.ElementType;
    variant: "default" | "outline" | "destructive" | "ghost" | "secondary" | "link";
    confirmTitle: string;
    confirmDescription: string;
    confirmLabel: string;
    showWhen: (status: ServerStatus | undefined) => boolean;
  }
> = {
  start: {
    label: "Start",
    icon: Play,
    variant: "outline",
    confirmTitle: "Start the server?",
    confirmDescription:
      "This will start the Minecraft server. Players will be able to connect once it finishes booting.",
    confirmLabel: "Start Server",
    showWhen: (s) => !s || s.status === "offline",
  },
  stop: {
    label: "Stop",
    icon: Square,
    variant: "outline",
    confirmTitle: "Stop the server?",
    confirmDescription:
      "This will gracefully stop the server. All online players will be disconnected. Unsaved data will be saved first.",
    confirmLabel: "Stop Server",
    showWhen: (s) => s?.status === "online",
  },
  restart: {
    label: "Restart",
    icon: RotateCcw,
    variant: "outline",
    confirmTitle: "Restart the server?",
    confirmDescription:
      "This will gracefully restart the server. All online players will be temporarily disconnected.",
    confirmLabel: "Restart Server",
    showWhen: (s) => s?.status === "online",
  },
};

function ServerActionButton({
  action,
  disabled,
  isLoading,
  onConfirm,
  serverStatus,
}: ActionButtonProps) {
  const config = ACTION_CONFIG[action];
  const Icon = config.icon;
  const [open, setOpen] = useState(false);

  if (!config.showWhen(serverStatus)) return null;

  return (
    <AlertDialog open={open} onOpenChange={setOpen}>
      <AlertDialogTrigger
        disabled={disabled || isLoading}
        className={cn(
          "inline-flex shrink-0 items-center justify-center rounded-lg border text-xs font-medium h-7 gap-1.5 px-2.5 transition-all",
          action === "stop" &&
            "border-red-500/20 text-red-400 hover:bg-red-500/10 hover:border-red-500/30",
          action === "restart" &&
            "border-yellow-500/20 text-yellow-400 hover:bg-yellow-500/10 hover:border-yellow-500/30",
          action === "start" &&
            "border-emerald-500/20 text-emerald-400 hover:bg-emerald-500/10 hover:border-emerald-500/30"
        )}
      >
        {isLoading ? (
          <Loader2 className="h-3 w-3 animate-spin" />
        ) : (
          <Icon className="h-3 w-3" />
        )}
        {config.label}
      </AlertDialogTrigger>

      <AlertDialogContent>
        <AlertDialogHeader>
          <AlertDialogTitle>{config.confirmTitle}</AlertDialogTitle>
          <AlertDialogDescription>
            {config.confirmDescription}
          </AlertDialogDescription>
        </AlertDialogHeader>
        <AlertDialogFooter>
          <AlertDialogCancel>Cancel</AlertDialogCancel>
          <AlertDialogAction
            onClick={() => {
              setOpen(false);
              onConfirm();
            }}
            className={cn(
              action === "stop" &&
                "bg-red-600 hover:bg-red-700 text-white border-0",
              action === "restart" &&
                "bg-yellow-600 hover:bg-yellow-700 text-white border-0",
              action === "start" &&
                "bg-emerald-600 hover:bg-emerald-700 text-white border-0"
            )}
          >
            {config.confirmLabel}
          </AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
}

// ---------------------------------------------------------------------------
// Notifications bell
// ---------------------------------------------------------------------------
function NotificationBell() {
  // TODO: fetch real notification count from /api/notifications
  const count = 0;

  return (
    <Button
      variant="ghost"
      size="icon"
      className="relative h-8 w-8 text-zinc-400 hover:text-zinc-100"
      aria-label={`Notifications${count > 0 ? ` (${count} unread)` : ""}`}
    >
      <Bell className="h-4 w-4" />
      {count > 0 && (
        <span className="absolute -top-0.5 -right-0.5 flex h-4 w-4 items-center justify-center rounded-full bg-emerald-500 text-[9px] font-bold text-white ring-2 ring-[#0a0a0a]">
          {count > 9 ? "9+" : count}
        </span>
      )}
    </Button>
  );
}

// ---------------------------------------------------------------------------
// Theme toggle
// ---------------------------------------------------------------------------
function ThemeToggle() {
  const { resolvedTheme, setTheme } = useTheme();
  const isDark = resolvedTheme === "dark";

  return (
    <Button
      variant="ghost"
      size="icon"
      className="h-8 w-8 text-zinc-400 hover:text-zinc-100"
      onClick={() => setTheme(isDark ? "light" : "dark")}
      aria-label={`Switch to ${isDark ? "light" : "dark"} mode`}
    >
      {isDark ? <Sun className="h-4 w-4" /> : <Moon className="h-4 w-4" />}
    </Button>
  );
}

// ---------------------------------------------------------------------------
// User avatar dropdown (topbar version)
// ---------------------------------------------------------------------------
function UserMenu() {
  const router = useRouter();
  const { data: session } = useQuery({
    queryKey: ["session"],
    queryFn: async () => {
      const { data } = await authClient.getSession();
      return data;
    },
    staleTime: 5 * 60_000,
  });

  async function handleLogout() {
    await authClient.signOut();
    router.push("/login");
  }

  return (
    <DropdownMenu>
      <DropdownMenuTrigger className="flex items-center gap-1.5 rounded-md px-1.5 py-1 text-sm transition-colors hover:bg-white/[0.05] outline-none focus-visible:ring-2 focus-visible:ring-emerald-500/50">
        <div className="flex h-6 w-6 items-center justify-center rounded-full bg-emerald-600/30 ring-1 ring-emerald-500/20 flex-shrink-0">
          {session?.user?.image ? (
            // eslint-disable-next-line @next/next/no-img-element
            <img
              src={session.user.image}
              alt=""
              className="h-6 w-6 rounded-full object-cover"
            />
          ) : (
            <span className="text-[10px] font-semibold text-emerald-400">
              {(session?.user?.name ?? session?.user?.email ?? "?")
                .charAt(0)
                .toUpperCase()}
            </span>
          )}
        </div>
        <ChevronDown className="h-3 w-3 text-zinc-500" />
      </DropdownMenuTrigger>

      <DropdownMenuContent align="end" sideOffset={8} className="w-48">
        <DropdownMenuLabel className="font-normal">
          <div className="flex flex-col gap-0.5">
            <span className="text-sm font-medium">{session?.user?.name ?? "—"}</span>
            <span className="text-xs text-muted-foreground truncate">
              {session?.user?.email ?? "—"}
            </span>
          </div>
        </DropdownMenuLabel>
        <DropdownMenuSeparator />
        <DropdownMenuItem onClick={() => router.push("/settings")}>
          <Settings className="h-4 w-4" />
          Settings
        </DropdownMenuItem>
        <DropdownMenuSeparator />
        <DropdownMenuItem variant="destructive" onClick={handleLogout}>
          <LogOut className="h-4 w-4" />
          Sign out
        </DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

// ---------------------------------------------------------------------------
// Topbar
// ---------------------------------------------------------------------------
export function Topbar() {
  const title = usePageTitle();
  const queryClient = useQueryClient();

  const { data: serverStatus } = useQuery<ServerStatus>({
    queryKey: ["server-status"],
    queryFn: async () => {
      const res = await fetch("/api/server/status");
      if (!res.ok) return { online: false, status: "offline" as const };
      return res.json();
    },
    refetchInterval: 10_000,
    staleTime: 8_000,
  });

  const controlMutation = useMutation({
    mutationFn: async (action: ServerAction) => {
      const res = await fetch("/api/server/control", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ action }),
      });
      if (!res.ok) {
        const err = await res.json().catch(() => ({}));
        throw new Error(err.message ?? `Failed to ${action} server`);
      }
      return res.json();
    },
    onMutate: (action) => {
      toast.loading(`${capitalize(action)}ing server…`, {
        id: "server-control",
      });
    },
    onSuccess: (_data, action) => {
      toast.success(`Server ${action} command sent`, { id: "server-control" });
      // Refetch status after a short delay
      setTimeout(() => {
        queryClient.invalidateQueries({ queryKey: ["server-status"] });
      }, 2000);
    },
    onError: (err: Error, action) => {
      toast.error(`Failed to ${action} server: ${err.message}`, {
        id: "server-control",
      });
    },
  });

  const isOperating = controlMutation.isPending;

  return (
    <header className="flex h-14 flex-shrink-0 items-center justify-between border-b border-white/[0.06] bg-[#0a0a0a]/80 px-6 backdrop-blur-sm">
      {/* Left: page title */}
      <div className="flex items-center gap-4">
        <h1 className="text-sm font-semibold text-zinc-100">{title}</h1>
        <ServerStatusBadge status={serverStatus} />
      </div>

      {/* Right: controls */}
      <div className="flex items-center gap-1.5">
        {/* Server quick-actions */}
        <div className="mr-2 flex items-center gap-1.5">
          {(["start", "stop", "restart"] as ServerAction[]).map((action) => (
            <ServerActionButton
              key={action}
              action={action}
              serverStatus={serverStatus}
              disabled={isOperating}
              isLoading={isOperating && controlMutation.variables === action}
              onConfirm={() => controlMutation.mutate(action)}
            />
          ))}
        </div>

        <div className="h-5 w-px bg-white/[0.08]" />

        <NotificationBell />
        <ThemeToggle />
        <UserMenu />
      </div>
    </header>
  );
}

function capitalize(s: string) {
  return s.charAt(0).toUpperCase() + s.slice(1);
}
