"use client";
import * as z from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm, useFieldArray } from "react-hook-form";
import { useState } from "react";
import { useRouter } from "next/navigation";

import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import { X } from "lucide-react";
import { cn } from "@/lib/utils";
import { Textarea } from "./ui/textarea";

const formSchema = z.object({
  name: z.string().min(2, {
    message: "Name must be at least 2 characters.",
  }),
  description: z.string().min(2, {
    message: "Description must be at least 2 characters.",
  }),
  stack: z.array(z.string()).min(1, {
    message: "Project tech stack must have at least one item.",
  }),
  questions: z.array(
    z.object({
      question: z.string().optional(),
    })
  ),
});

export function CreateProject({ workspaceID }: { workspaceID: string }) {
  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    mode: "all",
    defaultValues: {
      name: "",
      description: "",
      stack: [],
      questions: [],
    },
  });

  const { setValue, formState } = form;
  const [stackInput, setStackInput] = useState("");
  const [isDialogOpen, setIsDialogOpen] = useState(false);
  const [formStep, setFormStep] = useState(0);
  const [questions, setQuestions] = useState([]); // TODO: [] as Question[]
  const router = useRouter();
  const { fields, append, remove } = useFieldArray({
    name: "questions",
    control: form.control,
  });

  async function onSubmit(values: z.infer<typeof formSchema>) {
    try {
      const res = await fetch(`/w/${workspaceID}/p`, {
        method: "POST",
        body: JSON.stringify({
          ...values,
          questionsText: questions,
        }),
      });

      const data = await res.json();

      console.log("===>", res);

      if (!res.ok) throw new Error("Something went wrong.");

      router.push(`/w/${workspaceID}/p/${data.project.id}`);
      setIsDialogOpen(false);
      return res;
    } catch (err) {
      console.error(err);
    }
  }

  async function generateQuestions() {
    try {
      const res = await fetch(`/w/${workspaceID}/p/gen`, {
        method: "POST",
        body: JSON.stringify(form.getValues()),
      });

      if (!res.ok) throw new Error("Something went wrong.");

      const data = await res.json();

      console.log("===>", data.questions);
      setQuestions(data.questions);
      append(data.questions);

      return res;
    } catch (err) {
      console.error(err);
    }
  }

  const keyHandler = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if ((e.key === "Enter" || e.key === "Tab") && stackInput !== "") {
      e.preventDefault();
      setValue("stack", [...form.getValues("stack"), stackInput]);
      setStackInput("");
    }
  };

  return (
    <Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
      <DialogTrigger asChild>
        <Button variant="outline">Create Project</Button>
      </DialogTrigger>
      <DialogContent>
        {formStep == 0 && (
          <DialogHeader>
            <DialogTitle>Create a Project</DialogTitle>
            <DialogDescription>
              Give your project a name, description, and tech stack.
            </DialogDescription>
          </DialogHeader>
        )}
        {formStep == 1 && (
          <DialogHeader>
            <DialogTitle>Extra Questions</DialogTitle>
            <DialogDescription>
              We&apos;ve like to know some more about the specifics of your
              project, feel free to answer any of the following additional
              questions.
            </DialogDescription>
          </DialogHeader>
        )}
        <Form {...form}>
          <form
            onSubmit={form.handleSubmit(onSubmit)}
            className={cn(formStep == 0 && "space-y-8")}
          >
            <div className={cn(formStep !== 0 && "sr-only")}>
              <FormField
                control={form.control}
                name="name"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Name</FormLabel>
                    <FormControl>
                      <Input {...field} />
                    </FormControl>
                    <FormDescription>
                      This is your project name.
                    </FormDescription>
                    <FormMessage />
                  </FormItem>
                )}
              />
              <FormField
                control={form.control}
                name="description"
                render={({ field }) => (
                  <FormItem>
                    <FormLabel>Description</FormLabel>
                    <FormControl>
                      <Input placeholder="" {...field} />
                    </FormControl>
                    <FormDescription>
                      This is your project description.
                    </FormDescription>
                    <FormMessage />
                  </FormItem>
                )}
              />
              <FormField
                control={form.control}
                name="stack"
                render={() => (
                  <FormItem>
                    <FormLabel>Tech Stack</FormLabel>
                    <FormControl>
                      <Input
                        value={stackInput}
                        onChange={(e) => setStackInput(e.target.value)}
                        onKeyDown={keyHandler}
                      />
                    </FormControl>
                    <FormDescription>
                      This is your project tech stack.
                    </FormDescription>
                    <div>
                      {form.getValues("stack").map((stack) => (
                        <Badge
                          key={stack}
                          className="mr-2 font-normal rounded-md"
                          variant="outline"
                        >
                          <span className="mr-1">{stack}</span>
                          <X
                            className="inline font-light text-red-500"
                            size={16}
                            onClick={() =>
                              setValue(
                                "stack",
                                form
                                  .getValues("stack")
                                  .filter((s) => s !== stack)
                              )
                            }
                          />
                        </Badge>
                      ))}
                    </div>
                    <FormMessage />
                  </FormItem>
                )}
              />
              <Button
                type="button"
                variant="outline"
                onClick={() => {
                  setFormStep(1);
                  generateQuestions();
                }}
              >
                Next
              </Button>
            </div>
            <div className={cn(formStep !== 1 && "sr-only")}>
              {questions.length == 0 && (
                <p className="text-gray-400 text-center">
                  Generating questions...
                </p>
              )}
              {fields.map((field, index) => (
                <FormField
                  control={form.control}
                  key={field.id}
                  name={`questions.${index}.question`}
                  render={({ field }) => (
                    <FormItem>
                      <FormLabel>Question {index + 1} </FormLabel>
                      <FormDescription>
                        <span className="text-gray-400">
                          {questions[index]}
                        </span>
                      </FormDescription>
                      <FormControl>
                        <Textarea {...field} />
                      </FormControl>
                      <FormMessage />
                    </FormItem>
                  )}
                />
              ))}
              <div className="flex p-4 gap-4 pl-0">
                <Button
                  type="button"
                  variant="outline"
                  onClick={() => {
                    setFormStep(0);
                    setQuestions([]);
                    remove();
                  }}
                >
                  Back
                </Button>
                {questions.length != 0 && <Button type="submit">Submit</Button>}
              </div>
            </div>
          </form>
        </Form>
      </DialogContent>
    </Dialog>
  );
}
