import React from "react";

import Image from "next/image";

import { z } from "zod";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";

import { Play } from "lucide-react";

import { formatDate } from "@/lib/utils";

import { Tables } from "@/utils/supabase/database.types";

import { Button } from "@/components/ui/button";

import {
  Dialog,
  DialogClose,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form";
import { Badge } from "@/components/ui/badge";

import Spinner from "@/components/spinner";
import { Textarea } from "@/components/ui/textarea";
import clsx from "clsx";
import { useMutation, useQueryClient } from "@tanstack/react-query";

import axios, { AxiosError } from "axios";
import { toast } from "sonner";
import { createClient } from "@/utils/supabase/client";

type AgentCardProps = { data: Tables<"agents"> };

export default function AgentCard(props: AgentCardProps) {
  const {
    id,
    image_url,
    name,
    description,
    model_type,
    created_at,
    conversation,
    last_conv,
  } = props.data;

  const [openDialogUpdate, setOpenDialogUpdate] = React.useState(false);

  const formSchema = z.object({
    question: z
      .string({
        required_error: "Question is required",
      })
      .min(2, {
        message: "Minimum Question is 2 characters.",
      }),
  });

  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      question: "",
    },
    mode: "onChange",
  });

  const queryClient = useQueryClient();

  const mutation = useMutation({
    mutationFn: async (values: z.infer<typeof formSchema>) => {
      const supabase = createClient();

      const { data: existingAgent } = await supabase
        .from("agents")
        .select("*")
        .eq("id", id);

      const { data, error } = await supabase
        .from("agents")
        .update({
          conversation: existingAgent ? existingAgent[0].conversation + 1 : 0,
          last_conv: new Date().toISOString(),
        })
        .eq("id", id)
        .select();

      const url = encodeURI(
        `https://ai-endpoint-one.dev3vds1.link/deepinfra-ai/${name}/${model_type}/${description}/${values.question}`
      );

      const json = await axios.get(url);

      return json.data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({
        queryKey: ["agents"],
      });
    },
    onError: (error) => {
      if (error instanceof AxiosError) {
        if (error.response) {
          // The request was made and the server responded with a status code
          // that falls out of the range of 2xx
          const errResponse = error.response.data;
          console.log({ errResponse });
          // if (errResponse.errors && Array.isArray(errResponse.errors)) {
          //   errResponse.errors.forEach(
          //     (inputErr: { field: string; message: string }) => {
          //       toast.error(`Error field : ${inputErr.field}`, {
          //         description: inputErr.message,
          //       });
          //     }
          //   );
          // }
          // if (errResponse.code) {
          //   toast.error(errResponse?.code, {
          //     description: errResponse?.message,
          //   });
          // }
        } else if (error.request) {
          // The request was made but no response was received
          // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
          // http.ClientRequest in node.js
          toast.error("No response from the server", {
            description: "Failed to fetch the data, server returns null.",
          });
        } else {
          // Something happened in setting up the request that triggered an Error
          toast.error("Failed to set up the request", {
            description: "There is something wrong when setting up the request",
          });
        }
      }
      // toast.error(err.message);
    },
  });

  const onSubmit = (values: z.infer<typeof formSchema>) => {
    mutation.mutate(values);
  };

  const {
    formState: { errors },
  } = form;

  return (
    <li className="flex flex-col rounded-lg p-4 border border-accent-foreground hover:shadow-sm transition-shadow duration-200">
      <figure className="overflow-hidden relative rounded-lg object-cover border mb-3 w-full h-[200px]">
        <Image
          className="w-full object-cover"
          src={image_url ? image_url : "/placeholder.png"}
          fill={true}
          alt={name}
        />
        <div className="h-full w-full absolute top-0 left-0" />
      </figure>
      <div className="flex items-center justify-between">
        <Badge className="mb-2" variant={"secondary"}>
          {conversation} chats
        </Badge>
        <p className="mb-2 text-primary">
          <time dateTime={created_at} className="text-xs">
            Last Active:{" "}
            <span className="font-bold">
              {last_conv ? formatDate(last_conv) : "-"}
            </span>
          </time>
        </p>
      </div>
      <h3 className="text-xl font-semibold mb-2 truncate">{name}</h3>
      <p className="text-sm text-foreground line-clamp-3 mb-4">{description}</p>
      <div className="mt-auto grid">
        <Dialog
          open={openDialogUpdate}
          onOpenChange={(val) => {
            form.reset();
            mutation.reset();
            setOpenDialogUpdate(val);
          }}
        >
          <DialogTrigger asChild>
            <Button size={"sm"} variant={"outline"}>
              <Play className="h-4 w-4 mr-2" />
              <span>Try it</span>
            </Button>
          </DialogTrigger>
          <DialogContent className="w-[90%] max-h-[90vh] max-w-xl rounded-md overflow-y-scroll">
            <DialogHeader>
              <DialogTitle>Try Agent</DialogTitle>
              <DialogDescription>
                Try to ask a question to our agent
              </DialogDescription>
            </DialogHeader>
            <div>
              <figure className="overflow-hidden relative rounded-lg object-cover border mb-3 w-full h-[200px]">
                <Image
                  className="w-full object-cover"
                  src={image_url ? image_url : "/placeholder.png"}
                  fill={true}
                  alt={name}
                />
                <div className="h-full w-full absolute top-0 left-0" />
              </figure>
              <div className="flex items-center justify-between mb-3">
                <Badge className="mb-2" variant={"secondary"}>
                  {conversation} chats
                </Badge>
                <p className="mb-2 text-primary">
                  <time dateTime={created_at} className="text-xs">
                    Last Active:{" "}
                    <span className="font-bold">
                      {last_conv ? formatDate(last_conv) : "-"}
                    </span>
                  </time>
                </p>
              </div>
              <ul className="text-sm space-y-3 mb-3">
                <li>
                  <h3 className="font-bold">Name:</h3>
                  <p className="text-gray-500">{name}</p>
                </li>
                <li>
                  <h3 className="font-bold">Description:</h3>
                  <p className="text-gray-500">{description}</p>
                </li>
              </ul>
              <Form {...form}>
                <form
                  onSubmit={form.handleSubmit(onSubmit)}
                  className="space-y-3"
                >
                  <FormField
                    control={form.control}
                    name="question"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel className="font-bold">Question:</FormLabel>
                        <FormControl>
                          <Textarea
                            rows={4}
                            placeholder="For answering daily questions."
                            className={clsx(
                              errors.question &&
                                "focus-visible:ring-destructive"
                            )}
                            {...field}
                          />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                  {mutation.isSuccess && (
                    <>
                      <h3 className="text-sm font-bold">Answer:</h3>
                      <blockquote className="border-l-2 pl-6 italic">
                        {mutation.data.response}
                      </blockquote>
                    </>
                  )}
                  <DialogFooter className="mt-4 flex justify-end space-x-2">
                    <DialogClose asChild>
                      <Button
                        type="button"
                        variant="outline"
                        disabled={mutation.isPending}
                        size="sm"
                      >
                        {mutation.isPending && (
                          <Spinner className="mr-2 h-4 w-4 " />
                        )}
                        Cancel
                      </Button>
                    </DialogClose>
                    <Button
                      type="submit"
                      disabled={mutation.isPending}
                      size="sm"
                    >
                      {mutation.isPending && (
                        <Spinner className="mr-2 h-4 w-4 " />
                      )}
                      Submit
                    </Button>
                  </DialogFooter>
                </form>
              </Form>
            </div>
          </DialogContent>
        </Dialog>
      </div>
    </li>
  );
}
