import { useState } from "react";
import { useMutation, useQuery } from "@tanstack/react-query";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { FolderOpen, HardDrive, Trash2 } from "lucide-react";
import { apiRequest, queryClient } from "@/lib/queryClient";
import { useToast } from "@/hooks/use-toast";
import { FolderBrowserModal } from "./folder-browser-modal";

export function BackupDestinationManager() {
  const { toast } = useToast();
  const [path, setPath] = useState("");
  const [deleteId, setDeleteId] = useState<number | null>(null);
  const [browserOpen, setBrowserOpen] = useState(false);

  // ==============================
  // Queries
  // ==============================
  const { data: destinations = [] } = useQuery({
    queryKey: ["/db/destination"],
    queryFn: async () => {
      const res = await apiRequest(
        "GET",
        "/api/database-management/destination"
      );
      return res.json();
    },
  });

  const { data: usbSettingData } = useQuery({
    queryKey: ["/db/usb-backup-setting"],
    queryFn: async () => {
      const res = await apiRequest("GET", "/api/database-management/usb-backup-setting");
      return res.json();
    },
  });

  const usbBackupEnabled = usbSettingData?.usbBackupEnabled ?? false;
  const usbBackupHour = usbSettingData?.usbBackupHour ?? 21;

  const usbToggleMutation = useMutation({
    mutationFn: async (patch: { usbBackupEnabled?: boolean; usbBackupHour?: number }) => {
      const res = await apiRequest("PUT", "/api/database-management/usb-backup-setting", patch);
      return res.json();
    },
    onSuccess: (data) => {
      queryClient.setQueryData(["/db/usb-backup-setting"], data);
      toast({ title: "Setting Saved" });
    },
    onError: () => {
      toast({
        title: "Error",
        description: "Failed to update USB backup setting.",
        variant: "destructive",
      });
    },
  });

  // ==============================
  // Mutations
  // ==============================
  const saveMutation = useMutation({
    mutationFn: async () => {
      const res = await apiRequest(
        "POST",
        "/api/database-management/destination",
        { path }
      );
      if (!res.ok) throw new Error((await res.json()).error);
    },
    onSuccess: () => {
      toast({ title: "Backup destination saved" });
      setPath("");
      queryClient.invalidateQueries({ queryKey: ["/db/destination"] });
    },
  });

  const deleteMutation = useMutation({
    mutationFn: async (id: number) => {
      await apiRequest("DELETE", `/api/database-management/destination/${id}`);
    },
    onSuccess: () => {
      toast({ title: "Backup destination deleted" });
      queryClient.invalidateQueries({ queryKey: ["/db/destination"] });
      setDeleteId(null);
    },
  });

  const backupNowMutation = useMutation({
    mutationFn: async () => {
      const res = await apiRequest("POST", "/api/database-management/backup-path");
      if (!res.ok) {
        const body = await res.json();
        throw new Error(body.details || body.error || "Backup failed");
      }
      return res.json();
    },
    onSuccess: (data) => {
      toast({ title: "Backup complete", description: `Saved: ${data.filename}` });
      queryClient.invalidateQueries({ queryKey: ["/db/status"] });
    },
    onError: (err: any) => {
      toast({ title: "Backup failed", description: err.message, variant: "destructive" });
    },
  });

  // ==============================
  // Folder browser
  // ==============================
  const handleFolderSelect = (selectedPath: string) => {
    setPath(selectedPath);
  };

  // ==============================
  // UI
  // ==============================
  return (
    <Card>
      <CardHeader>
        <CardTitle>External Backup Destination</CardTitle>
      </CardHeader>
      <CardContent className="space-y-4">
        <div className="flex flex-wrap items-center gap-3">
          <Switch
            id="usb-backup-toggle"
            checked={usbBackupEnabled}
            onCheckedChange={(checked) => usbToggleMutation.mutate({ usbBackupEnabled: checked })}
            disabled={usbToggleMutation.isPending}
          />
          <label
            htmlFor="usb-backup-toggle"
            className="text-sm font-medium text-gray-700 cursor-pointer select-none"
          >
            USB Backup
          </label>
          <div className="flex items-center gap-2">
            <label className="text-sm text-gray-600">at</label>
            <select
              className="border rounded px-2 py-1 text-sm text-gray-700 bg-white"
              value={usbBackupHour}
              onChange={(e) => usbToggleMutation.mutate({ usbBackupHour: Number(e.target.value) })}
            >
              {Array.from({ length: 24 }, (_, h) => {
                const label = h === 0 ? "12:00 AM" : h < 12 ? `${h}:00 AM` : h === 12 ? "12:00 PM" : `${h - 12}:00 PM`;
                return <option key={h} value={h}>{label}</option>;
              })}
            </select>
          </div>
        </div>

        <p className="text-sm text-gray-500">
          Enter the root path of your USB drive below. The app will automatically back up to the{" "}
          <span className="font-medium text-gray-700">USB Backup</span> folder inside it at the scheduled time when the toggle is on.
        </p>

        <div className="flex gap-2">
          <Input
            placeholder="/media/usb-drive or D:\\Backups"
            value={path}
            onChange={(e) => setPath(e.target.value)}
          />
          <Button variant="outline" onClick={() => setBrowserOpen(true)} title="Browse folders">
            <FolderOpen className="h-4 w-4" />
          </Button>
        </div>

        <FolderBrowserModal
          open={browserOpen}
          onClose={() => setBrowserOpen(false)}
          onSelect={handleFolderSelect}
        />

        <Button
          onClick={() => saveMutation.mutate()}
          disabled={!path || saveMutation.isPending}
        >
          Save Destination
        </Button>

        <div className="space-y-2">
          {destinations.map((d: any) => (
            <div
              key={d.id}
              className="flex justify-between items-center border rounded p-2"
            >
              <span className="text-sm text-gray-700">{d.path}</span>
              <div className="flex gap-2">
                <Button
                  size="sm"
                  variant="outline"
                  onClick={() => backupNowMutation.mutate()}
                  disabled={backupNowMutation.isPending}
                  title="Backup now to this destination"
                >
                  <HardDrive className="h-4 w-4 mr-1" />
                  {backupNowMutation.isPending ? "Backing up..." : "Backup Now"}
                </Button>
                <Button
                  size="sm"
                  variant="destructive"
                  onClick={() => setDeleteId(d.id)}
                >
                  <Trash2 className="h-4 w-4" />
                </Button>
              </div>
            </div>
          ))}
        </div>

        {/* Confirm delete dialog */}
        <AlertDialog open={deleteId !== null}>
          <AlertDialogContent>
            <AlertDialogHeader>
              <AlertDialogTitle>Delete backup destination?</AlertDialogTitle>
              <AlertDialogDescription>
                This will remove the destination and stop automatic backups.
              </AlertDialogDescription>
            </AlertDialogHeader>
            <AlertDialogFooter>
              <AlertDialogCancel onClick={() => setDeleteId(null)}>
                Cancel
              </AlertDialogCancel>
              <AlertDialogAction
                onClick={() => deleteId && deleteMutation.mutate(deleteId)}
              >
                Delete
              </AlertDialogAction>
            </AlertDialogFooter>
          </AlertDialogContent>
        </AlertDialog>
      </CardContent>
    </Card>
  );
}
