"use client";

import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useSession } from "next-auth/react";
import { useEffect, useState } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import { Separator } from "@/components/ui/separator";
import { PlayerAvatar } from "@/components/PlayerAvatar";
import { onAppEvent } from "@/lib/events";
import { formatHours, timeAgo } from "@/lib/time";
import type { PlaytimeEntry } from "@/components/PlaytimeLeaderboard";

type PlayerData = {
  ops: { name: string; uuid: string; level: number }[];
  whitelist: { name: string; uuid: string }[];
  banned: { name: string; uuid: string; reason: string }[];
};

type MetricEntry = { ts: string; players?: string[] };

export function PlayerDrawer() {
  const { data: session } = useSession();
  const queryClient = useQueryClient();
  const [name, setName] = useState<string | null>(null);
  const [banReason, setBanReason] = useState("");

  useEffect(() => onAppEvent("player:open", ({ name }) => setName(name)), []);

  useEffect(() => {
    if (!name) return;
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "Escape") setName(null);
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [name]);

  const authed = !!session;

  const players = useQuery<PlayerData>({
    queryKey: ["players"],
    queryFn: () => fetch("/api/players").then((r) => r.json()),
    enabled: authed && !!name,
    staleTime: 10_000,
  });

  const playtime = useQuery<PlaytimeEntry[]>({
    queryKey: ["players-playtime"],
    queryFn: () => fetch("/api/players/playtime").then((r) => r.json()),
    enabled: authed && !!name,
    staleTime: 60_000,
  });

  const myPlaytime = name
    ? playtime.data?.find((p) => p.name === name)
    : undefined;

  // Use existing analytics cache (last entry) to determine online now
  const analytics = queryClient.getQueryData<MetricEntry[]>(["analytics", 6]);
  const onlineNow =
    (analytics && analytics.length > 0
      ? analytics[analytics.length - 1].players || []
      : []) as string[];

  const isOp = !!name && !!players.data?.ops.some((p) => p.name === name);
  const isWhitelisted =
    !!name && !!players.data?.whitelist.some((p) => p.name === name);
  const bannedEntry =
    (name && players.data?.banned.find((p) => p.name === name)) || null;
  const isBanned = !!bannedEntry;
  const isOnline = !!name && onlineNow.includes(name);

  const action = useMutation({
    mutationFn: async (params: { action: string; reason?: string }) => {
      if (!name) throw new Error("No player selected");
      const res = await fetch("/api/players", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ action: params.action, player: name, reason: params.reason }),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error);
      return data;
    },
    onSuccess: (data) => {
      toast.success(data.response || "Done");
      setBanReason("");
      queryClient.invalidateQueries({ queryKey: ["players"] });
    },
    onError: (err) => toast.error("Action failed", { description: err.message }),
  });

  if (!name) return null;

  return (
    <div
      className="fixed inset-0 z-40 flex justify-end bg-black/40 backdrop-blur-[2px]"
      role="dialog"
      aria-modal="true"
      aria-label={`Profile for ${name}`}
      onClick={(e) => {
        if (e.target === e.currentTarget) setName(null);
      }}
    >
      <aside className="h-full w-full sm:max-w-sm bg-card border-l border-border shadow-2xl flex flex-col animate-in slide-in-from-right duration-150">
        <header className="p-4 border-b border-border flex items-start gap-3">
          <PlayerAvatar name={name} size={48} interactive={false} />
          <div className="min-w-0 flex-1">
            <h2 className="text-base font-semibold truncate">{name}</h2>
            <div className="flex items-center gap-1.5 mt-1 flex-wrap">
              {isOnline && (
                <Badge className="text-xs px-1.5 py-0 bg-emerald-500/20 text-emerald-300 border border-emerald-500/30">
                  Online
                </Badge>
              )}
              {isOp && (
                <Badge variant="secondary" className="text-xs px-1.5 py-0">
                  Op
                </Badge>
              )}
              {isWhitelisted && (
                <Badge variant="secondary" className="text-xs px-1.5 py-0">
                  Whitelisted
                </Badge>
              )}
              {isBanned && (
                <Badge
                  variant="outline"
                  className="text-xs px-1.5 py-0 border-red-500/40 text-red-300"
                >
                  Banned
                </Badge>
              )}
              {!isOp && !isWhitelisted && !isBanned && (
                <span className="text-xs text-muted-foreground">No roles</span>
              )}
            </div>
          </div>
          <Button
            variant="ghost"
            size="sm"
            aria-label="Close"
            onClick={() => setName(null)}
            className="shrink-0"
          >
            ✕
          </Button>
        </header>

        <div className="flex-1 overflow-y-auto p-4 space-y-4">
          {!authed ? (
            <p className="text-sm text-muted-foreground">
              Log in as admin to manage this player.
            </p>
          ) : (
            <>
              {myPlaytime && (
                <div className="grid grid-cols-2 gap-3">
                  <div className="rounded-md bg-muted p-3">
                    <p className="text-xs text-muted-foreground">Playtime</p>
                    <p className="text-lg font-bold tabular-nums">
                      {formatHours(myPlaytime.playtimeHours)}
                    </p>
                  </div>
                  <div className="rounded-md bg-muted p-3">
                    <p className="text-xs text-muted-foreground">Last seen</p>
                    <p
                      className="text-sm font-medium"
                      title={new Date(myPlaytime.lastPlayedMs).toLocaleString()}
                    >
                      {timeAgo(myPlaytime.lastPlayedMs)}
                    </p>
                  </div>
                </div>
              )}

              {bannedEntry?.reason && (
                <div>
                  <p className="text-xs font-semibold text-muted-foreground uppercase tracking-wide mb-1">
                    Ban reason
                  </p>
                  <p className="text-sm text-red-300 break-words">
                    {bannedEntry.reason}
                  </p>
                </div>
              )}

              <div className="grid grid-cols-2 gap-2">
                <Button
                  variant={isOp ? "outline" : "default"}
                  onClick={() =>
                    action.mutate({ action: isOp ? "deop" : "op" })
                  }
                  disabled={action.isPending}
                  className="text-sm"
                >
                  {isOp ? "Deop" : "Make Op"}
                </Button>
                <Button
                  variant={isWhitelisted ? "outline" : "default"}
                  onClick={() =>
                    action.mutate({
                      action: isWhitelisted ? "whitelist remove" : "whitelist add",
                    })
                  }
                  disabled={action.isPending}
                  className="text-sm"
                >
                  {isWhitelisted ? "Remove whitelist" : "Add to whitelist"}
                </Button>
              </div>

              <Separator />

              <div className="space-y-2">
                <p className="text-xs font-semibold text-muted-foreground uppercase tracking-wide">
                  {isBanned ? "Ban" : "Ban player"}
                </p>
                {isBanned ? (
                  <Button
                    variant="outline"
                    onClick={() => action.mutate({ action: "pardon" })}
                    disabled={action.isPending}
                    className="w-full"
                  >
                    Pardon
                  </Button>
                ) : (
                  <>
                    <Input
                      placeholder="Reason (optional)"
                      value={banReason}
                      onChange={(e) => setBanReason(e.target.value)}
                      className="h-9 text-sm"
                    />
                    <Button
                      variant="destructive"
                      onClick={() =>
                        action.mutate({ action: "ban", reason: banReason || undefined })
                      }
                      disabled={action.isPending}
                      className="w-full"
                    >
                      Ban {name}
                    </Button>
                  </>
                )}
              </div>

              <Separator />

              <div className="text-xs text-muted-foreground space-y-1">
                <p>
                  <span className="text-foreground font-medium">UUID:</span>{" "}
                  <span className="font-mono break-all">
                    {players.data?.ops.find((p) => p.name === name)?.uuid ||
                      players.data?.whitelist.find((p) => p.name === name)?.uuid ||
                      players.data?.banned.find((p) => p.name === name)?.uuid ||
                      myPlaytime?.uuid ||
                      "—"}
                  </span>
                </p>
                <p>
                  Actions use RCON on the live server. Some commands take a
                  moment to reflect.
                </p>
              </div>
            </>
          )}
        </div>
      </aside>
    </div>
  );
}
