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 Input from './input.tsx'
import Message from './message.tsx'
import sutil from './utility.module.scss'

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

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

    actions.pending()

    try {
      const result = await rek[role ? 'patch' : 'post'](
        `/api/roles${role ? '/' + role.id : ''}`,
        serializeForm(e.currentTarget),
      )

      actions.success()

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

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

      <Input name='name' label='Name' type='text' defaultValue={role?.name} required />

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

export default RoleForm
