import { h, type FunctionComponent, type TargetedSubmitEvent } from 'preact'
import { useCallback } from 'preact/hooks'
import rek, { type FetchError } from 'rek'

import useRequestState from '../../shared/hooks/use_request_state.ts'
import serializeForm from '../../shared/utils/serialize_form.ts'
import Button from './button.tsx'
import Checkbox from './checkbox.tsx'
import Input from './input.tsx'
import Message from './message.tsx'
import sutil from './utility.module.scss'

const AdmissionForm: FunctionComponent<{
  admission?: ANY
  onCancel?: ANY
  onCreate?: ANY
  onUpdate?: ANY
  roles?: ANY[]
}> = ({ admission, onCancel, onCreate, onUpdate, roles }) => {
  const [{ error, pending, success }, actions] = useRequestState<FetchError>()

  const create = useCallback(async (e: TargetedSubmitEvent<HTMLFormElement>) => {
    e.preventDefault()

    actions.pending()

    try {
      const form = e.currentTarget

      const result = await rek[admission ? 'patch' : 'post'](
        `/api/admissions${admission ? '/' + admission.id : ''}`,
        serializeForm(form),
      )

      actions.success()

      if (admission) {
        onUpdate?.(result)
      } else {
        form.reset()
        onCreate?.(result)
      }
    } catch (err) {
      actions.error(err as FetchError)
    }
  }, [])

  return (
    <form onSubmit={create}>
      {success && (
        <Message type='success' dismiss={actions.reset}>
          Admission {admission ? 'updated' : 'created'}!
        </Message>
      )}
      {error && (
        <Message type='error' dismiss={actions.reset}>
          {error.status || 500} {error.body?.message || error.message}
        </Message>
      )}

      <Input name='regex' label='Regex' type='text' defaultValue={admission?.regex} required />
      {roles && (
        <div>
          {roles.map((role) => (
            <Checkbox
              key={role.id}
              name='roles'
              label={role.name}
              value={role.id}
              defaultChecked={!!admission?.roles.find((r: ANY) => r.id === role.id)}
            />
          ))}
        </div>
      )}

      <div className={sutil.row}>
        <Button disabled={pending} type='submit'>
          {admission ? 'Update' : 'Create'}
        </Button>
        {onCancel && (
          <Button disabled={pending} onClick={onCancel} type='button'>
            Cancel
          </Button>
        )}
      </div>
    </form>
  )
}

export default AdmissionForm
