"use client";

import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { z } from "zod";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form";
import { useRouter } from "@/i18n/routing";
import { Input } from "@/components/ui/input";
import { Checkbox } from "@/components/ui/checkbox";
import { getUserRoles, postCategory } from "@/service/settings/settings";
import { Fragment, useEffect, useState } from "react";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
import { Icon } from "@iconify/react/dist/iconify.js";
import { Textarea } from "@/components/ui/textarea";
import { close, error, loading } from "@/config/swal";
import { UnitMapping } from "./unit-mapping";
import { useToast } from "@/components/ui/use-toast";
import { stringify } from "querystring";
import { useDropzone } from "react-dropzone";
import { CloudUpload } from "lucide-react";
import Image from "next/image";
import { Upload } from "tus-js-client";

const FormSchema = z.object({
  title: z.string({
    required_error: "Required",
  }),
  description: z.string({
    required_error: "Required",
  }),
  contentType: z
    .array(z.string())
    .refine((value) => value.some((item) => item), {
      message: "Required",
    }),
  selectedUser: z
    .array(z.string())
    .refine((value) => value.some((item) => item), {
      message: "Required",
    }),
  publishTo: z.array(z.string()).refine((value) => value.some((item) => item), {
    message: "Required",
  }),

  file: z.string().optional(),
});

const listContent = [
  {
    id: "1",
    name: "Foto",
  },
  {
    id: "2",
    name: "Audio Visual",
  },
  {
    id: "3",
    name: "Teks",
  },
  {
    id: "4",
    name: "Audio",
  },
];

const publishToList = [
  {
    id: "mabes",
    name: "Nasional",
  },
  {
    id: "polda",
    name: "Polda",
  },
  {
    id: "satker",
    name: "Satker",
  },
  {
    id: "internasional",
    name: "Internasional",
  },
];

