import { zodResolver } from '@hookform/resolvers/zod';
import { router } from '@inertiajs/react';
import { useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
import { toast } from 'sonner';
import {
    FormLanguageTabs,
    TranslatableField,
} from '@/components/admin/form-language';
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 { blogCategorySchema } from '@/lib/validators/blog-category';
import type { BlogCategoryFormValues } from '@/lib/validators/blog-category';
import { store, update } from '@/routes/admin/blog-categories';
import type { BlogCategory } from '@/types/models';

type Props = {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    category: BlogCategory | null; // null = tambah baru
    nextOrder?: number;
};

/**
 * Slug otomatis dari nama (Str::slug setara).
 */
const toSlug = (value: string) =>
    value
        .toLowerCase()
        .normalize('NFD')
        .replace(/[\u0300-\u036f]/g, '')
        .replace(/[^a-z0-9\s-]/g, '')
        .trim()
        .replace(/[\s_]+/g, '-')
        .replace(/-+/g, '-');

/**
 * Dialog tambah/edit kategori. Komponen di-remount oleh parent (via key) setiap
 * kali dibuka, sehingga defaultValues selalu fresh — tanpa useEffect reset.
 */
export default function BlogCategoryDialog({ open, onOpenChange, category, nextOrder }: Props) {
    const isEdit = !!category;
    const [slugEdited, setSlugEdited] = useState<{ id: boolean; en: boolean }>({
        id: false,
        en: false,
    });

    const translations = {
        name: {
            id: category?.translations.id.name ?? '',
            en: category?.translations.en.name ?? '',
        },
        slug: {
            id: category?.translations.id.slug ?? '',
            en: category?.translations.en.slug ?? '',
        },
    };

    const {
        register,
        control,
        setValue,
        getValues,
        handleSubmit,
        formState: { isSubmitting },
    } = useForm<BlogCategoryFormValues>({
        resolver: zodResolver(blogCategorySchema),
        defaultValues: {
            ...translations,
            sort_order: category?.sort_order ?? nextOrder ?? 0,
        },
    });

    // Set objek lengkap + getValues agar Controller slug re-render real-time
    // (setValue nested path tidak memicu re-render di react-hook-form 7.84).
    const syncSlug = (locale: 'id' | 'en', nameValue: string) => {
        if (slugEdited[locale]) {
            return;
        }

        const current = getValues('slug');

        setValue('slug', { ...current, [locale]: toSlug(nameValue) }, { shouldValidate: false });
    };

    const onSubmit = (values: BlogCategoryFormValues) => {
        // Client-side: pastikan kedua locale nama diisi.
        if (!values.name.id.trim()) {
            toast.error('Nama kategori (Indonesia) wajib diisi.');

            return;
        }

        if (!values.name.en.trim()) {
            toast.error('Nama kategori (English) wajib diisi. Silakan pindah ke tab English.');
            // Switch to EN tab via its trigger button.
            const tabList = document.querySelector('[aria-label="Bahasa konten"]');
            const triggers = tabList?.querySelectorAll<HTMLElement>('[role="tab"]');
            triggers?.[1]?.click();

            return;
        }

        const payload = {
            name: values.name,
            slug: values.slug,
            sort_order: values.sort_order ?? 0,
        };

        const opts = {
            preserveScroll: true,
            onSuccess: () => {
                onOpenChange(false);
            },
        };

        if (isEdit && category) {
            router.put(update(category.id), payload, opts);
        } else {
            router.post(store(), payload, opts);
        }
    };

    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent>
                <DialogHeader>
                    <DialogTitle>{isEdit ? 'Ubah Kategori' : 'Tambah Kategori'}</DialogTitle>
                    <DialogDescription>
                        Kategori dipakai untuk mengelompokkan postingan blog.
                    </DialogDescription>
                </DialogHeader>

                <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
                    <FormLanguageTabs>
                        <Controller
                            control={control}
                            name="name"
                            render={({ field }) => (
                                <TranslatableField
                                    label="Nama Kategori"
                                    required
                                    value={field.value}
                                    onChange={(next) => {
                                        const prev = field.value;

                                        if (prev.id !== next.id) {
                                            syncSlug('id', next.id);
                                        }

                                        if (prev.en !== next.en) {
                                            syncSlug('en', next.en);
                                        }

                                        field.onChange(next);
                                    }}
                                    placeholder="mis. Teknologi"
                                />
                            )}
                        />

                        <Controller
                            control={control}
                            name="slug"
                            render={({ field }) => (
                                <TranslatableField
                                    label="Slug (otomatis dari nama, bisa diedit)"
                                    value={field.value}
                                    onChange={(next) => {
                                        const prev = field.value;

                                        for (const locale of ['id', 'en'] as const) {
                                            if (next[locale] !== prev[locale]) {
                                                setSlugEdited((current) => ({ ...current, [locale]: true }));
                                            }
                                        }

                                        field.onChange(next);
                                    }}
                                    placeholder="mis. teknologi"
                                />
                            )}
                        />
                    </FormLanguageTabs>

                    <div className="space-y-2">
                        <Label htmlFor="sort_order">Urutan</Label>
                        <Input
                            id="sort_order"
                            type="number"
                            min={0}
                            placeholder="0"
                            {...register('sort_order')}
                        />
                    </div>

                    <DialogFooter>
                        <Button
                            type="button"
                            variant="outline"
                            onClick={() => onOpenChange(false)}
                        >
                            Batal
                        </Button>
                        <Button type="submit" disabled={isSubmitting}>
                            {isEdit ? 'Simpan Perubahan' : 'Tambah Kategori'}
                        </Button>
                    </DialogFooter>
                </form>
            </DialogContent>
        </Dialog>
    );
}
