import React, {
  forwardRef,
  useCallback,
  useImperativeHandle,
  useRef,
  useState,
  type ReactElement,
  type Ref,
} from 'react'
import { IconX } from '@tabler/icons-react'
import type { FieldValues } from 'react-hook-form'
import { ActionIcon, Drawer } from '@mantine/core'
import type { SuperFormDrawerProps, SuperFormDrawerRef, SuperFormRef } from '../../types'
import SuperForm from '../../components/SuperForm'
import { openConfirmModal } from '../../utils/openConfirmModal'

const SuperFormDrawer = <T extends FieldValues>(
  { drawerProps, noCloseOnSubmit, ...formProps }: SuperFormDrawerProps<T>,
  ref: Ref<SuperFormDrawerRef<T>>
) => {
  // Component Refs
  const formRef = useRef<SuperFormRef<T>>(null)
  const drawerRef = useRef<HTMLDivElement>(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') {
      drawerProps?.onClose()
    }

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

  const onCancel = (request) => {
    if (formRef?.current?.getFormState().isDirty) {
      openConfirmModal(() => {
        drawerProps?.onClose()
        formProps?.onCancel?.(request)
      })
    } else {
      drawerProps?.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<SuperFormDrawerRef<T>, SuperFormDrawerRef<T>>(
    ref,
    () => ({
      ...formRef.current,
      drawer: drawerRef.current,
    } as SuperFormDrawerRef<T>),
    [layoutMounted]
  )

  return (
    <Drawer
      ref={drawerRef}
      onClose={onCancel}
      closeOnClickOutside={false}
      onKeyDown={(e) => {
        if (e.key === 'Escape' && drawerProps.closeOnEscape !== false) {
          e.stopPropagation()
          onCancel(formProps.request)
        }
      }}
      overlayProps={{ backgroundOpacity: 0.5, blur: 0.5 }}
      padding={6}
      position='right'
      transitionProps={{
        transition: 'slide-left',
        duration: 150,
        timingFunction: 'linear',
      }}
      size={500}
      styles={{
        content: {
          display: 'flex',
          flexDirection: 'column',
          justifyContent: 'stretch',
        },
        body: {
          minHeight: '100px',
          flexGrow: 1,
        },
      }}
      keepMounted={false}
      {...drawerProps}
      closeOnEscape={false}
      withCloseButton={false}
      title={null}
    >
      <SuperForm<T>
        {...formProps}
        onCancel={onCancel}
        onSubmit={onSubmit}
        onLayoutMounted={onLayoutMounted}
        onLayoutUnMounted={onLayoutUnMounted}
        ref={formRef}
        layoutProps={{
          ...formProps?.layoutProps,
          rightSection: (
            <ActionIcon
              size='xs'
              onClick={() => {
                onCancel(formProps?.request)
              }}
            >
              <IconX size={18} />
            </ActionIcon>
          ),
          title:
            (drawerProps.title as string) ??
            formProps?.layoutProps?.title ??
            (formProps?.request as string),
        }}
      />
    </Drawer>
  )
}

const FRSuperFormDrawer = forwardRef(SuperFormDrawer) as <T extends FieldValues>(
  props: SuperFormDrawerProps<T> & { ref?: Ref<SuperFormDrawerRef<T>> }
) => ReactElement

export default FRSuperFormDrawer
