"use client";
import { PlusIcon } from "@heroicons/react/24/outline";
import { useEffect, useState } from "react";
import toast from "react-hot-toast";
import { useAppContext } from "../providers/AppContext";
import JsonInput from "./JsonInput";
import { useNotifications } from "./NotificationContext";
import QueueSettingsEditor from "./QueueSettingsEditor";
import SlideInForm from "./SlideInForm";
import WatcherSettingsEditor from "./WatcherSettingsEditor";

interface SettingsCrudProps {
  editKey?: string;
  editValue?: string;
  onEditClose?: () => void;
}

interface SettingsFormState {
  key: string;
  value: string;
  isOpen: boolean;
}

const initialSettingsState: SettingsFormState = {
  key: "",
  value: "",
  isOpen: false,
};

export default function SettingsCrud({
  editKey,
  editValue,
  onEditClose,
}: SettingsCrudProps) {
  const { updateSetting } = useAppContext();
  const { addNotification } = useNotifications();
  const [formState, setFormState] =
    useState<SettingsFormState>(initialSettingsState);
  const [isSaving, setIsSaving] = useState(false);

  const isEditing = !!editKey;

  useEffect(() => {
    if (isEditing) {
      setFormState({
        key: editKey,
        value: editValue || "",
        isOpen: true,
      });
    }
  }, [editKey, editValue, isEditing]);

  const handleSave = async () => {
    try {
      setIsSaving(true);
      await updateSetting(formState.key, formState.value);
      setFormState(initialSettingsState);
      if (onEditClose) onEditClose();
      const message = isEditing
        ? "Setting updated successfully"
        : "Setting added successfully";
      toast.success(message);
      addNotification({
        type: "success",
        title: "Setting Saved",
        message: `${formState.key} has been ${isEditing ? "updated" : "added"} successfully.`,
      });
    } catch (error) {
      console.error("Failed to save setting:", error);
      toast.error("Failed to save setting");
      addNotification({
        type: "error",
        title: "Save Failed",
        message: "Failed to save the setting. Please try again.",
      });
    } finally {
      setIsSaving(false);
    }
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    handleSave();
  };

  const getValueEditor = (currentKey?: string) => {
    const editorKey = currentKey || formState.key;
    switch (editorKey) {
      case "watcher":
        return (
          <WatcherSettingsEditor
            value={formState.value}
            onChange={(val) => setFormState({ ...formState, value: val })}
          />
        );
      case "queue":
        return (
          <QueueSettingsEditor
            value={formState.value}
            onChange={(val) => setFormState({ ...formState, value: val })}
          />
        );
      case "datasets":
        // Use JsonInput with JSON mode toggle for datasets configuration
        return (
          <JsonInput
            value={formState.value}
            onChange={(val) => setFormState({ ...formState, value: val })}
            className="w-full"
            placeholder="Datasets configuration (JSON)"
          />
        );
      default:
        return (
          <JsonInput
            value={formState.value}
            onChange={(val) => setFormState({ ...formState, value: val })}
            className="w-full"
            placeholder="Value (JSON)"
          />
        );
    }
  };

  const handleClose = () => {
    setFormState(initialSettingsState);
    if (onEditClose) onEditClose();
  };

  if (isEditing) {
    return (
      <SlideInForm
        isOpen={formState.isOpen}
        onClose={handleClose}
        title="Edit Setting"
        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="button"
              onClick={handleSubmit}
              disabled={isSaving}
              className="inline-flex items-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
            >
              Update Setting
            </button>
          </div>
        }
      >
        <form onSubmit={handleSubmit} className="space-y-4">
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
              Key
            </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="Key"
              value={formState.key}
              onChange={(e) =>
                setFormState({ ...formState, key: e.target.value })
              }
              required
              disabled
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
              Value
            </label>
            {getValueEditor()}
          </div>
        </form>
      </SlideInForm>
    );
  }

  return (
    <>
      <div className="relative group">
        <button
          onClick={() => setFormState({ ...formState, isOpen: true })}
          className="p-2 rounded-md text-gray-600 dark:text-gray-400 hover:bg-indigo-100 dark:hover:bg-indigo-900/30 hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors"
          title="Add Setting"
        >
          <PlusIcon className="h-5 w-5" />
        </button>
        <div className="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 px-2 py-1 bg-gray-900 dark:bg-gray-100 text-white dark:text-gray-900 text-xs rounded whitespace-nowrap opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none">
          Add Setting
        </div>
      </div>

      <SlideInForm
        isOpen={formState.isOpen}
        onClose={handleClose}
        title={isEditing ? `Edit Setting: ${editKey}` : "Add New Setting"}
        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"
              onClick={handleSubmit}
              disabled={isSaving}
              className="inline-flex items-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
            >
              {isEditing ? "Update Setting" : "Add Setting"}
            </button>
          </div>
        }
      >
        <form onSubmit={handleSubmit} className="space-y-4">
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
              Key
            </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="Key"
              value={formState.key}
              onChange={(e) =>
                setFormState({ ...formState, key: e.target.value })
              }
              required
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
              Value
            </label>
            {getValueEditor(formState.key)}
          </div>
        </form>
      </SlideInForm>
    </>
  );
}
