import { router, usePage } from '@inertiajs/react';
import { ChevronDown, Plus, RefreshCcw, Search, Trash2, X } from 'lucide-react';
import { useEffect, useRef, useState } from 'react';
import { BrandTags } from '@/components/shared/brand-tags';
import { ChromeTabs } from '@/components/shared/chrome-tabs';
import { EmptyState } from '@/components/shared/empty-state';
import { LocaleFallbackChip } from '@/components/shared/locale-chips';
import { PageHeader } from '@/components/shared/page-header';
import { Pagination } from '@/components/shared/pagination';
import { Button } from '@/components/ui/button';
import {
    Collapsible,
    CollapsibleContent,
    CollapsibleTrigger,
} from '@/components/ui/collapsible';
import { Input } from '@/components/ui/input';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { useCatalogLocale } from '@/hooks/use-catalog-locale';
import { formatCount, pickLocalizedName, updateQuery } from '@/lib/catalog';
import { cn } from '@/lib/utils';
import {
    store as categoryStore,
    destroy as categoryDestroy,
} from '@/routes/catalog/categories';
import { destroy as categoryItemDestroy } from '@/routes/catalog/categories/items';
import { show as elementShow } from '@/routes/catalog/structure/elements';
import type {
    CatalogElementType,
    CatalogStructureIndexProps,
    CatalogStructureItem,
} from '@/types/catalog';

const TABS = [
    { id: 'categories', label: 'Categories' },
    { id: 'elements', label: 'Elements' },
    { id: 'sections', label: 'Section catalog' },
    { id: 'data-units', label: 'Data units' },
];

const ELEMENT_TYPE_STYLES: Record<CatalogElementType, string> = {
    feature: 'bg-green-50 text-green-700',
    data: 'bg-orange-50 text-amber-700',
    sub_category: 'bg-slate-100 text-slate-600',
};

const FLAG_STYLES: Record<string, string> = {
    ENGINE: 'bg-slate-100 text-slate-600',
    TRIM: 'bg-orange-50 text-amber-700',
};