export default function CreateCategoryModal() {
  const router = useRouter();
  const { toast } = useToast();

  const [files, setFiles] = useState<File[]>([]);
  const [isOpen, setIsOpen] = useState(false);
  const [satkerData, setSatkerData] = useState<string[]>([]);
  const [unitData, setUnitData] = useState<string[]>([]);
  const [userList, setUserList] = useState<
    { id: string; name: string; isInternal: boolean }[]
  >([]);

  const form = useForm<z.infer<typeof FormSchema>>({
    resolver: zodResolver(FormSchema),
    defaultValues: { contentType: [], selectedUser: [], publishTo: [] },
  });

  const contentType = form.watch("contentType");
  const isAllContentChecked = listContent.every((item) =>
    contentType?.includes(item.id)
  );

  const users = form.watch("selectedUser");
  const isAllUserChecked = userList.every((item) => users?.includes(item.id));

  const target = form.watch("publishTo");
  const isAllTargetChecked = publishToList.every((item) =>
    target?.includes(item.id)
  );

  const { getRootProps, getInputProps } = useDropzone({
    onDrop: (acceptedFiles) => {
      setFiles(acceptedFiles.map((file) => Object.assign(file)));
    },
    maxFiles: 1,
  });

  useEffect(() => {
    getRoles();
  }, []);

  async function getRoles() {
    const response = await getUserRoles();
    let dataRoles = response?.data?.data;
    for (let i = 0; i < dataRoles.length; i++) {
      dataRoles[i].id = String(dataRoles[i].id);
    }
    setUserList(dataRoles);
  }

  const onSubmit = async (data: z.infer<typeof FormSchema>) => {
    if (data.publishTo.includes("polda") || data.publishTo.includes("satker")) {
      if (
        (data.publishTo.includes("polda") && unitData?.length < 1) ||
        (data.publishTo.includes("satker") && satkerData?.length < 1)
      ) {
        const poldaValidation = data.publishTo.includes("polda");
        const satkerValidation = data.publishTo.includes("satker");
        toast({
          title:
            poldaValidation && satkerValidation
              ? "Pilih Polda dan Satker tujuan"
              : `Pilih ${poldaValidation ? "Polda" : "Satker"} tujuan`,
          variant: "destructive",
        });
      } else {
        save(data);
      }
    } else {
      save(data);
    }
  };

  const save = async (data: z.infer<typeof FormSchema>) => {
    const formMedia = new FormData();

    loading();

    const unit = unitData?.join(",");
    const satker = satkerData?.join(",");
    const join =
      unitData?.length > 0 && satkerData?.length > 0
        ? unit + "," + satker
        : unitData?.length > 0
        ? unit
        : satkerData?.length > 0
        ? satker
        : "";

    formMedia.append("name", data.title);
    formMedia.append("description", data.description);
    formMedia.append("mediaTypes", data.contentType.join(","));
    formMedia.append("publishedFor", data.selectedUser.join(","));
    formMedia.append("file", files[0]);
    formMedia.append("publishedLocation", data.publishTo.sort().join(","));
    formMedia.append("publishedLocationLevel", join);

    const response = await postCategory(formMedia);
    close();
    if (response?.error) {
      toast({ title: stringify(response.message), variant: "destructive" });
      return false;
    }
    toast({
      title: "Succes",
      description: "Kategori berhasil dibuat",
    });
    router.push("/admin/settings/category?dataChange=true");
    setIsOpen(false);
  };

  const handleRemoveFile = (file: File) => {
    const uploadedFiles = files;
    const filtered = uploadedFiles.filter((i) => i.name !== file.name);
    setFiles([...filtered]);
  };

  return (
    <Dialog open={isOpen} onOpenChange={setIsOpen}>
      <DialogTrigger asChild>
        <Button color="primary" size="md">
          Tambah Kategori
        </Button>
      </DialogTrigger>
      <DialogContent size="md">
        <DialogHeader>
          <DialogTitle>Tambah Kategori</DialogTitle>
        </DialogHeader>
        <Form {...form}>
          <form
            onSubmit={form.handleSubmit(onSubmit)}
            className="space-y-3 bg-white rounded-sm"
          >
            <FormField
              control={form.control}
              name="contentType"
              render={() => (
                <FormItem>
                  <FormLabel>Tipe Konten</FormLabel>

                  <div className="flex flex-row items-center gap-2">
                    <div className="flex items-center gap-3">
                      <Checkbox
                        id="all"
                        checked={isAllContentChecked}
                        onCheckedChange={(checked) => {
                          if (checked) {
                            form.setValue(
                              "contentType",
                              listContent.map((item) => item.id)
                            );
                          } else {
                            form.setValue("contentType", []);
                          }
                        }}
                      />
                      <label htmlFor="all" className="text-sm">
                        Semua
                      </label>
                    </div>
                    {listContent.map((item) => (
                      <FormField
                        key={item.id}
                        control={form.control}
                        name="contentType"
                        render={({ field }) => {
                          return (
                            <FormItem
                              key={item.id}
                              className="flex flex-row items-start"
                            >
                              <div className="flex items-center gap-3">
                                <FormControl>
                                  <Checkbox
                                    checked={field.value?.includes(item.id)}
                                    onCheckedChange={(checked) => {
                                      return checked
                                        ? field.onChange([
                                            ...field.value,
                                            item.id,
                                          ])
                                        : field.onChange(
                                            field.value?.filter(
                                              (value) => value !== item.id
                                            )
                                          );
                                    }}
                                  />
                                </FormControl>
                                <FormLabel className="font-normal">
                                  {item.name}
                                </FormLabel>
                              </div>
                            </FormItem>
                          );
                        }}
                      />
                    ))}
                  </div>
                  <FormMessage />
                </FormItem>
              )}
            />

            <FormField
              control={form.control}
              name="selectedUser"
              render={() => (
                <FormItem>
                  <FormLabel>Target Publish</FormLabel>

                  <div className="flex flex-row items-center gap-2">
                    <div className="flex gap-3 items-center">
                      <Checkbox
                        id="all"
                        checked={isAllUserChecked}
                        onCheckedChange={(checked) => {
                          if (checked) {
                            form.setValue(
                              "selectedUser",
                              userList.map((item) => item.id)
                            );
                          } else {
                            form.setValue("selectedUser", []);
                          }
                        }}
                      />
                      <label htmlFor="all" className="text-sm">
                        Semua
                      </label>
                    </div>
                    {userList.map((item) => (
                      <FormField
                        key={item.id}
                        control={form.control}
                        name="selectedUser"
                        render={({ field }) => {
                          return (
                            <FormItem
                              key={item.id}
                              className="flex flex-row items-start "
                            >
                              <div className="flex items-center gap-3">
                                <FormControl>
                                  <Checkbox
                                    checked={field.value?.includes(item.id)}
                                    onCheckedChange={(checked) => {
                                      return checked
                                        ? field.onChange([
                                            ...field.value,
                                            item.id,
                                          ])
                                        : field.onChange(
                                            field.value?.filter(
                                              (value) => value !== item.id
                                            )
                                          );
                                    }}
                                  />
                                </FormControl>
                                <FormLabel className="font-normal">
                                  {item.name}
                                </FormLabel>
                              </div>
                            </FormItem>
                          );
                        }}
                      />
                    ))}
                  </div>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              control={form.control}
              name="publishTo"
              render={() => (
                <FormItem>
                  <FormLabel>Wilayah Publish</FormLabel>

                  <div className="flex flex-row items-center gap-2">
                    <div className="flex gap-3 items-center">
                      <Checkbox
                        id="all"
                        checked={isAllTargetChecked}
                        onCheckedChange={(checked) => {
                          if (checked) {
                            form.setValue(
                              "publishTo",
                              publishToList.map((item) => item.id)
                            );
                          } else {
                            form.setValue("publishTo", []);
                          }
                        }}
                      />
                      <label htmlFor="all" className="text-sm">
                        Semua
                      </label>
                    </div>
                    {publishToList.map((item) => (
                      <>
                        <FormField
                          key={item.id}
                          control={form.control}
                          name="publishTo"
                          render={({ field }) => {
                            return (
                              <FormItem
                                key={item.id}
                                className="flex flex-row items-start "
                              >
                                <div className="flex items-center gap-3">
                                  <FormControl>
                                    <Checkbox
                                      checked={field.value?.includes(item.id)}
                                      onCheckedChange={(checked) => {
                                        return checked
                                          ? field.onChange([
                                              ...field.value,
                                              item.id,
                                            ])
                                          : field.onChange(
                                              field.value?.filter(
                                                (value) => value !== item.id
                                              )
                                            );
                                      }}
                                    />
                                  </FormControl>
                                  <FormLabel className="font-normal">
                                    {item.name}{" "}
                                  </FormLabel>
                                </div>
                              </FormItem>
                            );
                          }}
                        />
                        {item.id === "polda" &&
                          form.getValues("publishTo")?.includes(item.id) && (
                            <UnitMapping
                              unit="Polda"
                              isDetail={false}
                              sendDataToParent={(data) => setUnitData(data)}
                            />
                          )}
                        {item.id === "satker" &&
                          form.getValues("publishTo")?.includes(item.id) && (
                            <UnitMapping
                              isDetail={false}
                              unit="Satker"
                              sendDataToParent={(data) => setSatkerData(data)}
                            />
                          )}
                      </>
                    ))}
                  </div>
                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              control={form.control}
              name="title"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Nama Kategori</FormLabel>
                  <Input
                    value={field.value}
                    placeholder="Masukkan Nama Kategori"
                    onChange={field.onChange}
                  />

                  <FormMessage />
                </FormItem>
              )}
            />

            <FormField
              control={form.control}
              name="file"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Thumbnail Category</FormLabel>
                  {files.length < 1 && (
                    <Fragment>
                      <div {...getRootProps({ className: "dropzone" })}>
                        <input {...getInputProps()} />
                        <div className=" w-full text-center border-dashed border border-default-200 dark:border-default-300  rounded-md py-[52px] flex  items-center flex-col">
                          <CloudUpload className="text-default-300 w-10 h-10" />
                          <h4 className=" text-2xl font-medium mb-1 mt-3 text-card-foreground/80">
                            Tarik file disini atau klik untuk upload.
                          </h4>
                          <div className=" text-xs text-muted-foreground">
                            ( Upload file dengan format .jpg, .jpeg, atau .png.
                            Ukuran maksimal 100mb.)
                          </div>
                        </div>
                      </div>
                    </Fragment>
                  )}

                  {files.length > 0 && (
                    <div className="flex flex-row gap-2">
                      <img
                        src={URL.createObjectURL(files[0])}
                        className="w-[30%]"
                        alt="thumbnail"
                      />
                      <a
                        onClick={() => handleRemoveFile(files[0])}
                        className="cursor-pointer"
                      >
                        <Icon icon="fa-solid:times" color="red" />
                      </a>
                    </div>
                  )}

                  <FormMessage />
                </FormItem>
              )}
            />
            <FormField
              control={form.control}
              name="description"
              render={({ field }) => (
                <FormItem>
                  <FormLabel>Deskripsi</FormLabel>
                  <FormControl>
                    <Textarea placeholder="Deskripsi" {...field} />
                  </FormControl>

                  <FormMessage />
                </FormItem>
              )}
            />
            <DialogFooter>
              <Button
                type="submit"
                color="primary"
                size="md"
                className="text-xs"
              >
                Tambah Kategori
              </Button>
            </DialogFooter>
          </form>
        </Form>
      </DialogContent>
    </Dialog>
  );
}
