"use client";

import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useState } from "react";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { Alert, AlertDescription } from "@/components/ui/alert";
import { Separator } from "@/components/ui/separator";
import { Skeleton } from "@/components/ui/skeleton";
import { ScheduledTasks } from "@/components/ScheduledTasks";
import { StatusBadge, statusFromServer } from "@/components/StatusBadge";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";

type ServerStatus = {
  online: boolean;
  starting?: boolean;
  players: { online: number; max: number };
  version?: string;
  motd?: string;
};

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

const ACTION_LABEL: Record<Action, string> = {
  start: "Start",
  stop: "Stop",
  restart: "Restart",
};

export function ServerControls() {
  const queryClient = useQueryClient();
  const [confirm, setConfirm] = useState<Action | null>(null);

  const { data: status, isLoading } = useQuery<ServerStatus>({
    queryKey: ["status"],
    queryFn: () => fetch("/api/status").then((r) => r.json()),
    refetchInterval: 60_000,
    staleTime: 5000,
  });

  const action = useMutation({
    mutationFn: async (act: Action) => {
      const res = await fetch(`/api/server/${act}`, { method: "POST" });
      if (!res.ok) {
        const data = await res.json();
        throw new Error(data.error || "Request failed");
      }
      return { ...(await res.json()), act };
    },
    onSuccess: (_, act) => {
      toast.success(`${ACTION_LABEL[act]} command sent`, {
        description: "Status will update in a few seconds.",
      });
      setTimeout(
        () => queryClient.invalidateQueries({ queryKey: ["status"] }),
        3000
      );
    },
    onError: (err, act) => {
      toast.error(`${ACTION_LABEL[act]} failed`, { description: err.message });
    },
  });

  const isOnline = status?.online ?? false;

  const trigger = (act: Action) => {
    if (act === "start") {
      action.mutate(act);
    } else {
      setConfirm(act);
    }
  };

  const confirmRun = () => {
    if (confirm) {
      action.mutate(confirm);
      setConfirm(null);
    }
  };

  return (
    <Card>
      <CardHeader>
        <div className="flex items-center justify-between gap-2">
          <div className="min-w-0">
            <CardTitle>Server Controls</CardTitle>
            <CardDescription className="hidden sm:block">Manage the Minecraft server process</CardDescription>
          </div>
          {isLoading || !status ? (
            <Skeleton className="h-5 w-20" />
          ) : (
            <StatusBadge status={statusFromServer(status)} />
          )}
        </div>
      </CardHeader>
      <CardContent className="space-y-4">
        {/* Stats row */}
        <div className="grid grid-cols-1 sm:grid-cols-3 gap-2 sm:gap-3">
          <div className="rounded-lg bg-muted p-3 text-center">
            <p className="text-xs text-muted-foreground mb-0.5">Players</p>
            {isLoading || !status ? (
              <Skeleton className="h-7 w-12 mx-auto" />
            ) : (
              <p className="text-xl font-bold tabular-nums">
                {isOnline ? `${status.players.online}/${status.players.max}` : "-"}
              </p>
            )}
          </div>
          <div className="rounded-lg bg-muted p-3 text-center">
            <p className="text-xs text-muted-foreground mb-0.5">Version</p>
            {isLoading || !status ? (
              <Skeleton className="h-5 w-16 mx-auto mt-1" />
            ) : (
              <p className="text-sm font-semibold mt-1">{status.version || "-"}</p>
            )}
          </div>
          <div className="rounded-lg bg-muted p-3 text-center">
            <p className="text-xs text-muted-foreground mb-0.5">Address</p>
            <p className="text-xs font-mono font-semibold mt-1">
              minecraft.hurkicorgi.com
            </p>
          </div>
        </div>

        {/* Confirmation */}
        {confirm && (
          <Alert className="border-amber-500/30 bg-amber-500/5">
            <AlertDescription className="text-amber-300 flex items-center justify-between gap-3 flex-wrap">
              <span>
                {confirm === "stop"
                  ? "Stop the server? Players will be disconnected."
                  : "Restart the server? Players will be disconnected briefly."}
              </span>
              <span className="flex gap-1">
                <Button size="sm" variant="destructive" onClick={confirmRun}>
                  Confirm {ACTION_LABEL[confirm]}
                </Button>
                <Button size="sm" variant="ghost" onClick={() => setConfirm(null)}>
                  Cancel
                </Button>
              </span>
            </AlertDescription>
          </Alert>
        )}

        {/* Action buttons */}
        <div className="grid grid-cols-3 gap-2">
          <Button
            variant="outline"
            onClick={() => trigger("start")}
            disabled={action.isPending || isOnline || !!confirm}
            className="w-full border-emerald-500/30 text-emerald-300 hover:bg-emerald-500/10 hover:text-emerald-200 disabled:opacity-40"
          >
            Start
          </Button>
          <Button
            variant="outline"
            onClick={() => trigger("stop")}
            disabled={action.isPending || !isOnline || !!confirm}
            className="w-full border-red-500/30 text-red-300 hover:bg-red-500/10 hover:text-red-200 disabled:opacity-40"
          >
            Stop
          </Button>
          <Button
            variant="outline"
            onClick={() => trigger("restart")}
            disabled={action.isPending || !isOnline || !!confirm}
            className="w-full border-amber-500/30 text-amber-300 hover:bg-amber-500/10 hover:text-amber-200 disabled:opacity-40"
          >
            Restart
          </Button>
        </div>

        {/* Feedback */}
        {action.isPending && (
          <Alert>
            <AlertDescription className="text-muted-foreground flex items-center gap-2">
              <span className="h-2 w-2 rounded-full bg-blue-400 animate-pulse" />
              Sending {action.variables ? ACTION_LABEL[action.variables] : ""} command...
            </AlertDescription>
          </Alert>
        )}
        {/* success/error surfaced via toast */}

        <Separator />

        {/* Scheduled restart */}
        <ScheduledRestart />

        <Separator />

        {/* Additional scheduled tasks */}
        <ScheduledTasks />
      </CardContent>
    </Card>
  );
}