export function StructureView({
    brands,
    brand_code,
    categories,
    elements,
    data_units,
    sections,
    filters,
}: CatalogStructureIndexProps) {
    const [tab, setTab] = useState('categories');
    const [searchInput, setSearchInput] = useState(filters.search ?? '');
    const [showCreate, setShowCreate] = useState(false);
    const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
    const { props } = usePage();
    const canEdit = props.auth.can.edit_catalog;
    const locale = useCatalogLocale();

    useEffect(() => {
        if (debounceRef.current) {
            clearTimeout(debounceRef.current);
        }

        debounceRef.current = setTimeout(() => {
            if (searchInput !== filters.search) {
                updateQuery(
                    { ...filters, search: searchInput || null },
                    { preserveState: true, replace: true },
                );
            }
        }, 300);

        return () => {
            if (debounceRef.current) {
                clearTimeout(debounceRef.current);
            }
        };
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [searchInput]);

    const resetFilters = () => {
        setSearchInput('');
        updateQuery({ brand: brand_code });
    };

    return (
        <div className="custom-scroll flex-1 overflow-y-auto">
            <PageHeader
                title="Structure"
                subtitle="Catalog dictionaries — brand structure & shared vocabulary"
            />

            <div className="p-4 md:p-6">
                <div className="mb-4 flex flex-col gap-3">
                    <BrandTags
                        brands={brands.map((brand) => brand.code)}
                        active={brand_code}
                        onSelect={(brand) =>
                            router.get('/structure', {
                                brand: brand ?? undefined,
                            })
                        }
                    />
                    {tab === 'categories' && (
                        <div className="flex flex-wrap items-center gap-3">
                            <div className="relative w-full max-w-md">
                                <Input
                                    value={searchInput}
                                    onChange={(event) =>
                                        setSearchInput(event.target.value)
                                    }
                                    placeholder="Search categories and items..."
                                    className="bg-white py-2 pr-3 pl-9 text-xs"
                                />
                                <Search
                                    size={14}
                                    className="absolute top-2.5 left-3 text-gray-400"
                                />
                            </div>
                            <Select
                                value={filters.element_type ?? 'all'}
                                onValueChange={(value) =>
                                    updateQuery({
                                        ...filters,
                                        element_type:
                                            value === 'all' ? null : value,
                                    })
                                }
                            >
                                <SelectTrigger
                                    size="sm"
                                    className="w-44 bg-white text-xs"
                                >
                                    <SelectValue placeholder="All element types" />
                                </SelectTrigger>
                                <SelectContent>
                                    <SelectItem value="all">
                                        All element types
                                    </SelectItem>
                                    <SelectItem value="feature">
                                        Feature
                                    </SelectItem>
                                    <SelectItem value="data">Data</SelectItem>
                                    <SelectItem value="sub_category">
                                        Sub category
                                    </SelectItem>
                                </SelectContent>
                            </Select>
                        </div>
                    )}
                </div>

                <ChromeTabs tabs={TABS} active={tab} onChange={setTab} />

                <div className="rounded-tr-xl rounded-b-xl border border-t-0 border-[rgba(30,25,50,0.06)] bg-white shadow-[0_2px_8px_rgba(30,25,50,0.04)]">
                    {tab === 'categories' && (
                        <>
                            {canEdit && (
                                <div className="border-b border-gray-50 px-4 py-2">
                                    {!showCreate ? (
                                        <Button
                                            type="button"
                                            size="sm"
                                            variant="outline"
                                            onClick={() => setShowCreate(true)}
                                        >
                                            <Plus size={14} />
                                            New category
                                        </Button>
                                    ) : (
                                        <CategoryCreateForm
                                            brandCode={brand_code}
                                            onClose={() => setShowCreate(false)}
                                        />
                                    )}
                                </div>
                            )}
                            {categories.meta.total === 0 ? (
                                <EmptyState
                                    title="No categories match the current filters"
                                    description="Adjust the brand, search or element-type filters."
                                    action={
                                        <button
                                            type="button"
                                            onClick={resetFilters}
                                            className="inline-flex cursor-pointer items-center gap-1.5 rounded-lg bg-astara-orange px-4 py-2 text-[10px] font-bold tracking-widest text-white uppercase transition-all hover:bg-astara-orange-hover"
                                        >
                                            <RefreshCcw size={12} />
                                            Reset filters
                                        </button>
                                    }
                                />
                            ) : (
                                <>
                                    <div className="divide-y divide-gray-50">
                                        {categories.data.map((category) => (
                                            <CategoryRow
                                                key={category.id}
                                                category={category}
                                                canEdit={canEdit}
                                            />
                                        ))}
                                    </div>
                                    <Pagination
                                        links={categories.links}
                                        meta={categories.meta}
                                    />
                                </>
                            )}
                        </>
                    )}

                    {tab === 'elements' && (
                        <>
                            {elements.meta.total === 0 ? (
                                <EmptyState
                                    title="No elements match the current filters"
                                    description="Adjust the brand, search or element-type filters."
                                    action={
                                        <button
                                            type="button"
                                            onClick={resetFilters}
                                            className="inline-flex cursor-pointer items-center gap-1.5 rounded-lg bg-astara-orange px-4 py-2 text-[10px] font-bold tracking-widest text-white uppercase transition-all hover:bg-astara-orange-hover"
                                        >
                                            <RefreshCcw size={12} />
                                            Reset filters
                                        </button>
                                    }
                                />
                            ) : (
                                <>
                                    <div className="divide-y divide-gray-50">
                                        {elements.data.map((element) => {
                                            const elementName =
                                                pickLocalizedName(
                                                    element,
                                                    locale,
                                                    element.name,
                                                );

                                            return (
                                                <div
                                                    key={element.id}
                                                    className="flex items-center gap-3 px-4 py-2.5"
                                                >
                                                    <span className="font-mono text-[10px] text-gray-500">
                                                        {element.code}
                                                    </span>
                                                    <span
                                                        className={cn(
                                                            'inline-flex h-[16px] shrink-0 items-center rounded px-1.5 text-[8px] font-bold tracking-wider uppercase',
                                                            ELEMENT_TYPE_STYLES[
                                                                element
                                                                    .element_type
                                                            ],
                                                        )}
                                                    >
                                                        {element.element_type}
                                                    </span>
                                                    <span className="flex-1 truncate text-[11px] font-semibold text-gray-600">
                                                        {elementName.text}
                                                    </span>
                                                    {elementName.fellBack && (
                                                        <LocaleFallbackChip
                                                            requested={locale}
                                                            used={
                                                                elementName.locale
                                                            }
                                                        />
                                                    )}
                                                    <span className="text-[10px] font-bold text-gray-400">
                                                        {formatCount(
                                                            element.categories_count,
                                                        )}{' '}
                                                        categories
                                                    </span>
                                                </div>
                                            );
                                        })}
                                    </div>
                                    <Pagination
                                        links={elements.links}
                                        meta={elements.meta}
                                    />
                                </>
                            )}
                        </>
                    )}

                    {tab === 'sections' && (
                        <div className="divide-y divide-gray-50">
                            {sections.map((section) => (
                                <div
                                    key={section.section_key}
                                    className="flex items-start gap-3 px-4 py-3"
                                >
                                    <span className="mt-0.5 shrink-0 font-mono text-[11px] font-bold text-astara-purple">
                                        {section.section_key}
                                    </span>
                                    <span
                                        className={cn(
                                            'mt-0.5 inline-flex h-[16px] shrink-0 items-center rounded px-1.5 text-[8px] font-bold tracking-wider uppercase',
                                            FLAG_STYLES[section.flag],
                                        )}
                                    >
                                        {section.flag}
                                    </span>
                                    <div className="flex-1">
                                        <p className="text-[11px] font-bold text-gray-600">
                                            {section.display_name}
                                        </p>
                                        <p className="text-[10px] leading-relaxed text-gray-400">
                                            {section.description}
                                        </p>
                                    </div>
                                </div>
                            ))}
                            <div className="border-t border-gray-50 px-4 py-2.5 text-[10px] text-gray-400">
                                Shared section definitions. The per-body-type
                                section elements (23,345 rows) are served on the
                                body-type detail pages.
                            </div>
                        </div>
                    )}

                    {tab === 'data-units' && (
                        <div className="divide-y divide-gray-50">
                            {data_units.map((unit) => (
                                <div
                                    key={unit.code}
                                    className="flex items-center justify-between px-4 py-2.5"
                                >
                                    <span className="font-mono text-[11px] font-bold text-astara-purple">
                                        {unit.code}
                                    </span>
                                    <span className="flex items-center gap-3 text-[10px] font-semibold text-gray-500">
                                        <span>
                                            {formatCount(
                                                unit.entity_data_values_count,
                                            )}{' '}
                                            <span className="text-[9px] font-bold tracking-widest text-gray-400 uppercase">
                                                data values
                                            </span>
                                        </span>
                                        <span>
                                            {formatCount(
                                                unit.body_type_section_elements_count,
                                            )}{' '}
                                            <span className="text-[9px] font-bold tracking-widest text-gray-400 uppercase">
                                                section elements
                                            </span>
                                        </span>
                                    </span>
                                </div>
                            ))}
                            {data_units.length === 0 && (
                                <div className="px-4 py-6 text-[11px] text-gray-400">
                                    No data units imported yet.
                                </div>
                            )}
                        </div>
                    )}
                </div>
            </div>
        </div>
    );
}

function CategoryCreateForm({
    brandCode,
    onClose,
}: {
    brandCode: string;
    onClose: () => void;
}) {
    const [nameDe, setNameDe] = useState('');
    const [nameFr, setNameFr] = useState('');
    const [nameIt, setNameIt] = useState('');

    const submit = (event: React.FormEvent) => {
        event.preventDefault();
        router.post(
            categoryStore({
                query: { brand: brandCode, market: 'CH' },
            }) as never,
            {
                name_de: nameDe,
                name_fr: nameFr || null,
                name_it: nameIt || null,
            },
            { preserveScroll: true, onSuccess: onClose },
        );
    };

    return (
        <form
            onSubmit={submit}
            className="flex flex-wrap items-end gap-2 rounded-lg border border-gray-100 bg-gray-50/60 p-3"
        >
            <div>
                <label className="mb-1 block text-[9px] font-bold tracking-widest text-gray-400 uppercase">
                    Name (DE) *
                </label>
                <Input
                    value={nameDe}
                    onChange={(event) => setNameDe(event.target.value)}
                    required
                    className="h-8 w-48 bg-white text-xs"
                    placeholder="Kategorie DE"
                />
            </div>
            <div>
                <label className="mb-1 block text-[9px] font-bold tracking-widest text-gray-400 uppercase">
                    Name (FR)
                </label>
                <Input
                    value={nameFr}
                    onChange={(event) => setNameFr(event.target.value)}
                    className="h-8 w-48 bg-white text-xs"
                    placeholder="Catégorie FR"
                />
            </div>
            <div>
                <label className="mb-1 block text-[9px] font-bold tracking-widest text-gray-400 uppercase">
                    Name (IT)
                </label>
                <Input
                    value={nameIt}
                    onChange={(event) => setNameIt(event.target.value)}
                    className="h-8 w-48 bg-white text-xs"
                    placeholder="Categoria IT"
                />
            </div>
            <div className="flex items-center gap-1.5">
                <Button type="submit" size="sm">
                    Create
                </Button>
                <Button
                    type="button"
                    size="sm"
                    variant="ghost"
                    onClick={onClose}
                >
                    <X size={14} />
                </Button>
            </div>
        </form>
    );
}

function CategoryRow({
    category,
    canEdit,
}: {
    canEdit: boolean;

    category: CatalogStructureIndexProps['categories']['data'][number];
}) {
    const [open, setOpen] = useState(false);
    const locale = useCatalogLocale();

    const categoryName = pickLocalizedName(category, locale, category.name);

    return (
        <Collapsible open={open} onOpenChange={setOpen}>
            <CollapsibleTrigger className="group flex w-full cursor-pointer items-center justify-between px-4 py-3 text-left transition-colors hover:bg-gray-50">
                <div>
                    <div className="flex items-center gap-2">
                        <span className="font-mono text-[11px] font-bold text-astara-purple">
                            {category.code}
                        </span>
                        <span className="text-[11px] font-semibold text-gray-600">
                            {categoryName.text}
                        </span>
                        {categoryName.fellBack && (
                            <LocaleFallbackChip
                                requested={locale}
                                used={categoryName.locale}
                            />
                        )}
                        <span className="text-[10px] font-bold text-gray-400">
                            {formatCount(category.items_count)} items
                        </span>
                    </div>
                    {category.disclaimer && (
                        <p className="mt-0.5 text-[10px] text-gray-400 italic">
                            {category.disclaimer}
                        </p>
                    )}
                </div>
                <span className="flex items-center gap-1">
                    {canEdit && category.items_count === 0 && (
                        <button
                            type="button"
                            title="Delete empty category"
                            onClick={(event) => {
                                event.stopPropagation();
                                router.delete(
                                    categoryDestroy({
                                        category: category.id,
                                    }) as never,
                                    { preserveScroll: true },
                                );
                            }}
                            className="flex h-7 w-7 cursor-pointer items-center justify-center rounded-md text-gray-300 transition-colors hover:bg-red-50 hover:text-red-600"
                        >
                            <Trash2 size={13} />
                        </button>
                    )}
                    <ChevronDown
                        size={14}
                        className={cn(
                            'text-gray-300 transition-transform',
                            open && 'rotate-180',
                        )}
                    />
                </span>
            </CollapsibleTrigger>
            <CollapsibleContent>
                <div className="divide-y divide-gray-50 border-t border-gray-50 bg-gray-50/50">
                    {category.items.length === 0 && (
                        <div className="px-4 py-3 text-[11px] text-gray-400">
                            No items match the current filters.
                        </div>
                    )}
                    {category.items.map((item) => (
                        <ItemRow
                            key={item.id}
                            item={item}
                            categoryId={category.id}
                            canDelete={canEdit}
                        />
                    ))}
                </div>
            </CollapsibleContent>
        </Collapsible>
    );
}

function ItemRow({
    item,
    categoryId,
    canDelete,
}: {
    item: CatalogStructureItem;
    categoryId: number;
    canDelete: boolean;
}) {
    const locale = useCatalogLocale();

    const itemName = pickLocalizedName(item, locale, item.name);
    const elementId = item.element?.id ?? null;

    const content = (
        <div className="flex w-full items-center gap-3 px-4 py-2">
            <span className="font-mono text-[10px] text-gray-400">
                {item.element_code}
            </span>
            <span
                className={cn(
                    'inline-flex h-[16px] shrink-0 items-center rounded px-1.5 text-[8px] font-bold tracking-wider uppercase',
                    ELEMENT_TYPE_STYLES[item.element_type],
                )}
            >
                {item.element_type}
            </span>
            <span className="flex-1 truncate text-[11px] font-semibold text-gray-600">
                {itemName.text}
            </span>
            {itemName.fellBack && (
                <LocaleFallbackChip requested={locale} used={itemName.locale} />
            )}
            <span className="text-[9px] font-bold text-gray-300">
                #{item.sort_order}
            </span>
        </div>
    );

    const visitable = elementId !== null;

    return (
        <div
            className={cn(
                'group/item flex w-full items-center transition-colors',
                !visitable && 'bg-gray-50/50',
            )}
        >
            {visitable ? (
                <button
                    type="button"
                    onClick={() =>
                        router.visit(elementShow({ element: elementId }))
                    }
                    className="min-w-0 flex-1 cursor-pointer text-left hover:bg-white"
                >
                    {content}
                </button>
            ) : (
                <div className="min-w-0 flex-1">{content}</div>
            )}
            {/* Item removal unlocks the empty-category delete (audit gap 4). */}
            {canDelete && (
                <button
                    type="button"
                    title="Remove item from category"
                    onClick={() =>
                        router.delete(
                            categoryItemDestroy({
                                category: categoryId,
                                item: item.id,
                            }) as never,
                            { preserveScroll: true },
                        )
                    }
                    className="mr-3 flex h-6 w-6 shrink-0 cursor-pointer items-center justify-center rounded-md text-gray-300 opacity-0 transition-opacity group-hover/item:opacity-100 hover:bg-red-50 hover:text-red-600"
                >
                    <X size={12} />
                </button>
            )}
        </div>
    );
}
