import { zodResolver } from '@hookform/resolvers/zod';
import { Link, router } from '@inertiajs/react';
import { Timer } from 'lucide-react';
import { useEffect, useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
import {
    FormSection,
    TranslatableField,
    TranslationCard,
} from '@/components/admin/form-language';
import FormImageUpload from '@/components/admin/FormImageUpload';
import type { SelectedMedia } from '@/components/admin/FormImageUpload';
import { Button } from '@/components/ui/button';
import { Combobox } from '@/components/ui/combobox';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { postSchema } from '@/lib/validators/post';
import type { PostFormValues } from '@/lib/validators/post';
import { index, store, update } from '@/routes/admin/blog';
import type { PostAdmin } from '@/types/models';

type CategoryOption = {
    id: number;
    name: string;
};

type Props = {
    mode: 'create' | 'edit';
    post?: PostAdmin;
    categories: CategoryOption[];
};

const translatableFields = ['title', 'slug', 'excerpt', 'body'] as const;

type TranslatableFieldKey = (typeof translatableFields)[number];

const emptyTranslations = (): Record<
    TranslatableFieldKey,
    { id: string; en: string }
> => ({
    title: { id: '', en: '' },
    slug: { id: '', en: '' },
    excerpt: { id: '', en: '' },
    body: { id: '', en: '' },
});

/** Hitung perkiraan waktu baca (200 kata/menit). */
const calculateReadingTime = (body: { id: string; en: string }): number => {
    const text = `${body.id ?? ''} ${body.en ?? ''}`
        .replace(/<[^>]*>/g, ' ')
        .trim();
    const words = text.split(/\s+/).filter(Boolean).length;

    return Math.max(1, Math.ceil(words / 200));
};

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

/**
 * published_at dari server ('Y-m-d H:i') → nilai input datetime-local ('Y-m-dTH:i').
 */
const toDatetimeLocal = (value: string | null | undefined) => {
    if (!value) {
        return '';
    }

    return value.replace(' ', 'T');
};

const currentDatetimeLocal = () => {
    const now = new Date();
    const local = new Date(now.getTime() - now.getTimezoneOffset() * 60000);

    return local.toISOString().slice(0, 16);
};

export default function PostForm({ mode, post, categories }: Props) {
    const isCreate = mode === 'create';
    const [coverFile, setCoverFile] = useState<File | null>(null);
    const [coverMedia, setCoverMedia] = useState<SelectedMedia | null>(null);
    const [removeCover, setRemoveCover] = useState(false);
    const [slugEdited, setSlugEdited] = useState<{ id: boolean; en: boolean }>({
        id: false,
        en: false,
    });

    const {
        register,
        control,
        setValue,
        getValues,
        watch,
        handleSubmit,
        formState: { isSubmitting },
    } = useForm<PostFormValues>({
        resolver: zodResolver(postSchema),
        defaultValues: (() => {
            const translations = emptyTranslations();

            if (post) {
                for (const field of translatableFields) {
                    translations[field] = {
                        id: post.translations.id[field] ?? '',
                        en: post.translations.en[field] ?? '',
                    };
                }
            }

            return {
                ...translations,
                blog_category_ids: (post?.category_ids ?? []).map(String),
                status: post?.status ?? 'draft',
                published_at: toDatetimeLocal(post?.published_at),
                reading_time:
                    post?.reading_time ??
                    calculateReadingTime(translations.body),
            };
        })(),
    });

    const status = watch('status');
    const scheduledMin = currentDatetimeLocal();

    useEffect(() => {
        if (status === 'draft') {
            setValue('published_at', '');
        }
    }, [setValue, status]);

    // Auto-fill slug dari title per locale (hanya bila slug belum diedit manual).
    // 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', titleValue: string) => {
        if (slugEdited[locale]) {
            return;
        }

        const current = getValues('slug');

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

    const onSubmit = (values: PostFormValues) => {
        const formData = new FormData();

        translatableFields.forEach((field) => {
            const value = values[field];

            formData.append(`${field}[id]`, value.id ?? '');
            formData.append(`${field}[en]`, value.en ?? '');
        });

        values.blog_category_ids.forEach((id) => {
            formData.append('blog_category_ids[]', id);
        });

        formData.append('status', values.status);
        formData.append('reading_time', String(values.reading_time));

        if (values.status !== 'draft' && values.published_at) {
            formData.append(
                'published_at',
                values.published_at.replace('T', ' '),
            );
        }

        if (coverFile) {
            formData.append('cover_image', coverFile);
        } else if (coverMedia) {
            formData.append('cover_media_id', String(coverMedia.id));
        } else if (removeCover) {
            formData.append('remove_cover', '1');
        }

        if (isCreate) {
            router.post(store(), formData, { preserveScroll: true });
        } else if (post) {
            router.put(update(post.id), formData, { preserveScroll: true });
        }
    };

    return (
        <form onSubmit={handleSubmit(onSubmit)} className="flex flex-col gap-6">
            <TranslationCard
                title="Konten"
                description="Isi artikel per bahasa — pilih tab bahasa di atas, lalu lengkapi field di bawahnya."
            >
                <div className="grid gap-6 lg:grid-cols-2">
                    <Controller
                        control={control}
                        name="title"
                        render={({ field }) => (
                            <TranslatableField
                                label="Judul"
                                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. Transformasi Digital untuk UMKM"
                            />
                        )}
                    />
                    <Controller
                        control={control}
                        name="slug"
                        render={({ field }) => (
                            <TranslatableField
                                label="Slug (otomatis dari judul, bisa diedit)"
                                required
                                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. transformasi-digital-umkm"
                            />
                        )}
                    />
                </div>

                <Controller
                    control={control}
                    name="excerpt"
                    render={({ field }) => (
                        <TranslatableField
                            label="Ringkasan (excerpt)"
                            value={field.value}
                            onChange={field.onChange}
                            type="textarea"
                            placeholder="Ringkasan singkat artikel (tampil di kartu)"
                        />
                    )}
                />

                <Controller
                    control={control}
                    name="body"
                    render={({ field }) => (
                        <TranslatableField
                            label="Konten"
                            required
                            value={field.value}
                            onChange={field.onChange}
                            type="richtext"
                            placeholder="Tulis isi artikel di sini..."
                        />
                    )}
                />
            </TranslationCard>

            <FormSection
                title="Publikasi"
                description="Kategori, status, dan jadwal tayang artikel."
            >
                <div className="max-w-xs space-y-2">
                    <Label htmlFor="reading_time">Lama baca (menit)</Label>
                    <div className="relative">
                        <Timer className="pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground" />
                        <Input
                            id="reading_time"
                            type="number"
                            min={1}
                            max={120}
                            className="w-28 pl-9"
                            {...register('reading_time', {
                                valueAsNumber: true,
                            })}
                        />
                    </div>
                    <p className="text-xs text-muted-foreground">
                        Estimasi otomatis dari konten, dapat disesuaikan.
                    </p>
                </div>

                <div className="grid gap-6 lg:grid-cols-2">
                    <div className="space-y-2">
                        <Label>Kategori</Label>
                        <Controller
                            control={control}
                            name="blog_category_ids"
                            render={({ field }) => (
                                <Combobox
                                    multiple
                                    options={categories.map((category) => ({
                                        value: String(category.id),
                                        label: category.name,
                                    }))}
                                    value={field.value ?? []}
                                    onValueChange={field.onChange}
                                    clearOptionLabel="Tanpa kategori"
                                    placeholder="Tanpa kategori"
                                    searchPlaceholder="Cari kategori..."
                                    emptyText="Kategori tidak ditemukan"
                                />
                            )}
                        />
                        <p className="text-xs text-muted-foreground">
                            Bisa memilih lebih dari satu kategori.
                        </p>
                    </div>
                    <div className="space-y-2">
                        <Label>Status</Label>
                        <Controller
                            control={control}
                            name="status"
                            render={({ field }) => (
                                <Select
                                    value={field.value ?? 'draft'}
                                    onValueChange={field.onChange}
                                >
                                    <SelectTrigger className="w-full">
                                        <SelectValue placeholder="Pilih status" />
                                    </SelectTrigger>
                                    <SelectContent>
                                        <SelectItem value="draft">
                                            Draf
                                        </SelectItem>
                                        <SelectItem value="scheduled">
                                            Terjadwal
                                        </SelectItem>
                                        <SelectItem value="published">
                                            Terbit
                                        </SelectItem>
                                    </SelectContent>
                                </Select>
                            )}
                        />
                    </div>
                </div>

                {status !== 'draft' && (
                    <div className="max-w-sm space-y-2">
                        <Label htmlFor="published_at">Tanggal Tayang</Label>
                        <Input
                            id="published_at"
                            type="datetime-local"
                            min={
                                status === 'scheduled'
                                    ? scheduledMin
                                    : undefined
                            }
                            {...register('published_at')}
                        />
                        <p className="text-xs text-muted-foreground">
                            {status === 'scheduled'
                                ? 'Pilih tanggal dan waktu di masa depan.'
                                : 'Kosongkan untuk menerbitkan sekarang. Tanggal terbit dapat menggunakan tanggal lampau.'}
                        </p>
                    </div>
                )}
            </FormSection>

            <FormSection
                title="Thumbnail"
                description="Gambar thumbnail artikel."
            >
                <div className="max-w-md">
                    <FormImageUpload
                        label="Thumbnail"
                        existingUrl={post?.cover_url}
                        selectedMedia={coverMedia}
                        onChange={setCoverFile}
                        onSelectMedia={setCoverMedia}
                        onClear={() => setRemoveCover(true)}
                        showLibraryButton={false}
                        showClearButton={false}
                        aspectRatio="video"
                        hint="PNG, JPG, atau WEBP — maks. 4 MB"
                    />
                </div>
            </FormSection>

            <div className="flex gap-3">
                <Button type="submit" disabled={isSubmitting}>
                    {isCreate ? 'Simpan Postingan' : 'Simpan Perubahan'}
                </Button>
                <Button type="button" variant="outline" asChild>
                    <Link href={index()}>Batal</Link>
                </Button>
            </div>
        </form>
    );
}
