import { useId, useState } from 'react'

import { zodResolver } from '@hookform/resolvers/zod'
import { Controller, useForm } from 'react-hook-form'
import { toast } from 'sonner'

import { createSysUser, updateSysUser } from '@/api'
import { FileUpload } from '@/components/file-upload'
import { Button } from '@/components/ui/button.tsx'
import {
  Dialog,
  DialogClose,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog.tsx'
import { Field, FieldError, FieldGroup, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
import { Spinner } from '@/components/ui/spinner.tsx'
import {
  sysUserFormSchema,
  type SysUser,
  type SysUserFormInput,
  type SysUserFormOutput,
} from '@/schemas'

interface Props {
  currentRow?: SysUser | null
  onClose: () => void
  onConfirm: () => void
  open: boolean
}

export function ActionsDialog({ open, currentRow, onClose, onConfirm }: Props) {
  const isEdit = !!currentRow?.id
  const formId = useId()
  const [loading, setLoading] = useState(false)

  const form = useForm<SysUserFormInput, undefined, SysUserFormOutput>({
    resolver: zodResolver(sysUserFormSchema),
    defaultValues: currentRow
      ? {
          ...currentRow,
          avatar: currentRow.avatar_id
            ? [{ id: currentRow.avatar_id, file_path: currentRow.avatar_url }]
            : [],
        }
      : {
          username: '',
          account: '',
          password: '',
          confirmPassword: '',
          avatar: [],
        },
  })

  const onSubmit = async (values: SysUserFormOutput) => {
    try {
      setLoading(true)

      if (values.id) {
        await updateSysUser(values.id, values)
      } else {
        await createSysUser(values)
      }

      toast('操作成功！')
      onConfirm()
    } finally {
      setLoading(false)
    }
  }

  return (
    <Dialog open={open} onOpenChange={onClose}>
      <DialogContent onCloseAutoFocus={() => form.reset()}>
        <DialogHeader>
          <DialogTitle>{isEdit ? '编辑' : '创建'}用户</DialogTitle>
          <DialogDescription />
        </DialogHeader>

        <form id={formId} onSubmit={form.handleSubmit(onSubmit)}>
          <FieldGroup className='gap-4'>
            <Controller
              name='avatar'
              control={form.control}
              render={({ field, fieldState }) => {
                return (
                  <Field data-invalid={fieldState.invalid}>
                    <FieldLabel>用户头像</FieldLabel>
                    <FileUpload defaultFiles={field.value} onChange={field.onChange} />
                    {fieldState.invalid && <FieldError errors={[fieldState.error]} />}
                  </Field>
                )
              }}
            />

            <Controller
              name='username'
              control={form.control}
              render={({ field, fieldState }) => (
                <Field data-invalid={fieldState.invalid}>
                  <FieldLabel htmlFor='username'>用户名称</FieldLabel>
                  <Input
                    {...field}
                    id='username'
                    aria-invalid={fieldState.invalid}
                    placeholder='请输入用户名称'
                    autoComplete='off'
                  />
                  {fieldState.invalid && <FieldError errors={[fieldState.error]} />}
                </Field>
              )}
            />

            {!isEdit && (
              <>
                <Controller
                  name='account'
                  control={form.control}
                  render={({ field, fieldState }) => (
                    <Field data-invalid={fieldState.invalid}>
                      <FieldLabel htmlFor='account'>账户名称</FieldLabel>
                      <Input
                        {...field}
                        id='account'
                        aria-invalid={fieldState.invalid}
                        placeholder='请输入账户名称'
                        autoComplete='off'
                      />
                      {fieldState.invalid && <FieldError errors={[fieldState.error]} />}
                    </Field>
                  )}
                />
                <Controller
                  name='password'
                  control={form.control}
                  render={({ field, fieldState }) => (
                    <Field data-invalid={fieldState.invalid}>
                      <FieldLabel htmlFor='password'>用户密码</FieldLabel>
                      <Input
                        {...field}
                        id='password'
                        aria-invalid={fieldState.invalid}
                        placeholder='请输入用户密码'
                        autoComplete='off'
                        type='password'
                      />
                      {fieldState.invalid && <FieldError errors={[fieldState.error]} />}
                    </Field>
                  )}
                />
                <Controller
                  name='confirmPassword'
                  control={form.control}
                  render={({ field, fieldState }) => (
                    <Field data-invalid={fieldState.invalid}>
                      <FieldLabel htmlFor='confirmPassword'>确认密码</FieldLabel>
                      <Input
                        {...field}
                        id='confirmPassword'
                        aria-invalid={fieldState.invalid}
                        placeholder='请输入确认密码'
                        autoComplete='off'
                        type='password'
                      />
                      {fieldState.invalid && <FieldError errors={[fieldState.error]} />}
                    </Field>
                  )}
                />
              </>
            )}
          </FieldGroup>
        </form>

        <DialogFooter>
          <DialogClose asChild>
            <Button disabled={loading} variant='outline'>
              取消
            </Button>
          </DialogClose>
          <Button disabled={loading} form={formId} type='submit'>
            保存
            {loading && <Spinner data-icon='inline-start' />}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}
