import { Head, router } from '@inertiajs/react';
import { ColumnDef } from '@tanstack/react-table';
import { Check, ChevronsUpDown, Pencil, Star, ToggleLeft, Trash2 } from 'lucide-react';
import { useEffect, useMemo, useRef, useState } from 'react';
import { toast } from 'sonner';

import DashboardLayout from '@/components/dashboard/DashboardLayout';
import { DashboardPageHeader } from '@/components/dashboard/DashboardPageHeader';
import FormDialog from '@/components/dashboard/FormDialog';
import ConfirmDialog from '@/components/dashboard/ConfirmDialog';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { DataTable } from '@/components/ui/data-table';
import { DataTableColumnHeader } from '@/components/ui/data-table-column-header';
import { FlagIcon } from '@/components/ui/flag-icon';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Switch } from '@/components/ui/switch';
import {
    TableActionMenu,
    TableActionMenuContent,
    TableActionMenuItem,
    TableActionMenuLabel,
    TableActionMenuSeparator,
    TableActionMenuTrigger,
} from '@/components/ui/table-action-menu';
import { useTranslation } from '@/contexts/LanguageContext';
import { COUNTRIES } from '@/lib/countries';
import { cn } from '@/lib/utils';

interface Language {
    id: number;
    code: string;
    country_code: string | null;
    name: string;
    native_name: string;
    is_rtl: boolean;
    is_active: boolean;
    is_default: boolean;
    sort_order: number;
}

interface Props {
    languages: Language[];
    availableLocales: string[];
}

type FormState = {
    [key: string]: string | boolean;
    code: string;
    country_code: string;
    name: string;
    native_name: string;
    is_rtl: boolean;
    is_active: boolean;
};

const emptyForm: FormState = {
    code: '',
    country_code: '',
    name: '',
    native_name: '',
    is_rtl: false,
    is_active: true,
};

