"use client";
import {
  ChevronDownIcon,
  WrenchScrewdriverIcon
} from "@heroicons/react/24/outline";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useState } from "react";
import toast from "react-hot-toast";
import { del, post } from "../../lib/api";
import { useNotifications } from "./NotificationContext";
import SlideInForm from "./SlideInForm";

export default function MaintenanceDropdown() {
  const queryClient = useQueryClient();
  const { addNotification } = useNotifications();
  const [isOpen, setIsOpen] = useState(false);
  const [operation, setOperation] = useState<
    "cleanup" | "purge" | "prune" | "clear" | null
  >(null);
  const [file, setFile] = useState("");
  const [dirs, setDirs] = useState<string[]>([]);
  const [dayMs, setDayMs] = useState<number | undefined>();
  const [cleanerMs, setCleanerMs] = useState<number | undefined>();

  const cleanupMutation = useMutation({
    mutationFn: () => post("/maintenance/cleanup", { file, dirs }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["files"] });
      queryClient.invalidateQueries({ queryKey: ["tasks"] });
      setIsOpen(false);
      resetForm();
      toast.success("Cleanup completed successfully");
      addNotification({
        type: "success",
        title: "Maintenance Complete",
        message: "File cleanup operation completed successfully."
      });
    },
    onError: (error: any) => {
      toast.error(`Cleanup failed: ${error.message}`);
      addNotification({
        type: "error",
        title: "Maintenance Failed",
        message: `Cleanup operation failed: ${error.message}`
      });
    }
  });

  const purgeMutation = useMutation({
    mutationFn: () => post("/maintenance/purge", { dirs, dayMs, cleanerMs }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["files"] });
      queryClient.invalidateQueries({ queryKey: ["tasks"] });
      setIsOpen(false);
      resetForm();
      toast.success("Purge completed successfully");
      addNotification({
        type: "success",
        title: "Maintenance Complete",
        message: "Directory purge operation completed successfully."
      });
    },
    onError: (error: any) => {
      toast.error(`Purge failed: ${error.message}`);
      addNotification({
        type: "error",
        title: "Maintenance Failed",
        message: `Purge operation failed: ${error.message}`
      });
    }
  });

  const pruneMutation = useMutation({
    mutationFn: () => post("/maintenance/prune", { dirs }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["files"] });
      queryClient.invalidateQueries({ queryKey: ["tasks"] });
      setIsOpen(false);
      resetForm();
      toast.success("Prune completed successfully");
      addNotification({
        type: "success",
        title: "Maintenance Complete",
        message: "Directory prune operation completed successfully."
      });
    },
    onError: (error: any) => {
      toast.error(`Prune failed: ${error.message}`);
      addNotification({
        type: "error",
        title: "Maintenance Failed",
        message: `Prune operation failed: ${error.message}`
      });
    }
  });

  const clearAllMutation = useMutation({
    mutationFn: () => del("/files"),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["files"] });
      queryClient.invalidateQueries({ queryKey: ["tasks"] });
      setIsOpen(false);
      resetForm();
      toast.success("All files cleared successfully");
      addNotification({
        type: "success",
        title: "Maintenance Complete",
        message: "All file records have been cleared from the database."
      });
    },
    onError: (error: any) => {
      toast.error(`Clear all files failed: ${error.message}`);
      addNotification({
        type: "error",
        title: "Maintenance Failed",
        message: `Clear all files operation failed: ${error.message}`
      });
    }
  });

  const resetForm = () => {
    setOperation(null);
    setFile("");
    setDirs([]);
    setDayMs(undefined);
    setCleanerMs(undefined);
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (operation === "cleanup") {
      cleanupMutation.mutate();
    } else if (operation === "purge") {
      purgeMutation.mutate();
    } else if (operation === "prune") {
      pruneMutation.mutate();
    } else if (operation === "clear") {
      if (file !== "CLEAR") {
        toast.error("Please type 'CLEAR' to confirm the operation");
        return;
      }
      clearAllMutation.mutate();
    }
  };

  const handleClose = () => {
    setIsOpen(false);
    resetForm();
  };

  const addDir = () => {
    setDirs([...dirs, ""]);
  };

  const updateDir = (index: number, value: string) => {
    const newDirs = [...dirs];
    newDirs[index] = value;
    setDirs(newDirs);
  };

  const removeDir = (index: number) => {
    setDirs(dirs.filter((_, i) => i !== index));
  };

  const renderForm = () => {
    if (operation === "cleanup") {
      return (
        <form onSubmit={handleSubmit} className="space-y-4">
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
              File Path
            </label>
            <input
              className="block w-full rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100"
              placeholder="Path to the file to clean up"
              value={file}
              onChange={(e) => setFile(e.target.value)}
              required
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
              Directories to Search
            </label>
            {dirs.map((dir, index) => (
              <div key={index} className="flex gap-2 mb-2">
                <input
                  className="flex-1 rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100"
                  placeholder="Directory path"
                  value={dir}
                  onChange={(e) => updateDir(index, e.target.value)}
                  required
                />
                <button
                  type="button"
                  onClick={() => removeDir(index)}
                  className="px-2 py-1 text-red-600 hover:text-red-800"
                >
                  ×
                </button>
              </div>
            ))}
            <button
              type="button"
              onClick={addDir}
              className="text-sm text-indigo-600 hover:text-indigo-800"
            >
              + Add Directory
            </button>
          </div>
        </form>
      );
    } else if (operation === "purge") {
      return (
        <form onSubmit={handleSubmit} className="space-y-4">
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
              Directories to Purge
            </label>
            {dirs.map((dir, index) => (
              <div key={index} className="flex gap-2 mb-2">
                <input
                  className="flex-1 rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100"
                  placeholder="Directory path"
                  value={dir}
                  onChange={(e) => updateDir(index, e.target.value)}
                  required
                />
                <button
                  type="button"
                  onClick={() => removeDir(index)}
                  className="px-2 py-1 text-red-600 hover:text-red-800"
                >
                  ×
                </button>
              </div>
            ))}
            <button
              type="button"
              onClick={addDir}
              className="text-sm text-indigo-600 hover:text-indigo-800"
            >
              + Add Directory
            </button>
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
              Day Threshold (ms) - Optional
            </label>
            <input
              type="number"
              className="block w-full rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100"
              placeholder="Minimum age in milliseconds"
              value={dayMs || ""}
              onChange={(e) =>
                setDayMs(e.target.value ? parseInt(e.target.value) : undefined)
              }
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
              Cleaner Threshold (ms) - Optional
            </label>
            <input
              type="number"
              className="block w-full rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100"
              placeholder="Cleaner threshold in milliseconds"
              value={cleanerMs || ""}
              onChange={(e) =>
                setCleanerMs(
                  e.target.value ? parseInt(e.target.value) : undefined
                )
              }
            />
          </div>
        </form>
      );
    } else if (operation === "prune") {
      return (
        <form onSubmit={handleSubmit} className="space-y-4">
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
              Directories to Prune
            </label>
            {dirs.map((dir, index) => (
              <div key={index} className="flex gap-2 mb-2">
                <input
                  className="flex-1 rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100"
                  placeholder="Directory path"
                  value={dir}
                  onChange={(e) => updateDir(index, e.target.value)}
                  required
                />
                <button
                  type="button"
                  onClick={() => removeDir(index)}
                  className="px-2 py-1 text-red-600 hover:text-red-800"
                >
                  ×
                </button>
              </div>
            ))}
            <button
              type="button"
              onClick={addDir}
              className="text-sm text-indigo-600 hover:text-indigo-800"
            >
              + Add Directory
            </button>
          </div>
        </form>
      );
    } else if (operation === "clear") {
      return (
        <div className="space-y-4">
          <div className="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-md p-4">
            <div className="flex">
              <div className="flex-shrink-0">
                <svg
                  className="h-5 w-5 text-red-400"
                  viewBox="0 0 20 20"
                  fill="currentColor"
                >
                  <path
                    fillRule="evenodd"
                    d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z"
                    clipRule="evenodd"
                  />
                </svg>
              </div>
              <div className="ml-3">
                <h3 className="text-sm font-medium text-red-800 dark:text-red-200">
                  Warning: Destructive Operation
                </h3>
                <div className="mt-2 text-sm text-red-700 dark:text-red-300">
                  <p>
                    This will permanently delete ALL file records from the
                    database. The file watcher will need to rediscover and
                    re-add all files. This operation cannot be undone.
                  </p>
                </div>
              </div>
            </div>
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
              Type "CLEAR" to confirm
            </label>
            <input
              className="block w-full rounded-md border-gray-300 dark:border-gray-700 shadow-sm focus:border-red-500 focus:ring-red-500 sm:text-sm bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100"
              placeholder="Type CLEAR to confirm"
              value={file}
              onChange={(e) => setFile(e.target.value)}
              required
            />
          </div>
        </div>
      );
    }
    return null;
  };

  const getFormTitle = () => {
    switch (operation) {
      case "cleanup":
        return "Cleanup Files";
      case "purge":
        return "Purge Directories";
      case "prune":
        return "Prune Directories";
      case "clear":
        return "Clear All Files";
      default:
        return "Maintenance";
    }
  };

  const isLoading =
    cleanupMutation.status === "pending" ||
    purgeMutation.status === "pending" ||
    pruneMutation.status === "pending" ||
    clearAllMutation.status === "pending";

  return (
    <>
      <div className="relative">
        <button
          onClick={() => setIsOpen(!isOpen)}
          className="inline-flex items-center rounded-md bg-orange-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-orange-700 focus:outline-none focus:ring-2 focus:ring-orange-500 focus:ring-offset-2"
        >
          <WrenchScrewdriverIcon className="h-4 w-4 mr-2" />
          Maintenance
          <ChevronDownIcon className="h-4 w-4 ml-2" />
        </button>
        {isOpen && (
          <div className="absolute right-0 mt-2 w-48 bg-white dark:bg-gray-800 rounded-md shadow-lg border border-gray-200 dark:border-gray-700 z-10">
            <div className="py-1">
              <button
                onClick={() => {
                  setOperation("cleanup");
                  setIsOpen(false);
                }}
                className="block w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"
              >
                Cleanup Files
              </button>
              <button
                onClick={() => {
                  setOperation("purge");
                  setIsOpen(false);
                }}
                className="block w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"
              >
                Purge Directories
              </button>
              <button
                onClick={() => {
                  setOperation("prune");
                  setIsOpen(false);
                }}
                className="block w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700"
              >
                Prune Directories
              </button>
              <button
                onClick={() => {
                  setOperation("clear");
                  setIsOpen(false);
                }}
                className="block w-full text-left px-4 py-2 text-sm text-red-600 dark:text-red-400 hover:bg-gray-100 dark:hover:bg-gray-700"
              >
                Clear All Files
              </button>
            </div>
          </div>
        )}
      </div>

      <SlideInForm
        isOpen={!!operation}
        onClose={handleClose}
        title={getFormTitle()}
        actions={
          <div className="flex justify-end space-x-3">
            <button
              type="button"
              onClick={handleClose}
              className="inline-flex items-center rounded-md border border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-900 px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-200 shadow-sm hover:bg-gray-50 dark:hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
            >
              Cancel
            </button>
            <button
              type="submit"
              disabled={isLoading}
              onClick={handleSubmit}
              className="inline-flex items-center rounded-md border border-transparent bg-orange-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-orange-700 focus:outline-none focus:ring-2 focus:ring-orange-500 focus:ring-offset-2"
            >
              {isLoading ? "Running..." : "Execute"}
            </button>
          </div>
        }
      >
        {renderForm()}
      </SlideInForm>
    </>
  );
}
