"use client";

import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { 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 {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { PlayerAvatar } from "@/components/PlayerAvatar";

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

type Tab = "ops" | "whitelist" | "banned";

export function PlayerManager() {
  const queryClient = useQueryClient();
  const [tab, setTab] = useState<Tab>("ops");
  const [playerName, setPlayerName] = useState("");
  const [banReason, setBanReason] = useState("");

  const { data = { ops: [], whitelist: [], banned: [] } } = useQuery<PlayerData>({
    queryKey: ["players"],
    queryFn: async () => {
      const res = await fetch("/api/players");
      if (!res.ok) throw new Error("Failed to fetch players");
      return res.json();
    },
    staleTime: 10_000,
    refetchInterval: 15_000,
  });

  const action = useMutation({
    mutationFn: async (params: { action: string; player: string; reason?: string }) => {
      const res = await fetch("/api/players", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(params),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error);
      return data;
    },
    onMutate: async (params) => {
      await queryClient.cancelQueries({ queryKey: ["players"] });
      const prev = queryClient.getQueryData<PlayerData>(["players"]);
      if (prev) {
        const next: PlayerData = {
          ops: [...prev.ops],
          whitelist: [...prev.whitelist],
          banned: [...prev.banned],
        };
        const name = params.player;
        switch (params.action) {
          case "op":
            if (!next.ops.some((p) => p.name === name))
              next.ops.push({ name, uuid: "", level: 4 });
            break;
          case "deop":
            next.ops = next.ops.filter((p) => p.name !== name);
            break;
          case "whitelist add":
            if (!next.whitelist.some((p) => p.name === name))
              next.whitelist.push({ name, uuid: "" });
            break;
          case "whitelist remove":
            next.whitelist = next.whitelist.filter((p) => p.name !== name);
            break;
          case "ban":
            if (!next.banned.some((p) => p.name === name))
              next.banned.push({ name, uuid: "", reason: params.reason || "" });
            break;
          case "pardon":
            next.banned = next.banned.filter((p) => p.name !== name);
            break;
        }
        queryClient.setQueryData(["players"], next);
      }
      return { prev };
    },
    onSuccess: (data) => {
      toast.success(data.response || "Done");
      setPlayerName("");
      setBanReason("");
    },
    onError: (err, _vars, ctx) => {
      if (ctx?.prev) queryClient.setQueryData(["players"], ctx.prev);
      toast.error("Action failed", { description: err.message });
    },
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ["players"] });
    },
  });

  const tabs: { key: Tab; label: string; count: number }[] = [
    { key: "ops", label: "Operators", count: data.ops.length },
    { key: "whitelist", label: "Whitelist", count: data.whitelist.length },
    { key: "banned", label: "Banned", count: data.banned.length },
  ];

  const MC_NAME_RE = /^[A-Za-z0-9_]{3,16}$/;
  const trimmed = playerName.trim();
  const nameValid = MC_NAME_RE.test(trimmed);
  const nameError =
    trimmed.length === 0
      ? null
      : !nameValid
      ? "3–16 chars, letters/numbers/underscores only"
      : null;

  const handleAction = (act: string, player?: string) => {
    const name = player || trimmed;
    if (!name) return;
    if (!player && !nameValid) return;
    action.mutate({ action: act, player: name, reason: banReason || undefined });
  };

  return (
    <Card>
      <CardHeader>
        <CardTitle>Player Management</CardTitle>
        <CardDescription>
          Manage operators, whitelist, and bans via RCON
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-4">
        {/* Tabs */}
        <div className="flex gap-1 bg-muted p-1 rounded-lg">
          {tabs.map((t) => (
            <button
              key={t.key}
              onClick={() => setTab(t.key)}
              className={`flex-1 px-2 sm:px-3 py-2 rounded-md text-xs sm:text-sm font-medium transition min-h-[40px] ${
                tab === t.key
                  ? "bg-background text-foreground shadow-sm"
                  : "text-muted-foreground hover:text-foreground"
              }`}
            >
              {t.label}
              {t.count > 0 && (
                <Badge variant="secondary" className="ml-1.5 text-xs px-1.5 py-0">
                  {t.count}
                </Badge>
              )}
            </button>
          ))}
        </div>

        {/* Add player input */}
        <div className="flex flex-col sm:flex-row gap-2">
          <div className="flex-1">
            <Input
              placeholder="Player name"
              value={playerName}
              onChange={(e) => setPlayerName(e.target.value)}
              aria-invalid={!!nameError}
              maxLength={16}
              onKeyDown={(e) => {
                if (e.key === "Enter") {
                  if (tab === "ops") handleAction("op");
                  else if (tab === "whitelist") handleAction("whitelist add");
                  else if (tab === "banned") handleAction("ban");
                }
              }}
              className="w-full"
            />
            {nameError && (
              <p className="text-xs text-red-300 mt-1">{nameError}</p>
            )}
          </div>
          {tab === "banned" && (
            <Input
              placeholder="Reason (optional)"
              value={banReason}
              onChange={(e) => setBanReason(e.target.value)}
              className="flex-1"
            />
          )}
          <Button
            onClick={() => {
              if (tab === "ops") handleAction("op");
              else if (tab === "whitelist") handleAction("whitelist add");
              else if (tab === "banned") handleAction("ban");
            }}
            disabled={!nameValid || action.isPending}
            className="w-full sm:w-auto"
          >
            {tab === "ops" ? "Add OP" : tab === "whitelist" ? "Add" : "Ban"}
          </Button>
        </div>

        <Separator />

        {/* Player lists */}
        {tab === "ops" && (
          <ul className="space-y-1">
            {data.ops.length === 0 && (
              <li className="text-sm text-muted-foreground py-2 text-center">No operators</li>
            )}
            {data.ops.map((p) => (
              <li
                key={p.uuid || p.name}
                className="flex items-center justify-between gap-2 px-3 py-2 rounded-md bg-muted/50 group"
              >
                <div className="flex items-center gap-2 min-w-0">
                  <PlayerAvatar name={p.name} size={24} />
                  <span className="text-sm font-medium truncate">{p.name}</span>
                  <Badge variant="secondary" className="text-xs px-1.5 py-0 shrink-0">
                    Lv{p.level}
                  </Badge>
                </div>
                <Button
                  size="sm"
                  variant="ghost"
                  onClick={() => handleAction("deop", p.name)}
                  disabled={action.isPending}
                  className="text-xs h-9 shrink-0 text-muted-foreground sm:opacity-0 sm:group-hover:opacity-100 transition"
                >
                  Deop
                </Button>
              </li>
            ))}
          </ul>
        )}

        {tab === "whitelist" && (
          <ul className="space-y-1">
            {data.whitelist.length === 0 && (
              <li className="text-sm text-muted-foreground py-2 text-center">Whitelist is empty</li>
            )}
            {data.whitelist.map((p) => (
              <li
                key={p.uuid || p.name}
                className="flex items-center justify-between gap-2 px-3 py-2 rounded-md bg-muted/50 group"
              >
                <div className="flex items-center gap-2 min-w-0">
                  <PlayerAvatar name={p.name} size={24} />
                  <span className="text-sm font-medium truncate">{p.name}</span>
                </div>
                <Button
                  size="sm"
                  variant="ghost"
                  onClick={() => handleAction("whitelist remove", p.name)}
                  disabled={action.isPending}
                  className="text-xs h-9 text-muted-foreground sm:opacity-0 sm:group-hover:opacity-100 transition"
                >
                  Remove
                </Button>
              </li>
            ))}
          </ul>
        )}

        {tab === "banned" && (
          <ul className="space-y-1">
            {data.banned.length === 0 && (
              <li className="text-sm text-muted-foreground py-2 text-center">No banned players</li>
            )}
            {data.banned.map((p) => (
              <li
                key={p.uuid || p.name}
                className="flex items-center justify-between gap-2 px-3 py-2 rounded-md bg-muted/50 group"
              >
                <div className="min-w-0">
                  <div className="flex items-center gap-2">
                    <PlayerAvatar name={p.name} size={24} />
                    <span className="text-sm font-medium truncate">{p.name}</span>
                  </div>
                  {p.reason && (
                    <p className="text-xs text-muted-foreground truncate ml-8">{p.reason}</p>
                  )}
                </div>
                <Button
                  size="sm"
                  variant="ghost"
                  onClick={() => handleAction("pardon", p.name)}
                  disabled={action.isPending}
                  className="text-xs h-9 text-muted-foreground sm:opacity-0 sm:group-hover:opacity-100 transition"
                >
                  Unban
                </Button>
              </li>
            ))}
          </ul>
        )}
      </CardContent>
    </Card>
  );
}