export default function LanguagesIndex({ languages, availableLocales }: Props) {
    const { t } = useTranslation();
    const [createOpen, setCreateOpen] = useState(false);
    const [editTarget, setEditTarget] = useState<Language | null>(null);
    const [deleteTarget, setDeleteTarget] = useState<Language | null>(null);
    const [form, setForm] = useState<FormState>(emptyForm);
    const [processing, setProcessing] = useState(false);

    const [localeOpen, setLocaleOpen] = useState(false);
    const [localeSearch, setLocaleSearch] = useState('');
    const localeRef = useRef<HTMLDivElement>(null);

    const [countryOpen, setCountryOpen] = useState(false);
    const [countrySearch, setCountrySearch] = useState('');
    const countryRef = useRef<HTMLDivElement>(null);

    useEffect(() => {
        const click = (event: MouseEvent) => {
            if (localeRef.current && !localeRef.current.contains(event.target as Node)) {
                setLocaleOpen(false);
            }
            if (countryRef.current && !countryRef.current.contains(event.target as Node)) {
                setCountryOpen(false);
            }
        };
        const escape = (event: KeyboardEvent) => {
            if (event.key === 'Escape') {
                setLocaleOpen(false);
                setCountryOpen(false);
            }
        };
        document.addEventListener('mousedown', click);
        document.addEventListener('keydown', escape);
        return () => {
            document.removeEventListener('mousedown', click);
            document.removeEventListener('keydown', escape);
        };
    }, []);

    const editing = editTarget !== null;

    const selectableLocales = useMemo(() => {
        const existing = languages.map((l) => l.code);
        const current = editTarget?.code;
        return availableLocales.filter((c) => !existing.includes(c) || c === current);
    }, [availableLocales, languages, editTarget]);

    const filteredLocales = useMemo(() => {
        if (!localeSearch) return selectableLocales;
        const q = localeSearch.toLowerCase();
        return selectableLocales.filter((c) => c.toLowerCase().includes(q));
    }, [localeSearch, selectableLocales]);

    const filteredCountries = useMemo(() => {
        if (!countrySearch) return COUNTRIES;
        const q = countrySearch.toLowerCase();
        return COUNTRIES.filter(
            (c) => c.name.toLowerCase().includes(q) || c.code.toLowerCase().includes(q),
        );
    }, [countrySearch]);

    function openCreate() {
        setForm(emptyForm);
        setLocaleSearch('');
        setCountrySearch('');
        setCreateOpen(true);
    }

    function openEdit(lang: Language) {
        setEditTarget(lang);
        setForm({
            code: lang.code,
            country_code: lang.country_code ?? '',
            name: lang.name,
            native_name: lang.native_name,
            is_rtl: lang.is_rtl,
            is_active: lang.is_active,
        });
        setLocaleSearch('');
        setCountrySearch('');
    }

    function submitCreate() {
        setProcessing(true);
        router.post('/dashboard/languages', form, {
            preserveScroll: true,
            onSuccess: () => {
                toast.success(t('Language created'));
                setCreateOpen(false);
                setForm(emptyForm);
            },
            onError: (errors) => {
                const msg = Object.values(errors)[0] as string;
                toast.error(msg || t('Create failed'));
            },
            onFinish: () => setProcessing(false),
        });
    }

    function submitEdit() {
        if (!editTarget) return;
        setProcessing(true);
        router.patch(`/dashboard/languages/${editTarget.id}`, form, {
            preserveScroll: true,
            onSuccess: () => {
                toast.success(t('Language updated'));
                setEditTarget(null);
            },
            onError: (errors) => {
                const msg = Object.values(errors)[0] as string;
                toast.error(msg || t('Update failed'));
            },
            onFinish: () => setProcessing(false),
        });
    }

    function handleToggle(lang: Language) {
        router.patch(
            `/dashboard/languages/${lang.id}/toggle`,
            {},
            {
                preserveScroll: true,
                onSuccess: () =>
                    toast.success(
                        t(lang.is_active ? ':lang deactivated' : ':lang activated', { lang: lang.name }),
                    ),
                onError: (errors) => toast.error((Object.values(errors)[0] as string) || t('Toggle failed')),
            },
        );
    }

    function handleSetDefault(lang: Language) {
        router.patch(
            `/dashboard/languages/${lang.id}/default`,
            {},
            {
                preserveScroll: true,
                onSuccess: () => toast.success(t('Default language updated.')),
                onError: (errors) => toast.error((Object.values(errors)[0] as string) || t('Failed')),
            },
        );
    }

    function handleDelete() {
        if (!deleteTarget) return;
        router.delete(`/dashboard/languages/${deleteTarget.id}`, {
            preserveScroll: true,
            onSuccess: () => {
                toast.success(t('Language deleted'));
                setDeleteTarget(null);
            },
            onError: (errors) => {
                toast.error((Object.values(errors)[0] as string) || t('Delete failed'));
                setDeleteTarget(null);
            },
        });
    }

    const columns: ColumnDef<Language>[] = [
        {
            accessorKey: 'name',
            header: ({ column }) => <DataTableColumnHeader column={column} title={t('Language')} />,
            cell: ({ row }) => {
                const lang = row.original;
                return (
                    <div className="flex items-center gap-3">
                        <FlagIcon code={lang.country_code} />
                        <div>
                            <div className="flex items-center gap-2">
                                <span className="font-medium">{lang.name}</span>
                                {lang.is_default && (
                                    <Badge variant="secondary" className="text-xs">
                                        <Star className="me-1 h-3 w-3" />
                                        {t('Default')}
                                    </Badge>
                                )}
                            </div>
                            <span className="text-sm text-muted-foreground">{lang.native_name}</span>
                        </div>
                    </div>
                );
            },
        },
        {
            accessorKey: 'code',
            header: ({ column }) => <DataTableColumnHeader column={column} title={t('Code')} />,
            cell: ({ row }) => (
                <code className="rounded bg-muted px-2 py-1 font-mono text-xs">{row.original.code}</code>
            ),
        },
        {
            accessorKey: 'country_code',
            header: ({ column }) => <DataTableColumnHeader column={column} title={t('Country')} />,
            cell: ({ row }) => (
                <span className="font-mono text-sm">{row.original.country_code ?? '—'}</span>
            ),
        },
        {
            accessorKey: 'is_rtl',
            header: ({ column }) => <DataTableColumnHeader column={column} title={t('Direction')} />,
            cell: ({ row }) => (
                <Badge variant={row.original.is_rtl ? 'default' : 'outline'}>
                    {row.original.is_rtl ? t('RTL') : t('LTR')}
                </Badge>
            ),
        },
        {
            accessorKey: 'is_active',
            header: ({ column }) => <DataTableColumnHeader column={column} title={t('Status')} />,
            cell: ({ row }) => {
                const lang = row.original;
                return (
                    <div className="flex items-center gap-2">
                        <Switch
                            checked={lang.is_active}
                            onCheckedChange={() => handleToggle(lang)}
                            disabled={lang.is_default && lang.is_active}
                        />
                        <Badge variant={lang.is_active ? 'default' : 'secondary'}>
                            {lang.is_active ? t('Active') : t('Inactive')}
                        </Badge>
                    </div>
                );
            },
        },
        {
            id: 'actions',
            enableHiding: false,
            cell: ({ row }) => {
                const lang = row.original;
                return (
                    <div className="flex justify-end">
                        <TableActionMenu>
                            <TableActionMenuTrigger />
                            <TableActionMenuContent>
                                <TableActionMenuLabel>{t('Actions')}</TableActionMenuLabel>
                                <TableActionMenuItem onClick={() => openEdit(lang)}>
                                    <Pencil className="h-4 w-4" />
                                    {t('Edit')}
                                </TableActionMenuItem>
                                <TableActionMenuItem onClick={() => handleToggle(lang)}>
                                    <ToggleLeft className="h-4 w-4" />
                                    {lang.is_active ? t('Deactivate') : t('Activate')}
                                </TableActionMenuItem>
                                {!lang.is_default && lang.is_active && (
                                    <TableActionMenuItem onClick={() => handleSetDefault(lang)}>
                                        <Star className="h-4 w-4" />
                                        {t('Set as default')}
                                    </TableActionMenuItem>
                                )}
                                {!lang.is_default && (
                                    <>
                                        <TableActionMenuSeparator />
                                        <TableActionMenuItem
                                            variant="destructive"
                                            onClick={() => setDeleteTarget(lang)}
                                        >
                                            <Trash2 className="h-4 w-4" />
                                            {t('Delete')}
                                        </TableActionMenuItem>
                                    </>
                                )}
                            </TableActionMenuContent>
                        </TableActionMenu>
                    </div>
                );
            },
        },
    ];

    function renderFormFields() {
        return (
            <div className="grid gap-4 py-4">
                <div className="grid grid-cols-2 gap-4">
                    <div className="space-y-2">
                        <Label>{t('Language code')}</Label>
                        <div className="relative" ref={localeRef}>
                            <Button
                                type="button"
                                variant="outline"
                                role="combobox"
                                aria-expanded={localeOpen}
                                className="w-full justify-between"
                                disabled={editing}
                                onClick={() => setLocaleOpen((o) => !o)}
                            >
                                {form.code ? (
                                    <span className="font-mono">{form.code}</span>
                                ) : (
                                    <span className="text-muted-foreground">{t('Select locale…')}</span>
                                )}
                                <ChevronsUpDown className="ms-2 h-4 w-4 shrink-0 opacity-50" />
                            </Button>
                            {localeOpen && (
                                <div className="absolute start-0 top-full z-50 mt-1 w-[220px] rounded-md border bg-popover text-popover-foreground shadow-md">
                                    {selectableLocales.length === 0 ? (
                                        <div className="p-3 text-center text-sm text-muted-foreground">
                                            {t('No locales available')} — drop a{' '}
                                            <code>lang/&#123;code&#125;/</code> dir first.
                                        </div>
                                    ) : (
                                        <>
                                            {selectableLocales.length > 5 && (
                                                <div className="p-2">
                                                    <Input
                                                        placeholder={t('Search locales…')}
                                                        value={localeSearch}
                                                        onChange={(e) => setLocaleSearch(e.target.value)}
                                                        className="h-8"
                                                        autoFocus
                                                    />
                                                </div>
                                            )}
                                            <ScrollArea className="max-h-[200px]">
                                                <div className="p-1">
                                                    {filteredLocales.length === 0 ? (
                                                        <div className="py-3 text-center text-sm text-muted-foreground">
                                                            {t('No matches')}
                                                        </div>
                                                    ) : (
                                                        filteredLocales.map((code) => (
                                                            <button
                                                                key={code}
                                                                type="button"
                                                                onClick={() => {
                                                                    setForm((f) => ({ ...f, code }));
                                                                    setLocaleOpen(false);
                                                                    setLocaleSearch('');
                                                                }}
                                                                className={cn(
                                                                    'flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent hover:text-accent-foreground',
                                                                    form.code === code && 'bg-accent',
                                                                )}
                                                            >
                                                                <span className="flex-1 text-start font-mono">{code}</span>
                                                                {form.code === code && <Check className="h-4 w-4" />}
                                                            </button>
                                                        ))
                                                    )}
                                                </div>
                                            </ScrollArea>
                                        </>
                                    )}
                                </div>
                            )}
                        </div>
                        <p className="text-xs text-muted-foreground">
                            {t('Read from lang/ directory.')}
                        </p>
                    </div>
                    <div className="space-y-2">
                        <Label>{t('Country flag')}</Label>
                        <div className="relative" ref={countryRef}>
                            <Button
                                type="button"
                                variant="outline"
                                role="combobox"
                                aria-expanded={countryOpen}
                                className="w-full justify-between"
                                onClick={() => setCountryOpen((o) => !o)}
                            >
                                {form.country_code ? (
                                    <span className="flex items-center gap-2">
                                        <FlagIcon code={form.country_code} />
                                        {COUNTRIES.find((c) => c.code === form.country_code)?.name ?? form.country_code}
                                    </span>
                                ) : (
                                    <span className="text-muted-foreground">{t('Select country…')}</span>
                                )}
                                <ChevronsUpDown className="ms-2 h-4 w-4 shrink-0 opacity-50" />
                            </Button>
                            {countryOpen && (
                                <div className="absolute start-0 top-full z-50 mt-1 w-[300px] rounded-md border bg-popover text-popover-foreground shadow-md">
                                    <div className="p-2">
                                        <Input
                                            placeholder={t('Search countries…')}
                                            value={countrySearch}
                                            onChange={(e) => setCountrySearch(e.target.value)}
                                            className="h-8"
                                            autoFocus
                                        />
                                    </div>
                                    <ScrollArea className="h-[220px]">
                                        <div className="p-1">
                                            {filteredCountries.length === 0 ? (
                                                <div className="py-6 text-center text-sm text-muted-foreground">
                                                    {t('No country found')}
                                                </div>
                                            ) : (
                                                filteredCountries.map((country) => (
                                                    <button
                                                        key={country.code}
                                                        type="button"
                                                        onClick={() => {
                                                            setForm((f) => ({ ...f, country_code: country.code }));
                                                            setCountryOpen(false);
                                                            setCountrySearch('');
                                                        }}
                                                        className={cn(
                                                            'flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent hover:text-accent-foreground',
                                                            form.country_code === country.code && 'bg-accent',
                                                        )}
                                                    >
                                                        <FlagIcon code={country.code} />
                                                        <span className="flex-1 text-start">{country.name}</span>
                                                        <span className="font-mono text-xs text-muted-foreground">
                                                            {country.code}
                                                        </span>
                                                        {form.country_code === country.code && (
                                                            <Check className="h-4 w-4" />
                                                        )}
                                                    </button>
                                                ))
                                            )}
                                        </div>
                                    </ScrollArea>
                                </div>
                            )}
                        </div>
                    </div>
                </div>

                <div className="grid grid-cols-2 gap-4">
                    <div className="space-y-2">
                        <Label htmlFor="name">{t('Name')} ({t('English')})</Label>
                        <Input
                            id="name"
                            value={form.name}
                            onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))}
                            placeholder={t('e.g. English, Arabic, French')}
                        />
                    </div>
                    <div className="space-y-2">
                        <Label htmlFor="native_name">{t('Native name')}</Label>
                        <Input
                            id="native_name"
                            value={form.native_name}
                            onChange={(e) => setForm((f) => ({ ...f, native_name: e.target.value }))}
                            placeholder={t('e.g. English, العربية, Français')}
                        />
                    </div>
                </div>

                <div className="flex items-center gap-6 pt-2">
                    <div className="flex items-center gap-2">
                        <Switch
                            id="is_rtl"
                            checked={form.is_rtl}
                            onCheckedChange={(c) => setForm((f) => ({ ...f, is_rtl: c }))}
                        />
                        <Label htmlFor="is_rtl">{t('Right-to-left (RTL)')}</Label>
                    </div>
                    <div className="flex items-center gap-2">
                        <Switch
                            id="is_active"
                            checked={form.is_active}
                            onCheckedChange={(c) => setForm((f) => ({ ...f, is_active: c }))}
                        />
                        <Label htmlFor="is_active">{t('Active')}</Label>
                    </div>
                </div>

                <div className="flex justify-end gap-2 pt-2">
                    <Button
                        type="button"
                        variant="outline"
                        onClick={() => (editing ? setEditTarget(null) : setCreateOpen(false))}
                    >
                        {t('Cancel')}
                    </Button>
                    <Button
                        type="button"
                        disabled={processing || !form.code || !form.country_code || !form.name || !form.native_name}
                        onClick={editing ? submitEdit : submitCreate}
                    >
                        {processing
                            ? t('Saving…')
                            : editing
                                ? t('Save changes')
                                : t('Create language')}
                    </Button>
                </div>
            </div>
        );
    }

    return (
        <DashboardLayout>
            <Head title={t('Languages')} />

            <DashboardPageHeader
                title={t('Languages')}
                subtitle={t('Manage site locales. Drop a lang/{code}/ directory of JSON files first, then add the locale here.')}
                action={<Button onClick={openCreate}>{t('New language')}</Button>}
            />

            {availableLocales.length > 0 && (
                <div className="mb-4 rounded-md border border-border bg-muted/30 p-3 text-sm">
                    <strong>{t('Detected locale dirs not yet added:')}</strong>{' '}
                    {availableLocales.join(', ')}
                </div>
            )}

            <DataTable
                columns={columns}
                data={languages}
                searchKey="name"
                searchPlaceholder={t('Search languages…')}
            />

            <FormDialog
                open={createOpen}
                onOpenChange={(open) => {
                    setCreateOpen(open);
                    if (!open) setForm(emptyForm);
                }}
                title={t('Add language')}
                description={t('Add a new locale once its lang/{code}/ JSON files exist on disk.')}
                size="lg"
            >
                {renderFormFields()}
            </FormDialog>

            <FormDialog
                open={editing}
                onOpenChange={(open) => !open && setEditTarget(null)}
                title={t('Edit language')}
                description={t('Update language settings.')}
                size="lg"
            >
                {renderFormFields()}
            </FormDialog>

            <ConfirmDialog
                open={deleteTarget !== null}
                onOpenChange={(open) => !open && setDeleteTarget(null)}
                title={t('Delete :name?', { name: deleteTarget?.name ?? '' })}
                description={t('Users currently on this language will fall back to the default. This cannot be undone.')}
                confirmLabel={t('Delete language')}
                onConfirm={handleDelete}
            />
        </DashboardLayout>
    );
}
