import {REG_REMOVE_EXTENSION, IFile} from "@fanam-pkg/core-utils"
import {ChangeEvent} from "react"
import {assets} from "../../assets"
import {ImageView} from "../../atoms"
import {useNotifyPopup} from "../../hooks"
import {FileUploadProps, FormValueType} from "../../props"
import styles from "./styles.module.sass"

export const FileUpload = ({
  wrapperClass = "",
  children,
  isMultiple = false,
  onChangeData,
  name,
  error,
  maxSize = 500000,
  inputClassName = "",
  fileType = "image/*",
  disabled,
}: FileUploadProps) => {
  const {toggleNotify} = useNotifyPopup()

  const onChangeValue = async (event: ChangeEvent<HTMLInputElement>) => {
    const files = Array.from(event.target.files || [])
    if (files.length) {
      const toBase64 = (file: File): Promise<IFile> => {
        return new Promise((resolve, reject) => {
          if (file.size < maxSize) {
            const reader = new FileReader()
            reader.readAsDataURL(file)
            reader.onload = () =>
              resolve({base64: reader.result as string, fileName: file.name.replace(REG_REMOVE_EXTENSION, ""), file})
            reader.onerror = error => {
              console.error(">>>>>>>>>>>>>>>>>> Error while parsing file to base64: ", file, error)
              reject(error)
            }
          } else {
            toggleNotify({
              title: "File size validation!",
              description: `Please choose a file within ${Math.ceil(maxSize / 1000)}KB`,
              type: "error",
            })
          }
        })
      }

      const filePathsPromises: Promise<IFile>[] = []
      files.forEach(file => filePathsPromises.push(toBase64(file)))
      const filePaths = await Promise.all(filePathsPromises)
      const mappedFiles = filePaths.filter(base64File => base64File) as FormValueType[]
      if (mappedFiles.length && onChangeData) {
        if (isMultiple) {
          onChangeData(name ? {[name]: mappedFiles} : (mappedFiles as FormValueType))
        } else onChangeData(name ? {[name]: mappedFiles[0]} : mappedFiles[0])
      }
      event.target.value = ""
    }
  }

  return (
    <div className={`${styles.file_upload_container} ${wrapperClass}`}>
      <section className={`${styles.upload_content} flex-col-center`}>
        {children || (
          <>
            <ImageView src={assets.ic_upload} alt="upload-image" imgSize={16} />
            <label className={`${styles.choose_file} ${disabled ? styles.text_undisable : styles.text_disable}`}>
              Drag and drop file here
            </label>
            <label className={`${styles.drag_file} ${disabled ? styles.text_undisable : styles.text_disable}`}>
              or
            </label>
            <label className={disabled ? styles.text_undisable : styles.text_disable}>Click to browse files</label>
          </>
        )}
      </section>
      <input
        type="file"
        className={`${styles.file_upload} ${inputClassName}`}
        onChange={onChangeValue}
        multiple={isMultiple}
        disabled={disabled}
        accept={typeof fileType === "string" ? fileType : fileType?.join(",")}
      />
      {error && <p className="error-text">{error}</p>}
    </div>
  )
}
