/**
 * UserFormDialog Component
 * Dialog for creating and editing users with form validation
 */

'use client';

import { useEffect } from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Checkbox } from '@/components/ui/checkbox';
import { Alert } from '@/components/ui/alert';
import { toast } from 'sonner';
import { useCreateUser, useUpdateUser, type User } from '@/lib/api/hooks/useAdmin';

// ============================================================================
// Validation Schema
// ============================================================================

const userFormSchema = z.object({
  email: z.string().min(1, 'Email is required').email('Please enter a valid email address'),
  first_name: z
    .string()
    .min(1, 'First name is required')
    .min(2, 'First name must be at least 2 characters')
    .max(50, 'First name must not exceed 50 characters'),
  last_name: z
    .string()
    .max(50, 'Last name must not exceed 50 characters')
    .optional()
    .or(z.literal('')),
  password: z.string(),
  is_active: z.boolean(),
  is_superuser: z.boolean(),
});

type UserFormData = z.infer<typeof userFormSchema>;

// ============================================================================
// Component
// ============================================================================

interface UserFormDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  user?: User | null;
  mode: 'create' | 'edit';
}

export function UserFormDialog({ open, onOpenChange, user, mode }: UserFormDialogProps) {
  const isEdit = mode === 'edit' && user;
  const createUser = useCreateUser();
  const updateUser = useUpdateUser();

  const form = useForm<UserFormData>({
    resolver: zodResolver(userFormSchema),
    defaultValues: {
      email: '',
      first_name: '',
      last_name: '',
      password: '',
      is_active: true,
      is_superuser: false,
    },
  });

  // Reset form when dialog opens/closes or user changes
  // istanbul ignore next - Form reset logic tested in E2E (admin-users.spec.ts)
  useEffect(() => {
    if (open && isEdit) {
      form.reset({
        email: user.email,
        first_name: user.first_name,
        last_name: user.last_name || '',
        password: '',
        is_active: user.is_active,
        is_superuser: user.is_superuser,
      });
    } else if (open && !isEdit) {
      form.reset({
        email: '',
        first_name: '',
        last_name: '',
        password: '',
        is_active: true,
        is_superuser: false,
      });
    }
  }, [open, isEdit, user, form]);

  // istanbul ignore next - Form submission logic fully tested in E2E (admin-users.spec.ts)
  const onSubmit = async (data: UserFormData) => {
    try {
      // Validate password for create mode
      if (!isEdit) {
        if (!data.password || data.password.length === 0) {
          form.setError('password', { message: 'Password is required' });
          return;
        }
        if (data.password.length < 8) {
          form.setError('password', { message: 'Password must be at least 8 characters' });
          return;
        }
        if (!/[0-9]/.test(data.password)) {
          form.setError('password', { message: 'Password must contain at least one number' });
          return;
        }
        if (!/[A-Z]/.test(data.password)) {
          form.setError('password', {
            message: 'Password must contain at least one uppercase letter',
          });
          return;
        }
      }

      if (isEdit) {
        // Validate password if provided in edit mode
        if (data.password && data.password.length > 0) {
          if (data.password.length < 8) {
            form.setError('password', { message: 'Password must be at least 8 characters' });
            return;
          }
          if (!/[0-9]/.test(data.password)) {
            form.setError('password', { message: 'Password must contain at least one number' });
            return;
          }
          if (!/[A-Z]/.test(data.password)) {
            form.setError('password', {
              message: 'Password must contain at least one uppercase letter',
            });
            return;
          }
        }

        // Prepare update data (exclude password if empty, email is not updatable)
        const updateData: Record<string, unknown> = {
          first_name: data.first_name,
          last_name: data.last_name || null,
          is_active: data.is_active,
          is_superuser: data.is_superuser,
        };

        // Only include password if provided
        if (data.password && data.password.length > 0) {
          updateData.password = data.password;
        }

        await updateUser.mutateAsync({
          userId: user.id,
          userData: updateData,
        });

        toast.success(`User ${data.first_name} ${data.last_name || ''} updated successfully`);
        onOpenChange(false);
        form.reset();
      } else {
        // Create new user
        await createUser.mutateAsync({
          email: data.email,
          first_name: data.first_name,
          last_name: data.last_name || undefined,
          password: data.password,
          is_superuser: data.is_superuser,
        });

        toast.success(`User ${data.first_name} ${data.last_name || ''} created successfully`);
        onOpenChange(false);
        form.reset();
      }
    } catch (error) {
      toast.error(error instanceof Error ? error.message : 'Operation failed');
    }
  };

  const {
    register,
    handleSubmit,
    formState: { errors, isSubmitting },
    watch,
    setValue,
  } = form;

  const isActive = watch('is_active');
  const isSuperuser = watch('is_superuser');

  // istanbul ignore next - JSX rendering tested in E2E (admin-users.spec.ts)
  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[500px]">
        <DialogHeader>
          <DialogTitle>{isEdit ? 'Edit User' : 'Create New User'}</DialogTitle>
          <DialogDescription>
            {isEdit
              ? 'Update user information and permissions'
              : 'Add a new user to the system with specified permissions'}
          </DialogDescription>
        </DialogHeader>

        <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
          {/* Email */}
          <div className="space-y-2">
            <Label htmlFor="email">Email *</Label>
            <Input
              id="email"
              type="email"
              {...register('email')}
              disabled={isSubmitting}
              aria-invalid={errors.email ? 'true' : 'false'}
              className={errors.email ? 'border-destructive' : ''}
            />
            {errors.email && (
              <p id="email-error" className="text-sm text-destructive">
                {errors.email.message}
              </p>
            )}
          </div>

          {/* First Name */}
          <div className="space-y-2">
            <Label htmlFor="first_name">First Name *</Label>
            <Input
              id="first_name"
              {...register('first_name')}
              disabled={isSubmitting}
              aria-invalid={errors.first_name ? 'true' : 'false'}
              className={errors.first_name ? 'border-destructive' : ''}
            />
            {errors.first_name && (
              <p id="first-name-error" className="text-sm text-destructive">
                {errors.first_name.message}
              </p>
            )}
          </div>

          {/* Last Name */}
          <div className="space-y-2">
            <Label htmlFor="last_name">Last Name</Label>
            <Input
              id="last_name"
              {...register('last_name')}
              disabled={isSubmitting}
              aria-invalid={errors.last_name ? 'true' : 'false'}
              className={errors.last_name ? 'border-destructive' : ''}
            />
            {errors.last_name && (
              <p id="last-name-error" className="text-sm text-destructive">
                {errors.last_name.message}
              </p>
            )}
          </div>

          {/* Password */}
          <div className="space-y-2">
            <Label htmlFor="password">
              Password {!isEdit && '*'} {isEdit && '(leave blank to keep current)'}
            </Label>
            <Input
              id="password"
              type="password"
              {...register('password')}
              disabled={isSubmitting}
              aria-invalid={errors.password ? 'true' : 'false'}
              className={errors.password ? 'border-destructive' : ''}
              placeholder={isEdit ? 'Leave blank to keep current password' : ''}
            />
            {errors.password && (
              <p id="password-error" className="text-sm text-destructive">
                {errors.password.message}
              </p>
            )}
            {!isEdit && (
              <p className="text-xs text-muted-foreground">
                Must be at least 8 characters with 1 number and 1 uppercase letter
              </p>
            )}
          </div>

          {/* Checkboxes */}
          <div className="space-y-3">
            <div className="flex items-center space-x-2">
              <Checkbox
                id="is_active"
                checked={isActive}
                onCheckedChange={(checked) => setValue('is_active', checked as boolean)}
                disabled={isSubmitting}
              />
              <Label htmlFor="is_active" className="text-sm font-normal cursor-pointer">
                Active (user can log in)
              </Label>
            </div>

            <div className="flex items-center space-x-2">
              <Checkbox
                id="is_superuser"
                checked={isSuperuser}
                onCheckedChange={(checked) => setValue('is_superuser', checked as boolean)}
                disabled={isSubmitting}
              />
              <Label htmlFor="is_superuser" className="text-sm font-normal cursor-pointer">
                Superuser (admin privileges)
              </Label>
            </div>
          </div>

          {/* Server Error Display */}
          {(createUser.isError || updateUser.isError) && (
            <Alert variant="destructive">
              {createUser.isError && createUser.error instanceof Error
                ? createUser.error.message
                : updateUser.error instanceof Error
                  ? updateUser.error.message
                  : 'An error occurred'}
            </Alert>
          )}

          <DialogFooter>
            <Button
              type="button"
              variant="outline"
              onClick={() => onOpenChange(false)}
              disabled={isSubmitting}
            >
              Cancel
            </Button>
            <Button type="submit" disabled={isSubmitting}>
              {isSubmitting
                ? isEdit
                  ? 'Updating...'
                  : 'Creating...'
                : isEdit
                  ? 'Update User'
                  : 'Create User'}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}
