"use client";
import { PlusIcon } from "@heroicons/react/24/outline";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useEffect, useState } from "react";
import toast from "react-hot-toast";
import { post } from "../../lib/api";
import { useAppContext } from "../providers/AppContext";
import { useNotifications } from "./NotificationContext";
import SlideInForm from "./SlideInForm";

interface FileCrudProps {
  editFile?: any;
  onEditClose?: () => void;
}

interface FileFormState {
  dataset: string;
  input: string;
  output: string;
  date: string;
  isOpen: boolean;
}

const initialFileState: FileFormState = {
  dataset: "pr0n",
  input: "",
  output: "",
  date: "",
  isOpen: false,
};

export default function FileCrud({ editFile, onEditClose }: FileCrudProps) {
  const queryClient = useQueryClient();
  const { addNotification } = useNotifications();
  const { datasets } = useAppContext();
  const [formState, setFormState] = useState<FileFormState>(initialFileState);

  const isEditing = !!editFile;

  useEffect(() => {
    if (isEditing && editFile) {
      setFormState({
        dataset: editFile.dataset || "pr0n",
        input: editFile.input || "",
        output: editFile.output || "",
        date: editFile.date || "",
        isOpen: true,
      });
    }
  }, [editFile, isEditing]);

  const resetForm = () => {
    setFormState(initialFileState);
  };

  const createMutation = useMutation({
    mutationFn: () =>
      post(`/files/${formState.dataset}/${formState.input}`, {
        output: formState.output,
        date: formState.date,
      }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["files"] });
      resetForm();
      if (onEditClose) onEditClose();
      toast.success("File added successfully");
      addNotification({
        type: "success",
        title: "File Added",
        message: `File "${formState.input}" has been added to dataset "${formState.dataset}" successfully.`,
      });
    },
  });

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

  const handleClose = () => {
    resetForm();
    if (onEditClose) onEditClose();
  };

  if (isEditing) {
    return (
      <SlideInForm
        isOpen={formState.isOpen}
        onClose={handleClose}
        title="Edit File"
        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={createMutation.isPending}
              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 File
            </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">
              Dataset
            </label>
            <select
              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"
              value={formState.dataset}
              onChange={(e) =>
                setFormState({ ...formState, dataset: e.target.value })
              }
              required
            >
              <option value="">Select a dataset</option>
              {datasets?.map((ds: string) => (
                <option key={ds} value={ds.split("/").pop()}>
                  {ds.split("/").pop()}
                </option>
              ))}
            </select>
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
              Input (filename)
            </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="Input (filename)"
              value={formState.input}
              onChange={(e) =>
                setFormState({ ...formState, input: e.target.value })
              }
              required
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
              Output
            </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="Output"
              value={formState.output}
              onChange={(e) =>
                setFormState({ ...formState, output: e.target.value })
              }
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
              Date
            </label>
            <input
              type="datetime-local"
              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"
              value={
                formState.date
                  ? new Date(formState.date).toISOString().slice(0, 16)
                  : ""
              }
              onChange={(e) =>
                setFormState({
                  ...formState,
                  date: e.target.value
                    ? new Date(e.target.value).toISOString()
                    : "",
                })
              }
            />
          </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 File"
        >
          <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 File
        </div>
      </div>

      <SlideInForm
        isOpen={formState.isOpen}
        onClose={handleClose}
        title="Add New File"
        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={createMutation.isPending}
              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"
            >
              Add File
            </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">
              Dataset
            </label>
            <select
              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"
              value={formState.dataset}
              onChange={(e) =>
                setFormState({ ...formState, dataset: e.target.value })
              }
            >
              <option value="">Select a dataset</option>
              {datasets?.map((ds: string) => (
                <option key={ds} value={ds.split("/").pop()}>
                  {ds.split("/").pop()}
                </option>
              ))}
            </select>
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
              Input (filename)
            </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="Input (filename)"
              value={formState.input}
              onChange={(e) =>
                setFormState({ ...formState, input: e.target.value })
              }
              required
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
              Output
            </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="Output"
              value={formState.output}
              onChange={(e) =>
                setFormState({ ...formState, output: e.target.value })
              }
            />
          </div>
          <div>
            <label className="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
              Date
            </label>
            <input
              type="datetime-local"
              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"
              value={
                formState.date
                  ? new Date(formState.date).toISOString().slice(0, 16)
                  : ""
              }
              onChange={(e) =>
                setFormState({
                  ...formState,
                  date: e.target.value
                    ? new Date(e.target.value).toISOString()
                    : "",
                })
              }
            />
          </div>
        </form>
      </SlideInForm>
    </>
  );
}
