import { FormGroup } from '@admin/components/ui/forms/form-group';
import { PasswordStrengthIndicator } from '@admin/components/ui/forms/password-strength-indicator';
import { FormSelect } from '@admin/components/ui/forms/form-select';
import { FormSwitch } from '@admin/components/ui/forms/form-switch';
import { PermissionMatrix, type PermissionSection } from '@admin/components/ui/forms/permission-matrix';
import { formHelpClassName } from '@admin/components/ui/field-styles';
import { formatRoleName } from '@admin/lib/format-role-name';
import type { SelectOption } from '@admin/lib/sort-select-options';
import { cn } from '@admin/lib/utils';

export type RoleOption = {
    id: number;
    name: string;
};

type UserFormFieldsProps = {
    data: {
        name: string;
        email: string;
        password: string;
        password_confirmation: string;
        role: string;
        permissions: string[];
        status: boolean;
        send_password_to_user?: boolean;
    };
    errors: Partial<
        Record<
            | 'name'
            | 'email'
            | 'password'
            | 'password_confirmation'
            | 'role'
            | 'permissions'
            | 'status'
            | 'send_password_to_user',
            string
        >
    >;
    setData: (key: string, value: unknown) => void;
    roles: RoleOption[];
    permissionSections: PermissionSection[];
    passwordRequired?: boolean;
    showSendPasswordOption?: boolean;
};

function roleSelectOptions(roles: RoleOption[]): SelectOption[] {
    return roles.map((role) => ({
        value: String(role.id),
        label: formatRoleName(role.name),
    }));
}

export function UserFormFields({
    data,
    errors,
    setData,
    roles,
    permissionSections,
    passwordRequired = true,
    showSendPasswordOption = false,
}: UserFormFieldsProps) {
    const sendPasswordToUser = Boolean(data.send_password_to_user);
    const showPasswordFields = passwordRequired && !sendPasswordToUser;

    return (
        <>
            <FormGroup
                label="Name"
                error={errors.name}
                inputProps={{
                    value: data.name,
                    onChange: (event) => setData('name', event.target.value),
                    required: true,
                }}
            />

            <FormGroup
                label="Email"
                error={errors.email}
                inputProps={{
                    type: 'email',
                    value: data.email,
                    onChange: (event) => setData('email', event.target.value),
                    required: true,
                    autoComplete: 'email',
                }}
            />

            <FormSelect
                label="Role (optional)"
                value={data.role}
                options={roleSelectOptions(roles)}
                placeholder="No role — assign permissions only"
                error={errors.role}
                onChange={(value) => setData('role', value)}
            />

            <p className={cn('-mt-2 mb-4', formHelpClassName)}>
                Choose a role for a predefined permission set, or leave empty and assign granular permissions below.
            </p>

            <div className="mb-2">
                <p className={cn('mb-0', formHelpClassName)}>
                    Grant individual module permissions. General access shortcuts (manage content, manage posts, etc.) are
                    not shown here — use a role if you need those.
                </p>
                {errors.permissions && <p className="text-danger text-sm mt-2">{errors.permissions}</p>}
            </div>

            <PermissionMatrix
                sections={permissionSections}
                selected={data.permissions}
                onChange={(permissions) => setData('permissions', permissions)}
            />

            {showSendPasswordOption && (
                <FormSwitch
                    id="send-password-to-user"
                    label="Email password to user"
                    checked={sendPasswordToUser}
                    onChange={(event) => {
                        const checked = event.target.checked;
                        setData('send_password_to_user', checked);
                        if (checked) {
                            setData('password', '');
                            setData('password_confirmation', '');
                        }
                    }}
                />
            )}

            {showSendPasswordOption && sendPasswordToUser && (
                <p className="text-xs text-gray-500 -mt-2 mb-4 dark:text-white/70">
                    A secure password will be generated and emailed to the user. You do not need to enter one here.
                </p>
            )}

            {showPasswordFields && (
                <div className="mb-4">
                    <FormGroup
                        label={passwordRequired ? 'Password' : 'Password (optional)'}
                        helpText={passwordRequired ? undefined : 'Leave blank to keep the current password.'}
                        error={errors.password}
                        inputProps={{
                            type: 'password',
                            value: data.password,
                            onChange: (event) => setData('password', event.target.value),
                            required: passwordRequired,
                            autoComplete: passwordRequired ? 'new-password' : 'off',
                        }}
                    />
                    {(passwordRequired || data.password.length > 0) && (
                        <PasswordStrengthIndicator password={data.password} />
                    )}
                </div>
            )}

            {showPasswordFields && (
                <FormGroup
                    label="Confirm password"
                    error={errors.password_confirmation}
                    inputProps={{
                        type: 'password',
                        value: data.password_confirmation,
                        onChange: (event) => setData('password_confirmation', event.target.value),
                        required: passwordRequired,
                        autoComplete: passwordRequired ? 'new-password' : 'off',
                    }}
                />
            )}

            <FormSwitch
                id="user-status"
                label="Active"
                checked={data.status}
                onChange={(event) => setData('status', event.target.checked)}
            />
        </>
    );
}
