import Form from '@/components/form/Form';
import FormField from '@/components/form/FormField';
import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import TextEditor from '@admin/components/rich-text-editor';
import { yupResolver } from '@hookform/resolvers/yup';
import { router, usePage } from '@inertiajs/react';
import { ClipboardList, Loader2 } from 'lucide-react';
import { useEffect, useRef, useState } from 'react';
import { SubmitHandler, useFormContext } from 'react-hook-form';
import { toast } from 'sonner';
import * as yup from 'yup';

declare const route: (...args: any[]) => string;

interface Language {
    id?: number;
    name: string;
    value: number;
    code: string;
    is_default: number;
}

interface ItemModalProps {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    onSuccess?: () => void;
    languages?: Language[];
    defaultValues?: {
        id: number;
        uid: string;
        title: Record<string, string>;
        slug: Record<string, string>;
        version: string | null;
        group: string | null;
        overall_completion_percent: string | null;
        media_id: number | null;
        description: Record<string, string>;
        shared_with_students: number;
        shared_with_parents: number;
        status: number;
        created_at: string;
        updated_at: string;
    };
}

const generateSlug = (text: string) =>
    text
        .toLowerCase()
        .trim()
        .replace(/[^\w\s-]/g, '')
        .replace(/[\s_-]+/g, '-')
        .replace(/^-+|-+$/g, '');

function SlugSync({ locale, slugEditedRef }: { locale: string; slugEditedRef: { current: boolean } }) {
    const { watch, setValue } = useFormContext();
    const title = watch(`title.${locale}`);
    const slug = watch(`slug.${locale}`);

    useEffect(() => {
        if (!slugEditedRef.current && title) {
            setValue(`slug.${locale}`, generateSlug(title), { shouldValidate: true });
        }
    }, [title]);

    useEffect(() => {
        if (slug && slug !== generateSlug(title || '')) {
            slugEditedRef.current = true;
        }
    }, [slug]);

    return null;
}

function TranslatableFields({
    languages,
    defaultLocale,
    slugEditedRefs,
}: {
    languages: Language[];
    defaultLocale: string;
    slugEditedRefs: React.RefObject<Record<string, { current: boolean }>>;
}) {
    const { watch } = useFormContext();
    const selectedLocale = watch('locale');

    return (
        <div className="space-y-4">
            {languages.map((lang) => (
                <div
                    key={lang.code}
                    className={selectedLocale === lang.code ? 'block' : 'hidden'}
                >
                    <SlugSync locale={lang.code} slugEditedRef={slugEditedRefs.current![lang.code]} />
                    <div className="grid gap-4 sm:grid-cols-2">
                        <FormField
                            type="text"
                            name={`title.${lang.code}`}
                            label={`Title (${lang.name})`}
                            placeholder="Enter result title"
                            required={lang.code === defaultLocale}
                        />

                        <FormField
                            type="text"
                            name={`slug.${lang.code}`}
                            label={`Slug (${lang.name})`}
                            placeholder="Enter result slug"
                        />

                        <div className="sm:col-span-2">
                            <TextEditor
                                name={`description.${lang.code}`}
                                label={`Description (${lang.name})`}
                                type="textarea"
                                placeholder="Enter result description..."
                            />
                        </div>
                    </div>
                </div>
            ))}
        </div>
    );
}

