"use client";
import {
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/shared/ui/form";
import { useTranslations } from "next-intl";
import React, { useEffect, useMemo, useState } from "react";
import { Upload, Spin, Image, UploadFile, UploadProps } from "antd";
import { useFormContext } from "react-hook-form";
import { EditIcon } from "lucide-react";
import AppModal from "../Modal/AppModal";
import { UploadIcon } from "../Icons";
import ShowAlertMixin from "../ShowAlertMixin";
import { getBase64 } from "@/utils/helpers";
import axiosInstanceClient from "@/utils/axiosClient";

type FileType = File;

interface FormUploadProps {
  name: string;
  label?: string;
  uploadText?: string;
  model: string;
  maxCount?: number;
  disabled?: boolean;
  shapeType?: "picture-card" | "text";
  type_file?: "image" | "document" | "media";
  singleFile?: boolean;
  showRequired?: boolean;
  initialFileList?: any;
  onChange?: (fileList: any[]) => void;
  onRemove?: (fileList: any[]) => void;
}

const FormUpload: React.FC<FormUploadProps> = ({
  name,
  label,
  model,
  uploadText,
  maxCount = 1,
  disabled,
  shapeType = "picture-card",
  type_file = "image",
  singleFile,
  showRequired = true,
  initialFileList = [],
  onChange,
  onRemove,
}) => {
  const [fileList, setFileList] = useState<any[]>([]);
  const [previewOpen, setPreviewOpen] = useState(false);
  const [previewContent, setPreviewContent] = useState<string>("");
  const [previewType, setPreviewType] = useState<
    "image" | "video" | "document" | ""
  >("");
  const [loading, setLoading] = useState(false);

  const t = useTranslations("LABELS");
  const form = useFormContext();
  const { getValues } = form;
  const memoizedInitialFileList = useMemo(
    () => initialFileList,
    [JSON.stringify(initialFileList)],
  );

  useEffect(() => {
    setFileList(memoizedInitialFileList);
  }, [memoizedInitialFileList]);
  useEffect(() => {
    if (!getValues(name)) {
      setFileList([]);
      setPreviewContent("");
    }
  }, [getValues(name)]);
  const handlePreview = async (file: UploadFile) => {
    if (type_file === "document") {
      setPreviewType("document");
      setPreviewContent(file.url || (file.preview as string));
    } else if (type_file === "media") {
      const isVideo = file.type?.startsWith("video");
      setPreviewType(isVideo ? "video" : "image");
      if (!file.url && !file.preview) {
        file.preview = await getBase64(file.originFileObj as FileType);
      }
      setPreviewContent(file.url || (file.preview as string));
    } else {
      setPreviewType("image");
      if (!file.url && !file.preview) {
        file.preview = await getBase64(file.originFileObj as FileType);
      }
      setPreviewContent(file.url || (file.preview as string));
    }
    setPreviewOpen(true);
  };
  const handleChange: UploadProps["onChange"] = async ({
    fileList: newFileList,
  }) => {
    try {
      setLoading(true);
      for (let file of newFileList as any) {
        if (fileList.some((f: any) => f.name === file.name)) {
          continue;
        }
        let attachmentType = "";
        if (file.type.startsWith("image/")) {
          attachmentType = "image";
        } else if (file.type.startsWith("video/")) {
          attachmentType = "video";
        } else {
          attachmentType = "file";
        }

        const formData = new FormData();
        formData.append("file", file.originFileObj);
        formData.append("attachment_type", attachmentType);
        formData.append("collection", model);

        try {
          const { data } = await axiosInstanceClient.post(
            "/media/upload",
            formData,
            { headers: { "Content-Type": "multipart/form-data" } },
          );
          if (data) {
            file.status = "done";
            setFileList((prevList: any) => [...prevList, file]);
            if (onChange) {
              onChange(data?.data);
            } else {
              form.setValue(name, data?.data?.hash);
            }
          }
        } catch (error: any) {
          ShowAlertMixin({
            icon: "error",
            title: error?.response?.data.message,
          });
          console.error("Error uploading file:", error);
        }
      }
    } catch (error: any) {
      ShowAlertMixin({
        icon: "error",
        title: error?.response?.data.message,
      });
    } finally {
      setLoading(false);
    }
  };

  const handleRemove = async (file: UploadFile) => {
    if (file?.uid) {
      const isLocalFile =
        typeof file?.uid === "string" &&
        (file?.uid.startsWith("rc-upload") || file?.uid.startsWith("__AUTO__"));
      if (isLocalFile) {
        const updatedFiles = fileList.filter(
          (item: any) => item.uid !== file.uid,
        );
        setFileList(updatedFiles);
        form.setValue(name, updatedFiles);
        if (onRemove) {
          onRemove(updatedFiles);
        }
        return;
      }
      try {
        const updatedFiles = fileList.filter(
          (item: any) => item.uid !== file.uid,
        );
        setFileList(updatedFiles);
        form.setValue(name, updatedFiles);

        if (onRemove) {
          onRemove(updatedFiles);
        }
      } catch (error: any) {
        ShowAlertMixin({
          icon: "error",
          title: error?.response?.data.message,
        });
      }
    }
  };

  const uploadButton = (
    <button
      type="button"
      className="bg-transparent border-none flex flex-col items-center justify-center  cursor-pointer "
    >
      {fileList.length !== 0 && singleFile ? (
        <div className="absolute bottom-0 start-0">
          <EditIcon />
        </div>
      ) : (
        <div className="flex-col justify-center items-center text-[#818C92] gap-2.5 inline-flex">
          <UploadIcon />
          {uploadText}
        </div>
      )}
    </button>
  );
  const beforeUpload = (file: FileType) => {
    if (type_file === "document") {
      // Allowed mime types for document
      // const allowedTypes = ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'];
      const allowedTypes = ["application/pdf"];
      if (!allowedTypes.includes(file.type)) {
        ShowAlertMixin({
          icon: "error",
          title: t("Messages.onlyPdfAllowed"),
        });
        return Upload.LIST_IGNORE;
      }
    }
    return true;
  };
  return (
    <FormField
      control={form.control}
      name={name}
      render={() => (
        <FormItem>
          <div className="flex items-center gap-2">
            {label && (
              <FormLabel className=" text-text-primary font-medium text-sm leading-6 px-4 ">
                {t(label)}
                {showRequired && (
                  <span className="text-error mx-1 text-lg translate-y-1 inline-block">
                    *
                  </span>
                )}
              </FormLabel>
            )}
          </div>
          <FormControl>
            <Spin spinning={loading}>
              <Upload
                customRequest={() => ""}
                listType={shapeType}
                fileList={fileList}
                onPreview={handlePreview}
                onChange={handleChange}
                onRemove={handleRemove}
                beforeUpload={beforeUpload}
                accept={
                  type_file === "media"
                    ? "image/*,video/*"
                    : type_file === "image"
                      ? "image/*"
                      : ".pdf,.doc,.docx"
                }
                className={`${
                  type_file === "image"
                    ? "image-uploader"
                    : type_file === "media"
                      ? fileList.length < 1
                        ? "file-uploader"
                        : "image-uploader"
                      : "file-uploader"
                }`}
                disabled={disabled}
                maxCount={maxCount}
              >
                {fileList.length >= maxCount ? null : uploadButton}
              </Upload>
            </Spin>
          </FormControl>
          <FormMessage />
          {previewOpen && (
            <AppModal
              isModalVisible={previewOpen}
              width={previewType === "document" ? "80%" : "fit-content"}
              getContainer={"html"}
              onCancel={() => setPreviewOpen(false)}
              centered
              key="app-Preview-modal"
            >
              {previewType === "video" ? (
                <video controls style={{ width: "100%" }}>
                  <source src={previewContent} type="video/mp4" />
                </video>
              ) : previewType === "document" ? (
                <iframe
                  src={previewContent}
                  style={{ width: "100%", height: "500px", border: "none" }}
                />
              ) : (
                <Image
                  wrapperStyle={{ display: "none" }}
                  preview={{
                    visible: previewOpen,
                    onVisibleChange: (v) => setPreviewOpen(v),
                    afterOpenChange: (v) => !v && setPreviewContent(""),
                  }}
                  src={previewContent}
                />
              )}
            </AppModal>
          )}
        </FormItem>
      )}
    />
  );
};

export default FormUpload;
