import React, {
  forwardRef,
  useCallback,
  useImperativeHandle,
  useRef,
  useState,
  type ReactElement,
  type Ref,
} from 'react'
import type { FieldValues } from 'react-hook-form'
import { Modal, ScrollArea } from '@mantine/core'
import type { SuperFormModalProps, SuperFormModalRef, SuperFormRef } from '../../types'
import SuperForm from '../../components/SuperForm'
import { openConfirmModal } from '../../utils/openConfirmModal'

const SuperFormModal = <T extends FieldValues>(
  { modalProps, noCloseOnSubmit, ...formProps }: SuperFormModalProps<T>,
  ref: Ref<SuperFormModalRef<T>>
) => {
  // Component Refs
  const modalRef = useRef<HTMLDivElement>(null)
  const formRef = useRef<SuperFormRef<T>>(null)

  // Component store State
  // Tell drawer that form layout mounted to fix refs
  const [layoutMounted, setLayoutMounted] = useState(false)

  // Component Callback Functions
  const onSubmit = (data: T, request, formData, form, closeForm: boolean = true) => {
    formProps?.onSubmit?.(data, request, formData, form, closeForm)

    if (request === 'delete') {
      modalProps?.onClose()
    }

    if (!noCloseOnSubmit) {
      if (closeForm) {
        modalProps?.onClose()
      }
    }
  }

  const onCancel = (request) => {
    if (formRef?.current?.getFormState().isDirty) {
      openConfirmModal(() => {
        modalProps?.onClose()
        formProps?.onCancel?.(request)
      })
    } else {
      modalProps?.onClose()
      formProps?.onCancel?.(request)
    }
  }

  const onLayoutMounted = useCallback(() => {
    setLayoutMounted(true)
    formProps?.onLayoutMounted?.()
  }, [formProps?.onLayoutMounted])

  const onLayoutUnMounted = useCallback(() => {
    setLayoutMounted(false)
    formProps?.onLayoutUnMounted?.()
  }, [formProps?.onLayoutUnMounted])

  // Component use Effects
  useImperativeHandle<SuperFormModalRef<T>, SuperFormModalRef<T>>(
    ref,
    () => ({
      ...formRef.current,
      modal: modalRef.current,
    } as SuperFormModalRef<T>),
    [layoutMounted]
  )

  return (
    <Modal
      ref={modalRef}
      closeOnClickOutside={false}
      overlayProps={{
        backgroundOpacity: 0.5,
        blur: 4,
      }}
      padding='sm'
      scrollAreaComponent={ScrollArea.Autosize}
      size={500}
      keepMounted={false}
      {...modalProps}
    >
      <SuperForm<T>
        {...formProps}
        onCancel={onCancel}
        onSubmit={onSubmit}
        onLayoutMounted={onLayoutMounted}
        onLayoutUnMounted={onLayoutUnMounted}
        ref={formRef}
      />
    </Modal>
  )
}

const FRSuperFormModal = forwardRef(SuperFormModal) as <T extends FieldValues>(
  props: SuperFormModalProps<T> & { ref?: Ref<SuperFormModalRef<T>> }
) => ReactElement

export default FRSuperFormModal
