import { yupResolver } from '@hookform/resolvers/yup'
import { Stack } from '@mui/material'
import { useEffect } from 'react'
import { useForm } from 'react-hook-form'
import { useMutation, useQuery, useQueryClient } from 'react-query'
import { toast } from 'react-toastify'
import { useImmer } from 'use-immer'
import axios, { axiosErrorToast } from '../../config/axios'
import ActionButton from '../ActionButton'
import { FormMultiSelect, FormSingleSelect } from '../HookForm'
import Spinner from '../Spinner'
import {
  editUserProfileSchema,
  fetchUsers,
  updateCreateUserApplicationProfile,
  userProfileSchema,
} from './services'
import { useErrorModal } from '../ErrorModalWrapper/ErrorModalWrapper'
interface UserProps {
  options: {
    label: any
    value: any
  }[]
  inputValue: string
}
const getDepartments = () => {
  return axios.get('/hrms/departments').then((res) => res?.data?.data)
}
function UserProfileRelation({ close, application, profiles, data }) {
  const errorModal = useErrorModal()
  const [state, setState] = useImmer<UserProps>({
    options: [],
    inputValue: '',
  })
  const queryClient = useQueryClient()
  const { data: departments, isLoading } = useQuery('get-department', () =>
    getDepartments(),
  )

  const { control, handleSubmit, watch } = useForm({
    defaultValues: {
      profileIds:
        data?.profiles?.map((profile) => ({
          label: profile.name,
          value: profile.id,
        })) ?? [],
      departmentId: null,
    },
    resolver: yupResolver(data ? editUserProfileSchema : userProfileSchema),
  })

  const { mutate, isLoading: creatingUserProfile } = useMutation(
    updateCreateUserApplicationProfile,
    {
      onSuccess: (res) => {
        queryClient.invalidateQueries(`application-users`)
        toast.success(`User profile ${data ? 'updated' : 'added'} successfully`)
        close()
      },
      onError: (err) => {
        // eslint-disable-next-line no-console
        console.log(err)
        // axiosErrorToast(err)
        errorModal({ error: err })
      },
    },
  )

  useEffect(() => {
    if (watch('departmentId')) {
      fetchUsersFn({
        application: application,
        departmentId: watch('departmentId'),
      })
    }
  }, [watch('departmentId')])

  const { mutate: fetchUsersFn, isLoading: gettingUsers } = useMutation(
    fetchUsers,
    {
      onSuccess: (res) => {
        setState((s) => {
          s.options = res.result?.map((item) => ({
            label: `${item.fullName} ( ${item.email} )`,
            value: item.id,
          }))
        })
      },
    },
  )
  const onSubmit = (formData) => {
    mutate({
      userIds: formData?.userId?.map((userId) => +userId.value) ?? [],
      application: application,
      profileIds: formData.profileIds?.map((profile) => profile.value) ?? [],
      ...(data && { userId: data?.id }),
    })
  }
  const onError = (err) => {
    // eslint-disable-next-line no-console
    console.log(err)
  }

  const handleInputChange = (e) => {
    //TODO : debounce
    if (e) {
      setState((s) => {
        s.inputValue = e.target.value
      })
      if (e.target.value.length >= 3) {
        fetchUsersFn({
          application: application,
          search: e.target.value,
          departmentId: watch('departmentId') ?? null,
        })
      }
    }
  }

  if (isLoading) {
    return <Spinner />
  }

  return (
    <>
      <form onSubmit={handleSubmit(onSubmit, onError)}>
        <Stack gap={4} sx={{ padding: '10px' }}>
          {!data && (
            <FormSingleSelect
              control={control}
              name="departmentId"
              label="Department"
              options={departments?.map((department) => ({
                label: department.name,
                value: department._id,
              }))}
            />
          )}

          {!data && (
            <FormMultiSelect
              label={'User'}
              name={'userId'}
              onInputChange={handleInputChange}
              loading={gettingUsers}
              control={control}
              options={state.options ?? []}
              required
            />
          )}

          <FormMultiSelect
            label={'Profile'}
            name={'profileIds'}
            control={control}
            options={
              profiles?.map((profile) => ({
                label: profile.name,
                value: profile.id,
              })) ?? []
            }
            required
          />
          <Stack gap={2} direction={'row'} sx={{ justifyContent: 'flex-end' }}>
            <ActionButton variant="outlined" onClick={close}>
              Cancel
            </ActionButton>
            <ActionButton type="submit" loading={creatingUserProfile}>
              Confirm
            </ActionButton>
          </Stack>
        </Stack>
      </form>
    </>
  )
}
export default UserProfileRelation
