"use client";

import { useEffect, useState, useCallback } from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Skeleton } from "@/components/ui/skeleton";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import {
  Archive,
  Download,
  Trash2,
  RefreshCw,
  Plus,
  MoreHorizontal,
  Globe,
  Puzzle,
  Settings,
  Package,
} from "lucide-react";
import { toast } from "sonner";
import { formatDistanceToNow, format } from "date-fns";

interface Backup {
  id: string;
  name: string;
  type: "worlds" | "plugins" | "config" | "full";
  size: number;
  path: string;
  createdAt: number;
  status: "pending" | "running" | "completed" | "failed";
  triggeredBy: string;
}

const TYPE_CONFIG = {
  worlds: { label: "Worlds", icon: Globe, color: "text-blue-400", bg: "bg-blue-500/10" },
  plugins: { label: "Plugins", icon: Puzzle, color: "text-amber-400", bg: "bg-amber-500/10" },
  config: { label: "Config", icon: Settings, color: "text-violet-400", bg: "bg-violet-500/10" },
  full: { label: "Full", icon: Package, color: "text-emerald-400", bg: "bg-emerald-500/10" },
};

function formatBytes(bytes: number): string {
  if (bytes === 0) return "0 B";
  const k = 1024;
  const sizes = ["B", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
}

export default function BackupsPage() {
  const [backups, setBackups] = useState<Backup[]>([]);
  const [loading, setLoading] = useState(true);
  const [creating, setCreating] = useState(false);
  const [deleteId, setDeleteId] = useState<string | null>(null);

  const fetchBackups = useCallback(async () => {
    try {
      const res = await fetch("/api/backups");
      if (res.ok) setBackups((await res.json()).backups);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    fetchBackups();
    // Poll every 5s to catch running->completed transitions
    const interval = setInterval(fetchBackups, 5000);
    return () => clearInterval(interval);
  }, [fetchBackups]);

  const createBackup = async (type: Backup["type"]) => {
    setCreating(true);
    try {
      const res = await fetch("/api/backups", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ type }),
      });
      if (!res.ok) throw new Error((await res.json()).error);
      toast.success(`${TYPE_CONFIG[type].label} backup started`);
      fetchBackups();
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Backup failed");
    } finally {
      setCreating(false);
    }
  };

  const deleteBackup = async (id: string) => {
    try {
      const res = await fetch(`/api/backups/${id}`, { method: "DELETE" });
      if (!res.ok) throw new Error((await res.json()).error);
      toast.success("Backup deleted");
      setBackups((prev) => prev.filter((b) => b.id !== id));
    } catch (err) {
      toast.error(err instanceof Error ? err.message : "Delete failed");
    }
    setDeleteId(null);
  };

  const downloadBackup = (id: string) => {
    window.open(`/api/backups/${id}`, "_blank");
  };

  const statusBadge = (status: Backup["status"]) => {
    const config = {
      pending: "bg-zinc-500/20 text-zinc-400 border-zinc-500/30",
      running: "bg-blue-500/20 text-blue-400 border-blue-500/30",
      completed: "bg-emerald-500/20 text-emerald-400 border-emerald-500/30",
      failed: "bg-red-500/20 text-red-400 border-red-500/30",
    };
    return (
      <Badge className={`text-xs ${config[status]}`}>
        {status === "running" && (
          <span className="w-1.5 h-1.5 rounded-full bg-blue-400 mr-1.5 animate-pulse" />
        )}
        {status.charAt(0).toUpperCase() + status.slice(1)}
      </Badge>
    );
  };

  return (
    <div className="p-6 space-y-6">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold text-white">Backups</h1>
          <p className="text-zinc-400 text-sm mt-1">
            Create and manage server backups
          </p>
        </div>
        <div className="flex items-center gap-2">
          <Button
            variant="outline"
            size="sm"
            onClick={fetchBackups}
            className="border-zinc-700 text-zinc-400 hover:text-white"
          >
            <RefreshCw className="w-4 h-4" />
          </Button>
          <DropdownMenu>
            <DropdownMenuTrigger disabled={creating} className="inline-flex shrink-0 items-center justify-center rounded-lg text-sm font-medium h-7 gap-1 px-2.5 bg-emerald-600 hover:bg-emerald-500 text-white transition-all">
              <Plus className="w-4 h-4 mr-1.5" />
              New Backup
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end" className="bg-zinc-900 border-zinc-700">
              {(Object.entries(TYPE_CONFIG) as [Backup["type"], typeof TYPE_CONFIG.full][]).map(
                ([type, config]) => {
                  const Icon = config.icon;
                  return (
                    <DropdownMenuItem
                      key={type}
                      onClick={() => createBackup(type)}
                      className="text-zinc-300 focus:text-white focus:bg-zinc-800"
                    >
                      <Icon className={`w-4 h-4 mr-2 ${config.color}`} />
                      {config.label} backup
                    </DropdownMenuItem>
                  );
                },
              )}
            </DropdownMenuContent>
          </DropdownMenu>
        </div>
      </div>

      {/* Type summary cards */}
      <div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
        {(Object.entries(TYPE_CONFIG) as [Backup["type"], typeof TYPE_CONFIG.full][]).map(
          ([type, config]) => {
            const Icon = config.icon;
            const count = backups.filter(
              (b) => b.type === type && b.status === "completed",
            ).length;
            return (
              <Card
                key={type}
                className="bg-zinc-900 border-zinc-800 cursor-pointer hover:border-zinc-700 transition-colors"
                onClick={() => createBackup(type)}
              >
                <CardContent className="p-4 flex items-center gap-3">
                  <div className={`p-2 rounded-lg ${config.bg}`}>
                    <Icon className={`w-5 h-5 ${config.color}`} />
                  </div>
                  <div>
                    <p className="text-sm font-medium text-white">
                      {config.label}
                    </p>
                    <p className="text-xs text-zinc-500">{count} backup(s)</p>
                  </div>
                </CardContent>
              </Card>
            );
          },
        )}
      </div>

      {/* Backups list */}
      <Card className="bg-zinc-900 border-zinc-800">
        <CardContent className="p-0">
          {loading ? (
            <div className="p-4 space-y-3">
              {Array.from({ length: 5 }).map((_, i) => (
                <Skeleton key={i} className="h-14 w-full bg-zinc-800" />
              ))}
            </div>
          ) : backups.length === 0 ? (
            <div className="flex flex-col items-center justify-center py-16 text-zinc-600">
              <Archive className="w-10 h-10 mb-3 opacity-50" />
              <p>No backups yet</p>
              <p className="text-sm mt-1">Create your first backup above</p>
            </div>
          ) : (
            <div className="divide-y divide-zinc-800">
              <div className="grid grid-cols-[auto_1fr_auto_auto_auto_auto] gap-4 px-4 py-2.5 text-xs font-medium text-zinc-500 uppercase tracking-wide">
                <span />
                <span>Name</span>
                <span>Size</span>
                <span>Status</span>
                <span>Created</span>
                <span />
              </div>
              {backups.map((backup) => {
                const typeConfig = TYPE_CONFIG[backup.type];
                const Icon = typeConfig.icon;
                return (
                  <div
                    key={backup.id}
                    className="grid grid-cols-[auto_1fr_auto_auto_auto_auto] gap-4 px-4 py-3 items-center hover:bg-zinc-800/50 transition-colors"
                  >
                    <div className={`p-1.5 rounded-md ${typeConfig.bg}`}>
                      <Icon className={`w-4 h-4 ${typeConfig.color}`} />
                    </div>
                    <div>
                      <p className="text-sm font-medium text-white truncate max-w-xs">
                        {backup.name}
                      </p>
                      <p className="text-xs text-zinc-500 capitalize">
                        {backup.type}
                      </p>
                    </div>
                    <span className="text-sm text-zinc-400">
                      {backup.size > 0 ? formatBytes(backup.size) : "—"}
                    </span>
                    {statusBadge(backup.status)}
                    <span className="text-sm text-zinc-500">
                      {formatDistanceToNow(new Date(backup.createdAt), {
                        addSuffix: true,
                      })}
                    </span>
                    <DropdownMenu>
                      <DropdownMenuTrigger className="inline-flex shrink-0 items-center justify-center rounded-lg text-sm font-medium w-8 h-8 text-zinc-500 hover:text-white transition-all">
                        <MoreHorizontal className="w-4 h-4" />
                      </DropdownMenuTrigger>
                      <DropdownMenuContent align="end" className="bg-zinc-900 border-zinc-700">
                        {backup.status === "completed" && (
                          <DropdownMenuItem
                            onClick={() => downloadBackup(backup.id)}
                            className="text-zinc-300 focus:text-white focus:bg-zinc-800"
                          >
                            <Download className="w-4 h-4 mr-2" />
                            Download
                          </DropdownMenuItem>
                        )}
                        <DropdownMenuItem
                          onClick={() => setDeleteId(backup.id)}
                          className="text-red-400 focus:text-red-300 focus:bg-zinc-800"
                        >
                          <Trash2 className="w-4 h-4 mr-2" />
                          Delete
                        </DropdownMenuItem>
                      </DropdownMenuContent>
                    </DropdownMenu>
                  </div>
                );
              })}
            </div>
          )}
        </CardContent>
      </Card>

      {/* Delete confirmation */}
      <AlertDialog open={!!deleteId} onOpenChange={() => setDeleteId(null)}>
        <AlertDialogContent className="bg-zinc-900 border-zinc-700">
          <AlertDialogHeader>
            <AlertDialogTitle className="text-white">
              Delete backup?
            </AlertDialogTitle>
            <AlertDialogDescription className="text-zinc-400">
              This will permanently delete the backup file from disk. This
              action cannot be undone.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel className="border-zinc-700 text-zinc-400">
              Cancel
            </AlertDialogCancel>
            <AlertDialogAction
              onClick={() => deleteId && deleteBackup(deleteId)}
              className="bg-red-600 hover:bg-red-500 text-white"
            >
              Delete
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </div>
  );
}
