/* eslint-disable no-console */
import { yupResolver } from '@hookform/resolvers/yup'
import { Stack } from '@mui/material'
import { useEffect, useState } from 'react'
import { useForm } from 'react-hook-form'
import { useMutation, useQuery } from 'react-query'
import { toast } from 'react-toastify'
import { useImmer } from 'use-immer'
import * as yup from 'yup'
import axios, { axiosErrorToast } from '../../../config/axios'
import { queryClient } from '../../../contexts/QueryClientProvider'
import ActionButton from '../../ActionButton'
import { FormSingleSelect, FormTextField } from '../../HookForm'
import ImageUpload from '../../ImageUpload'
import MediaRow from '../../MediaRow/MediaRow'
import { Media } from '../../UploadButton/types'
import FileUpload from '../FileUpload'
import {
  createUpdatePaperPublicaton,
  getPaperPublicationSubtypes,
} from '../service'
import Authors from './Authors'
const authorsSelect = [
  {
    label: 'Single Author',
    value: 'singleAuthor',
  },
  {
    label: 'Multiple Authors',
    value: 'multipleAuthors',
  },
]

const schema = yup.object().shape({
  title: yup.string().required('Title is required'),
  publicationType: yup.string().required('Publication Type is required'),
  publicationYear: yup
    .number()
    .typeError('Year of Publication must be a number')
    .required('Year of Publication is required'),
  stream: yup.string().required('Stream is required'),
  program: yup.string().required('Program is required'),
})

export const PublicationsForm = ({ data, hideDialog, userProfile = null }) => {
  const { control, handleSubmit, watch, setValue } = useForm({
    resolver: yupResolver(schema),
    defaultValues: {
      ...data,
      authors: [{ name: userProfile?.fullName || '' }],
    },
  })

  const [media, setMedia] = useState<Media[]>([])
  const [state, setState] = useImmer({
    resource: data?.attachments || [],
    selectedAuthor: 'singleAuthor',
    publicationSubtypes: [],
  })

  const { resource, selectedAuthor, publicationSubtypes } = state

  const { data: paperPublicationTypes } = useQuery(
    'paper-publication-type',
    () =>
      axios.get('/square/paper-publications/types').then((res) => res?.data),
    {
      onSuccess: (res) => {
        const isOthersCheck = res.includes(data?.publicationType)
        setValue(
          'publicationType',
          isOthersCheck ? data?.publicationType : 'Other',
        )

        setValue(
          'publicationOtherType',
          isOthersCheck ? '' : data?.publicationType,
        )
      },
    },
  )

  const { mutate: fetchPublicationSubtypes } = useMutation(
    getPaperPublicationSubtypes,
    {
      onSuccess: (data) => {
        setState((s) => {
          s.publicationSubtypes = data
        })
      },
    },
  )
  const { mutate, isLoading } = useMutation(createUpdatePaperPublicaton, {
    onSuccess: () => {
      toast.success(data ? 'Publication Updated' : 'Publication Added')
      queryClient.invalidateQueries('dashboard')
      hideDialog()
    },
    onError: (err) => {
      console.log(err)
      axiosErrorToast(err)
    },
  })

  useEffect(() => {
    fetchPublicationSubtypes(watch('publicationType'))
    data && data?.image?.key
      ? setMedia([
          {
            key: data?.image?.key,
            url: data?.image?.url,
            type: data?.image?.mediaType,
          },
        ])
      : setMedia([])

    setState((s) => {
      s.selectedAuthor =
        data?.authors?.length > 1 ? 'multipleAuthors' : 'singleAuthor'
    })

    setValue(
      'authors',
      data?.authors?.map((author) => ({ name: author })),
    )
  }, [data, setValue])

  const onSubmit = (formData) => {
    const isOthers = formData.publicationType === 'Other'
    const postBody = {
      ...formData,
      authors:
        selectedAuthor === 'singleAuthor'
          ? [userProfile?.fullName]
          : formData?.authors?.map((author) => author?.name),
      publicationType: isOthers
        ? formData.publicationOtherType
        : formData.publicationType,
      publicationSubtype: isOthers ? 'other' : formData.publicationSubtype,
      image: media[0]?.key || null,
      attachments: state.resource.map((file) => file.key),
    }
    mutate(postBody)
  }

  const onError = (error) => {
    console.log(error)
  }

  const handleImageChange = (v) => {
    setMedia([{ type: 'image', url: v.url, key: v.key }])
  }

  const handleDeleteImage = (key) => {
    setMedia((prev) => prev.filter((m) => m.key !== key))
  }

  const handleFileInput = (e) => {
    let filesData = e.target.files
    let fileArray = Object.keys(filesData)
    fileArray.forEach(async (file) => {
      const fileData = new FormData()
      fileData.append('file', filesData[file])
      const originalFileName = filesData[file].name

      try {
        let fileKey = await axios.post(
          `/square/paper-publications/attachment`,
          fileData,
        )
        setState((s) => {
          s.resource.push({
            originalFileName: originalFileName,
            key: fileKey?.data?.key,
          })
        })
      } catch (error) {
        console.log(error)
      }
    })
  }

  const onDelete = (fileKey) => {
    setState((s) => {
      s.resource = resource.filter((item) => item.key !== fileKey)
    })
  }

  return (
    <form onSubmit={handleSubmit(onSubmit, onError)}>
      <Stack gap={2.5}>
        <>
          {!media.length ? (
            <ImageUpload
              key={media.length}
              onFileUploaded={handleImageChange}
              postUrl="/square/paper-publications/image"
            />
          ) : (
            <MediaRow list={media} onDelete={handleDeleteImage} />
          )}
          <FormTextField
            control={control}
            name="title"
            label="Title"
            required
          />

          <Authors
            control={control}
            selectedAuthor={selectedAuthor}
            setState={setState}
            authorsSelect={authorsSelect}
            userName={userProfile?.fullName}
            watch={watch}
            setValue={setValue}
          />

          <FormSingleSelect
            name="publicationType"
            label="Publication Type"
            control={control}
            options={paperPublicationTypes?.map((item) => ({
              value: item,
              label: item,
            }))}
            required
            onChange={(e) => {
              setValue('publicationType', e.target.value)
              fetchPublicationSubtypes(e.target.value)
            }}
          />
          {watch('publicationType') === 'Other' ? (
            <FormTextField
              name="publicationOtherType"
              label="Publication Type Name"
              control={control}
              required
            />
          ) : (
            <FormSingleSelect
              name="publicationSubtype"
              label="Sub Type"
              control={control}
              options={publicationSubtypes?.map((item) => ({
                value: item,
                label: item,
              }))}
              required
            />
          )}
          <FormTextField
            name="publicationYear"
            label="Year of Publication"
            control={control}
            required
          />
          <FormTextField
            name="stream"
            label="Stream"
            control={control}
            required
          />
          <FormTextField
            name="program"
            label="Program"
            control={control}
            required
          />
          <FileUpload
            handleFileInput={handleFileInput}
            onDelete={onDelete}
            resource={resource}
          />
        </>
      </Stack>
      <Stack direction="row" gap={2} mt={3}>
        <ActionButton type="submit" fullWidth loading={isLoading}>
          {data ? 'Edit' : 'Submit'}
        </ActionButton>
        <ActionButton variant="outlined" fullWidth onClick={() => hideDialog()}>
          Cancel
        </ActionButton>
      </Stack>
    </form>
  )
}

export default PublicationsForm
