import { FineTuneOpenaiInputModelEnum } from "@montelo/browser-client";
import { useFetcher, useMatches, useNavigate, useParams } from "@remix-run/react";
import { SlidersHorizontal } from "lucide-react";
import { FC, useEffect, useState } from "react";
import { Button } from "~/components/ui/button";
import {
  Dialog,
  DialogClose,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "~/components/ui/dialog";
import { Label } from "~/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "~/components/ui/select";
import { Routes } from "~/routes";
import { AppLayoutLoader } from "~/types/AppLayoutLoader.types";
import { StartFineTuneAction, StartFineTuneBody } from "~/types/StartFineTuneAction.types";

type Models = (typeof FineTuneOpenaiInputModelEnum)[keyof typeof FineTuneOpenaiInputModelEnum];

export const FineTuneDialog: FC<{ isDialogDisabled: boolean }> = ({ isDialogDisabled }) => {
  const matches = useMatches();
  const params = useParams();
  const fetcher = useFetcher<StartFineTuneAction>();
  const navigate = useNavigate();
  const [selectedModel, setSelectedModel] = useState<Models | null>(null);
  const [isDialogOpen, setIsDialogOpen] = useState(false);

  const projectOpenAIKey = (
    matches.find((match) => match.id === "routes/app+/project+/$projectId+/env+/$envId+/_layout")!
      .data as AppLayoutLoader
  ).project.openaiApiKey;

  const noApiKey = !projectOpenAIKey.length;
  const isNotIdle = fetcher.state !== "idle";
  const isCancelDisabled = isNotIdle;
  const isStartDisabled = isNotIdle || noApiKey || !selectedModel;

  const handleStartFineTune = () => {
    if (!selectedModel || isNotIdle) {
      return;
    }

    fetcher.submit(
      {
        model: selectedModel,
      } as StartFineTuneBody,
      {
        method: "POST",
        action: Routes.actions.finetuning.create({
          projectId: params.projectId!,
          datasetId: params.datasetId!,
        }),
        encType: "application/json",
      },
    );
  };

  const handleSelect = (value: Models) => {
    setSelectedModel(value);
  };

  useEffect(() => {
    if (fetcher.data?.finetune.id) {
      setIsDialogOpen(false);
      void navigate(
        Routes.app.project.env.finetuning({
          projectId: params.projectId!,
          envId: params.envId!,
        }),
      );
    }
  }, [fetcher.data]);

  return (
    <Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
      <DialogTrigger asChild>
        <Button disabled={isDialogDisabled}>
          <SlidersHorizontal className="mr-2 h-4 w-4" /> Fine-Tune
        </Button>
      </DialogTrigger>
      <DialogContent className={"max-h-[500px] overflow-y-scroll"}>
        <DialogHeader>
          <DialogTitle>Create a Fine-Tuned Model</DialogTitle>
        </DialogHeader>
        <div className={"flex flex-col gap-8"}>
          {noApiKey && <p className={"text-destructive"}>Please set an OpenAI API Key to fine-tune models.</p>}
          <div className={"flex flex-col gap-2"}>
            <Label>Base Model</Label>
            <Select onValueChange={handleSelect}>
              <SelectTrigger className="w-1/2">
                <SelectValue placeholder="Select..." />
              </SelectTrigger>
              <SelectContent>
                {Object.values(FineTuneOpenaiInputModelEnum).map((model) => (
                  <SelectItem key={model} value={model}>
                    {model}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
        </div>
        <DialogFooter>
          <DialogClose asChild>
            <Button variant={"secondary"} disabled={isCancelDisabled}>
              Cancel
            </Button>
          </DialogClose>
          <Button onClick={handleStartFineTune} disabled={isStartDisabled}>
            Start Fine-Tune
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
};
