'use client';

import { useRef, type ComponentProps } from 'react';
import {
  Controller,
  type Control,
  type FieldErrors,
  type UseFormRegister,
} from 'react-hook-form';
import { Loader2 } from 'lucide-react';

import { FormField, PhoneInput } from '@/components/form';
import { RoleSelect } from '@/components/lookups/RoleSelect';
import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogBody,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import type { UserFormValues } from '../hooks/useUserForm';

interface UserSheetProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  userId?: number;
  register: UseFormRegister<UserFormValues>;
  control: Control<UserFormValues>;
  errors: FieldErrors<UserFormValues>;
  isSubmitted: boolean;
  onSubmit: ComponentProps<'form'>['onSubmit'];
  roleId: string;
  onRoleChange: (roleId: string) => void;
  canSubmit: boolean;
  isSaving: boolean;
}

export function UserSheet({
  open,
  onOpenChange,
  userId,
  register,
  control,
  errors,
  isSubmitted,
  onSubmit,
  roleId,
  onRoleChange,
  canSubmit,
  isSaving,
}: UserSheetProps) {
  const roleComboboxPortalRef = useRef<HTMLDivElement | null>(null);
  const firstNameErrorMessage = isSubmitted
    ? errors.first_name?.message
    : undefined;
  const lastNameErrorMessage = isSubmitted
    ? errors.last_name?.message
    : undefined;
  const emailErrorMessage = isSubmitted ? errors.email?.message : undefined;
  const phoneErrorMessage = isSubmitted
    ? errors.phone_number?.message
    : undefined;
  const roleErrorMessage = isSubmitted ? errors.role_id?.message : undefined;

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-xl">
        <DialogHeader>
          <DialogTitle>
            {userId ? 'Edit User' : 'Create User'}
          </DialogTitle>

          <DialogDescription>
            Assign user details and a role.
          </DialogDescription>
        </DialogHeader>

        <form
          noValidate
          onSubmit={onSubmit}
          className="flex min-h-0 flex-1 flex-col"
        >
          <DialogBody className="space-y-5">
            <div className="grid gap-4 md:grid-cols-2">
              <FormField
                id="first-name"
                label="First Name"
                required
                error={firstNameErrorMessage}
              >
                <Input
                  id="first-name"
                  placeholder="Enter first name"
                  aria-invalid={!!firstNameErrorMessage}
                  {...register('first_name')}
                />
              </FormField>

              <FormField
                id="last-name"
                label="Last Name"
                required
                error={lastNameErrorMessage}
              >
                <Input
                  id="last-name"
                  placeholder="Enter last name"
                  aria-invalid={!!lastNameErrorMessage}
                  {...register('last_name')}
                />
              </FormField>
            </div>

            <div className="grid gap-4 md:grid-cols-2">
              <FormField
                id="email"
                label="Email"
                required
                error={emailErrorMessage}
              >
                <Input
                  id="email"
                  placeholder="name@example.com"
                  aria-invalid={!!emailErrorMessage}
                  {...register('email')}
                />
              </FormField>

              <FormField
                id="phone-number"
                label="Phone Number"
                error={phoneErrorMessage}
              >
                <Controller
                  control={control}
                  name="phone_number"
                  render={({ field }) => (
                    <PhoneInput
                      value={field.value}
                      onChange={field.onChange}
                      onBlur={field.onBlur}
                      placeholder="Enter phone number"
                      aria-invalid={!!phoneErrorMessage}
                      portalContainer={roleComboboxPortalRef}
                    />
                  )}
                />
              </FormField>
            </div>

            <FormField
              id="role"
              label="Role"
              required
              error={roleErrorMessage}
            >
              <RoleSelect
                value={roleId}
                onValueChange={onRoleChange}
                enabled={open}
                disabled={isSaving}
                portalContainer={roleComboboxPortalRef}
              />

              <input
                type="hidden"
                {...register('role_id')}
                value={roleId}
              readOnly
            />
          </FormField>
          </DialogBody>

          <DialogFooter>
            <Button
              type="button"
              variant="outline"
              onClick={() => onOpenChange(false)}
              disabled={isSaving}
            >
              Cancel
            </Button>

            <Button type="submit" disabled={isSaving || !canSubmit}>
              {isSaving ? (
                <Loader2 className="mr-2 size-4 animate-spin" />
              ) : null}

              {userId ? 'Update User' : 'Create User'}
            </Button>
          </DialogFooter>
        </form>

        <div ref={roleComboboxPortalRef} />
      </DialogContent>
    </Dialog>
  );
}
