import { Head, usePage } from '@inertiajs/react';
import type { FormEvent } from 'react';
import ProfileController from '@/actions/App/Domains/Shared/Http/Controllers/Settings/ProfileController';
import DeleteUser from '@/components/DeleteUser';
import Heading from '@/components/Heading';
import InputError from '@/components/InputError';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { useYupForm } from '@/hooks/use-yup-form';
import { avatarUrl, cn, getInitials } from '@/lib/utils';
import { profileSettingsSchema } from '@/lib/validation/auth';
import { edit } from '@/routes/profile';

interface ProfileProps {
    /** Kunci avatar yang boleh dipilih, dikirim dari User::AVATAR_PRESETS. */
    avatarPresets: string[];
}

export default function Profile({ avatarPresets }: ProfileProps) {
    const { auth } = usePage().props;

    const { data, setData, processing, errors, validateField, submit } =
        useYupForm(profileSettingsSchema, {
            name: auth.user.name,
            email: auth.user.email,
            avatar: auth.user.avatar ?? null,
        });

    /** Cincin penanda pilihan; dipakai tombol inisial maupun tombol preset. */
    const ringClass = (isSelected: boolean) =>
        cn(
            'rounded-full ring-2 ring-offset-2 ring-offset-background transition',
            isSelected
                ? 'ring-primary'
                : 'ring-transparent hover:ring-border focus-visible:ring-border',
        );

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

        submit((form) =>
            form.patch(ProfileController.update.url(), {
                preserveScroll: true,
            }),
        );
    };

    return (
        <>
            <Head title="Profile settings" />

            <h1 className="sr-only">Profile settings</h1>

            <div className="space-y-6">
                <Heading
                    variant="small"
                    title="Profile information"
                    description="Update your name and email address"
                />

                <form onSubmit={handleSubmit} className="space-y-6" noValidate>
                    <div className="grid gap-2">
                        <Label id="avatar-label">Avatar</Label>

                        {/* Pratinjau besar dari pilihan yang sedang aktif.
                            Petak pilihan di bawah terlalu kecil untuk menilai
                            detail wajahnya, jadi yang terpilih ditampilkan
                            sekali lagi dalam ukuran penuh. */}
                        <div className="mb-2 flex items-center gap-4">
                            {data.avatar ? (
                                <img
                                    src={avatarUrl(data.avatar)}
                                    alt=""
                                    className="size-20 shrink-0 rounded-full border bg-muted"
                                />
                            ) : (
                                <div className="flex size-20 shrink-0 items-center justify-center rounded-full border bg-primary/10 text-xl font-medium text-primary">
                                    {getInitials(auth.user.name)}
                                </div>
                            )}

                            <div className="min-w-0">
                                <p className="text-sm font-medium capitalize">
                                    {data.avatar ?? 'Initials'}
                                </p>
                                <p className="text-xs text-muted-foreground">
                                    Currently selected
                                </p>
                            </div>
                        </div>

                        <div
                            role="group"
                            aria-labelledby="avatar-label"
                            className="flex flex-wrap gap-3"
                        >
                            {/* Pilihan pertama mengosongkan avatar, yaitu
                                kembali ke inisial seperti sebelum ada preset. */}
                            <button
                                type="button"
                                onClick={() => setData('avatar', null)}
                                aria-pressed={data.avatar === null}
                                aria-label="Use initials"
                                className={cn(
                                    'flex size-12 items-center justify-center bg-primary/10 text-sm font-medium text-primary',
                                    ringClass(data.avatar === null),
                                )}
                            >
                                {getInitials(auth.user.name)}
                            </button>

                            {avatarPresets.map((preset) => (
                                <button
                                    key={preset}
                                    type="button"
                                    onClick={() => setData('avatar', preset)}
                                    aria-pressed={data.avatar === preset}
                                    aria-label={`Avatar ${preset}`}
                                    className={ringClass(
                                        data.avatar === preset,
                                    )}
                                >
                                    <img
                                        src={avatarUrl(preset)}
                                        alt=""
                                        className="size-12 rounded-full bg-muted"
                                    />
                                </button>
                            ))}
                        </div>
                    </div>

                    <div className="grid gap-2">
                        <Label htmlFor="name">Name</Label>

                        <Input
                            id="name"
                            className="mt-1 block w-full"
                            name="name"
                            value={data.name}
                            onChange={(e) => setData('name', e.target.value)}
                            onBlur={() => validateField('name')}
                            required
                            autoComplete="name"
                            placeholder="Full name"
                        />

                        <InputError className="mt-2" message={errors.name} />
                    </div>

                    <div className="grid gap-2">
                        <Label htmlFor="email">Email address</Label>

                        <Input
                            id="email"
                            type="email"
                            className="mt-1 block w-full"
                            name="email"
                            value={data.email}
                            onChange={(e) => setData('email', e.target.value)}
                            onBlur={() => validateField('email')}
                            required
                            autoComplete="username"
                            placeholder="Email address"
                        />

                        <InputError className="mt-2" message={errors.email} />
                    </div>

                    <div className="flex items-center gap-4">
                        <Button
                            disabled={processing}
                            data-test="update-profile-button"
                        >
                            Save
                        </Button>
                    </div>
                </form>
            </div>

            <DeleteUser />
        </>
    );
}

Profile.layout = {
    breadcrumbs: [
        {
            title: 'Profile settings',
            href: edit(),
        },
    ],
};
