import { UserPlus } from 'lucide-react';
import React from 'react';

import { store as userStore } from '@/actions/App/Domains/Shared/Http/Controllers/Admin/UserController';

import PasswordInput from '@/components/PasswordInput';
import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { useYupForm } from '@/hooks/use-yup-form';
import { NIK_PATTERN, NIK_TITLE, PASSWORD_HINT } from '@/lib/field-constraints';
import { userCreateSchema } from '@/lib/validation/user';
import type { DivisionOption } from '@/types/admin';

/** Nilai select yang berarti "tidak ditempatkan di divisi mana pun". */
const NO_DIVISION = 'none';

interface UserCreateDialogProps {
    divisions: DivisionOption[];
    divisionRoleOptions: string[];
    open: boolean;
    onOpenChange: (open: boolean) => void;
}

export function UserCreateDialog({
    divisions,
    divisionRoleOptions,
    open,
    onOpenChange,
}: UserCreateDialogProps) {
    const {
        data,
        setData,
        processing,
        errors,
        reset,
        clearErrors,
        validateField,
        submit,
    } = useYupForm(userCreateSchema, {
        name: '',
        nik: '',
        email: '',
        password: '',
        password_confirmation: '',
        division_id: null as number | null,
        role_type: divisionRoleOptions[0] ?? 'member',
        role_label: '',
    });

    const close = () => {
        reset();
        clearErrors();
        onOpenChange(false);
    };

    const handleSubmit = (e: React.FormEvent) => {
        e.preventDefault();

        submit((form) =>
            form.post(userStore().url, {
                preserveScroll: true,
                onSuccess: close,
            }),
        );
    };

    return (
        <Dialog
            open={open}
            onOpenChange={(next) => (next ? onOpenChange(true) : close())}
        >
            <DialogContent className="flex max-h-[calc(100dvh-4rem)] flex-col sm:max-w-125 [&>button:last-child]:hidden">
                <DialogHeader>
                    <DialogTitle className="flex items-center gap-2">
                        <UserPlus className="h-5 w-5" />
                        Add User
                    </DialogTitle>
                    <DialogDescription>
                        The password you set here is temporary — the user will
                        be forced to change it on their first login.
                    </DialogDescription>
                </DialogHeader>

                <form
                    onSubmit={handleSubmit}
                    className="flex min-h-0 flex-1 flex-col"
                    noValidate
                >
                    <div className="min-h-0 flex-1 space-y-4 overflow-y-auto py-4">
                        <div className="space-y-2">
                            <Label htmlFor="create-user-name">Name</Label>
                            <Input
                                id="create-user-name"
                                value={data.name}
                                onChange={(
                                    e: React.ChangeEvent<HTMLInputElement>,
                                ) => setData('name', e.target.value)}
                                onBlur={() => validateField('name')}
                                required
                            />
                            {errors.name && (
                                <p className="text-xs text-destructive">
                                    {errors.name}
                                </p>
                            )}
                        </div>

                        <div className="space-y-2">
                            <Label htmlFor="create-user-nik">NIK</Label>
                            <Input
                                id="create-user-nik"
                                value={data.nik}
                                onChange={(
                                    e: React.ChangeEvent<HTMLInputElement>,
                                ) => setData('nik', e.target.value)}
                                onBlur={() => validateField('nik')}
                                placeholder="e.g. SK-000123"
                                pattern={NIK_PATTERN}
                                title={NIK_TITLE}
                                required
                            />
                            {errors.nik && (
                                <p className="text-xs text-destructive">
                                    {errors.nik}
                                </p>
                            )}
                        </div>

                        <div className="space-y-2">
                            <Label htmlFor="create-user-email">Email</Label>
                            <Input
                                id="create-user-email"
                                type="email"
                                value={data.email}
                                onChange={(
                                    e: React.ChangeEvent<HTMLInputElement>,
                                ) => setData('email', e.target.value)}
                                onBlur={() => validateField('email')}
                                required
                            />
                            {errors.email && (
                                <p className="text-xs text-destructive">
                                    {errors.email}
                                </p>
                            )}
                        </div>

                        <div className="space-y-2">
                            <Label htmlFor="create-user-password">
                                Temporary Password
                            </Label>
                            <PasswordInput
                                id="create-user-password"
                                autoComplete="new-password"
                                value={data.password}
                                onChange={(
                                    e: React.ChangeEvent<HTMLInputElement>,
                                ) => setData('password', e.target.value)}
                                onBlur={() => validateField('password')}
                                required
                            />
                            <p className="text-xs text-muted-foreground">
                                {PASSWORD_HINT}
                            </p>
                            {errors.password && (
                                <p className="text-xs text-destructive">
                                    {errors.password}
                                </p>
                            )}
                        </div>

                        <div className="space-y-2">
                            <Label htmlFor="create-user-password-confirmation">
                                Confirm Password
                            </Label>
                            <PasswordInput
                                id="create-user-password-confirmation"
                                autoComplete="new-password"
                                value={data.password_confirmation}
                                onChange={(
                                    e: React.ChangeEvent<HTMLInputElement>,
                                ) =>
                                    setData(
                                        'password_confirmation',
                                        e.target.value,
                                    )
                                }
                                onBlur={() =>
                                    validateField('password_confirmation')
                                }
                                required
                            />
                            {errors.password_confirmation && (
                                <p className="text-xs text-destructive">
                                    {errors.password_confirmation}
                                </p>
                            )}
                        </div>

                        <div className="grid gap-3 rounded-lg border bg-muted/30 p-3 sm:grid-cols-[minmax(0,1fr)_9rem]">
                            <div className="space-y-1.5">
                                <Label
                                    className="text-xs text-muted-foreground"
                                    htmlFor="create-user-division"
                                >
                                    Division (optional)
                                </Label>
                                <Select
                                    value={
                                        data.division_id === null
                                            ? NO_DIVISION
                                            : String(data.division_id)
                                    }
                                    onValueChange={(value) =>
                                        setData(
                                            'division_id',
                                            value === NO_DIVISION
                                                ? null
                                                : Number(value),
                                        )
                                    }
                                >
                                    <SelectTrigger
                                        id="create-user-division"
                                        className="w-full"
                                    >
                                        <SelectValue />
                                    </SelectTrigger>
                                    <SelectContent>
                                        <SelectItem value={NO_DIVISION}>
                                            No division yet
                                        </SelectItem>
                                        {divisions.map((division) => (
                                            <SelectItem
                                                key={division.id}
                                                value={String(division.id)}
                                            >
                                                {division.name}
                                            </SelectItem>
                                        ))}
                                    </SelectContent>
                                </Select>
                                {errors.division_id && (
                                    <p className="text-xs text-destructive">
                                        {errors.division_id}
                                    </p>
                                )}
                            </div>

                            <div className="space-y-1.5">
                                <Label
                                    className="text-xs text-muted-foreground"
                                    htmlFor="create-user-role"
                                >
                                    Role
                                </Label>
                                <Select
                                    value={data.role_type}
                                    onValueChange={(value) =>
                                        setData('role_type', value)
                                    }
                                    disabled={data.division_id === null}
                                >
                                    <SelectTrigger
                                        id="create-user-role"
                                        className="w-full capitalize"
                                    >
                                        <SelectValue />
                                    </SelectTrigger>
                                    <SelectContent>
                                        {divisionRoleOptions.map((role) => (
                                            <SelectItem
                                                key={role}
                                                value={role}
                                                className="capitalize"
                                            >
                                                {role}
                                            </SelectItem>
                                        ))}
                                    </SelectContent>
                                </Select>
                                {errors.role_type && (
                                    <p className="text-xs text-destructive">
                                        {errors.role_type}
                                    </p>
                                )}
                            </div>

                            <p className="text-xs text-muted-foreground sm:col-span-2">
                                Need more than one division? Create the account
                                first, then use Division Memberships.
                            </p>
                        </div>
                    </div>

                    <DialogFooter className="border-t pt-4">
                        <Button type="button" variant="outline" onClick={close}>
                            Cancel
                        </Button>
                        <Button type="submit" disabled={processing}>
                            {processing ? 'Creating...' : 'Create User'}
                        </Button>
                    </DialogFooter>
                </form>
            </DialogContent>
        </Dialog>
    );
}