export function EditModal({ open, onOpenChange, onSuccess, defaultValues, languages: langsProp }: ItemModalProps) {
    const [isSubmitting, setIsSubmitting] = useState(false);

    const slugEditedRefs = useRef<Record<string, { current: boolean }>>(
        Object.fromEntries((langsProp ?? []).map((l) => [l.code, { current: !!(defaultValues?.slug?.[l.code]) }])),
    );

    const { data } = usePage<any>().props;
    const academicVersions = data?.academicVersions ?? [];
    const academicGroups = data?.academicGroups ?? [];
    const languages: Language[] = langsProp ?? data?.languages ?? [];

    const { current_locale } = usePage().props as any;
    const defaultLocale =
        languages.find((l) => l.is_default === 1)?.code ??
        languages.find((l) => l.code === current_locale)?.code ??
        languages[0]?.code ?? 'us';

    const buildSchema = (langs: Language[]) => {
        const localeStringShape = Object.fromEntries(langs.map((l) => [l.code, yup.string().nullable()]));
        localeStringShape[defaultLocale] = yup
            .string()
            .required(`Title (${langs.find((l) => l.code === defaultLocale)?.name ?? defaultLocale}) is required`);

        return yup.object({
            locale:                    yup.string().required('Language is required'),
            title:                     yup.object(localeStringShape).required(),
            slug:                      yup.object(Object.fromEntries(langs.map((l) => [l.code, yup.string().nullable()]))).nullable(),
            description:               yup.object(Object.fromEntries(langs.map((l) => [l.code, yup.string().nullable()]))).nullable(),
            version:                   yup.string().nullable(),
            group:                     yup.string().nullable(),
            overall_completion_percent: yup.string().nullable(),
            media_id:                  yup.number().nullable(),
            shared_with_students:      yup.number().oneOf([1, 0], 'Invalid value').required(),
            shared_with_parents:       yup.number().oneOf([1, 0], 'Invalid value').required(),
            status:                    yup.number().oneOf([1, 0], 'Invalid status').required('Status is required'),
        });
    };

    const buildDefaultValues = () => {
        if (!defaultValues) return undefined;

        return {
            locale:                    defaultLocale,
            title:                     Object.fromEntries(languages.map((l) => [l.code, defaultValues.title?.[l.code] ?? ''])),
            slug:                      Object.fromEntries(languages.map((l) => [l.code, defaultValues.slug?.[l.code] ?? ''])),
            description:               Object.fromEntries(languages.map((l) => [l.code, defaultValues.description?.[l.code] ?? ''])),
            version:                   defaultValues.version ?? '',
            group:                     defaultValues.group ?? '',
            overall_completion_percent: defaultValues.overall_completion_percent ?? '',
            media_id:                  defaultValues.media_id ?? null,
            shared_with_students:      defaultValues.shared_with_students ?? 1,
            shared_with_parents:       defaultValues.shared_with_parents ?? 1,
            status:                    defaultValues.status ?? 1,
        };
    };

    const handleSubmit: SubmitHandler<any> = async (formData) => {
        setIsSubmitting(true);

        try {
            router.put(route('result.update', defaultValues?.id), formData, {
                onSuccess: () => {
                    onOpenChange(false);
                    onSuccess?.();
                },
                onError: (errors) => {
                    const firstError = Object.values(errors)[0];
                    toast.error(typeof firstError === 'string' ? firstError : 'Something went wrong. Please try again.');
                },
                onFinish: () => {
                    setIsSubmitting(false);
                },
            });
        } catch (error) {
            console.error('Submission error:', error);
            toast.error('Something went wrong. Please try again.');
            setIsSubmitting(false);
        }
    };

    useEffect(() => {
        if (!open) {
            setIsSubmitting(false);
        }
    }, [open]);

    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent className="max-h-[95vh] w-[95vw] max-w-4xl overflow-y-auto sm:w-[90vw] md:max-w-3xl">
                <DialogHeader className="gap-0 pb-4">
                    <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between">
                        <div className="flex items-center gap-3">
                            <ClipboardList className="h-6 w-6" />
                            <div>
                                <DialogTitle className="text-lg sm:text-xl">Edit Result</DialogTitle>
                            </div>
                        </div>
                    </div>
                    <DialogDescription className="text-sm text-text-gray sm:text-base">
                        Update result here. Click save when you're done.
                    </DialogDescription>
                </DialogHeader>

                <div className="space-y-6 rounded-lg border px-2 py-4 sm:px-4 md:px-6">
                    <Form
                        submitHandler={handleSubmit}
                        resolver={yupResolver(buildSchema(languages))}
                        defaultValues={buildDefaultValues()}
                        key={defaultValues?.id ?? 'edit'}
                    >
                        <FormField
                            type="select"
                            name="locale"
                            label="Language"
                            defaultValue={defaultLocale}
                            options={languages.map((l) => ({
                                value: l.code,
                                label: `${l.name}${l.is_default ? ' (Default)' : ''}`,
                            }))}
                        />

                        <TranslatableFields languages={languages} defaultLocale={defaultLocale} slugEditedRefs={slugEditedRefs} />

                        {/* ── Non-translatable fields ── */}
                        <div className="mb-5 grid gap-4 sm:grid-cols-2">
                            <FormField type="select" name="version" label="Version" placeholder="Select version" options={academicVersions} />
                            <FormField type="select" name="group" label="Group" placeholder="Select group" options={academicGroups} />
                            <FormField type="text" name="overall_completion_percent" label="Completion %" placeholder="e.g. 85" />
                            <FormField
                                type="media-picker"
                                name="media_id"
                                label="Media"
                                placeholder="Select media"
                                app_name="website"
                                app_module="results"
                            />
                            <FormField
                                type="select"
                                name="shared_with_students"
                                label="Shared with Students"
                                required
                                options={[
                                    { label: 'Yes', value: 1 },
                                    { label: 'No', value: 0 },
                                ]}
                            />
                            <FormField
                                type="select"
                                name="shared_with_parents"
                                label="Shared with Parents"
                                required
                                options={[
                                    { label: 'Yes', value: 1 },
                                    { label: 'No', value: 0 },
                                ]}
                            />
                            <FormField
                                type="select"
                                name="status"
                                label="Status"
                                required
                                options={[
                                    { label: 'Active', value: 1 },
                                    { label: 'Inactive', value: 0 },
                                ]}
                            />
                        </div>

                        <div className="flex flex-col-reverse gap-3 sm:flex-row sm:justify-end">
                            <Button type="submit" disabled={isSubmitting} className="w-full bg-success hover:bg-brand-800 sm:w-auto">
                                {isSubmitting ? (
                                    <>
                                        <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                                        Updating...
                                    </>
                                ) : (
                                    <p>Update Changes</p>
                                )}
                            </Button>
                        </div>
                    </Form>
                </div>
            </DialogContent>
        </Dialog>
    );
}

export default EditModal;