function ScheduledRestart() {
  const { data: schedule } = useQuery<{ enabled: boolean; hour: number; minute: number }>({
    queryKey: ["schedule"],
    queryFn: () => fetch("/api/schedule").then((r) => r.json()),
    staleTime: 30_000,
    initialData: { enabled: false, hour: 4, minute: 0 },
  });

  const [hour, setHour] = useState<number | null>(null);
  const [minute, setMinute] = useState<number | null>(null);

  const h = hour ?? schedule.hour;
  const m = minute ?? schedule.minute;

  const update = useMutation({
    mutationFn: async (params: { enabled: boolean; hour: number; minute: number }) => {
      const res = await fetch("/api/schedule", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(params),
      });
      return res.json();
    },
  });

  const pad = (n: number) => String(n).padStart(2, "0");

  return (
    <div className="space-y-3">
      <div>
        <p className="text-sm font-semibold">Scheduled Restart</p>
        <p className="text-xs text-muted-foreground">
          {schedule.enabled
            ? `Daily at ${pad(schedule.hour)}:${pad(schedule.minute)} server time — warns players before restarting`
            : "Set a time for daily auto-restart with player warnings (uses server's local time)"}
        </p>
      </div>
      <div className="flex flex-wrap items-center gap-2">
        <select
          value={h}
          onChange={(e) => setHour(parseInt(e.target.value))}
          className="h-10 w-20 rounded-md border border-input bg-muted px-3 text-sm text-foreground"
        >
          {Array.from({ length: 24 }, (_, i) => (
            <option key={i} value={i}>
              {pad(i)}
            </option>
          ))}
        </select>
        <span className="text-muted-foreground font-bold">:</span>
        <select
          value={m}
          onChange={(e) => setMinute(parseInt(e.target.value))}
          className="h-10 w-20 rounded-md border border-input bg-muted px-3 text-sm text-foreground"
        >
          {[0, 15, 30, 45].map((v) => (
            <option key={v} value={v}>
              {pad(v)}
            </option>
          ))}
        </select>
        <span className="text-xs text-muted-foreground">server time</span>
        {schedule.enabled ? (
          <Button
            variant="ghost"
            onClick={() => update.mutate({ enabled: false, hour: h, minute: m })}
            disabled={update.isPending}
            className="text-muted-foreground"
          >
            Disable
          </Button>
        ) : (
          <Button
            onClick={() => update.mutate({ enabled: true, hour: h, minute: m })}
            disabled={update.isPending}
          >
            Enable
          </Button>
        )}
      </div>
    </div>
  );
}
