import { router } from '@inertiajs/react';
import type { ColDef, SortChangedEvent } from 'ag-grid-community';
import { AgGridReact } from 'ag-grid-react';
import type { CustomCellRendererProps } from 'ag-grid-react';
import { RefreshCcw, Search } from 'lucide-react';
import { useEffect, useRef, useState } from 'react';
import { BrandChip } from '@/components/shared/badges';
import { EmptyState } from '@/components/shared/empty-state';
import { PageHeader } from '@/components/shared/page-header';
import { Pagination } from '@/components/shared/pagination';
import { Input } from '@/components/ui/input';
import { astaraGridTheme } from '@/lib/ag-grid-theme';
import { brandLabel, formatCount, updateQuery } from '@/lib/catalog';
import { detail as engineDetail } from '@/routes/catalog/engines';
import type { CatalogEngine, CatalogEnginesIndexProps } from '@/types/catalog';

const SORT_COLUMNS: Record<string, string> = {
    brand: 'brand',
    engine_key: 'engine_key',
    created: 'created',
};

function initialSort(filters: CatalogEnginesIndexProps['filters']) {
    const colId = Object.entries(SORT_COLUMNS).find(
        ([, value]) => value === filters.sort,
    )?.[0];

    return colId
        ? {
              colId,
              sort: filters.direction ?? 'asc',
          }
        : null;
}

const BrandCell = ({ data }: CustomCellRendererProps<CatalogEngine>) => (
    <div className="flex h-full items-center">
        {data?.brand && <BrandChip label={brandLabel(data.brand.code)} />}
    </div>
);

const MonoCell = ({ value }: { value: string | null }) => (
    <div className="flex h-full items-center font-mono text-[10px] text-gray-500">
        {value ?? '—'}
    </div>
);

const CountCell = ({ value }: { value: number }) => (
    <div className="flex h-full items-center text-[11px] font-bold text-astara-purple tabular-nums">
        {formatCount(value)}
    </div>
);

const TextCell = ({ value }: { value: string | number | null }) => (
    <div className="flex h-full items-center text-[11px] text-slate-600">
        {value ?? '—'}
    </div>
);

export function EnginesIndexView({
    engines,
    filters,
}: CatalogEnginesIndexProps) {
    const [searchInput, setSearchInput] = useState(filters.search ?? '');
    const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);

    const [columnDefs] = useState<ColDef<CatalogEngine>[]>(() => {
        const sort = initialSort(filters);

        return [
            {
                colId: 'brand',
                headerName: 'Brand',
                field: 'brand.code',
                width: 120,
                sortable: true,
                sort: sort?.colId === 'brand' ? sort.sort : undefined,
                cellRenderer: BrandCell,
            },
            {
                colId: 'engine_key',
                headerName: 'Key',
                field: 'engine_key',
                width: 170,
                sortable: true,
                sort: sort?.colId === 'engine_key' ? sort.sort : undefined,
                cellRenderer: (
                    params: CustomCellRendererProps<CatalogEngine>,
                ) => <MonoCell value={params.data?.engine_key ?? null} />,
            },
            {
                colId: 'engine_name',
                headerName: 'Name',
                field: 'engine_name',
                flex: 2,
                minWidth: 220,
                cellRenderer: (
                    params: CustomCellRendererProps<CatalogEngine>,
                ) => (
                    <div className="flex h-full items-center overflow-hidden">
                        <span className="truncate text-xs font-bold text-astara-purple">
                            {params.data?.engine_name ??
                                params.data?.engine_key}
                        </span>
                    </div>
                ),
            },
            {
                colId: 'fuel_type',
                headerName: 'Fuel',
                field: 'fuel_type',
                width: 110,
                cellRenderer: (
                    params: CustomCellRendererProps<CatalogEngine>,
                ) => <TextCell value={params.data?.fuel_type ?? null} />,
            },
            {
                colId: 'power',
                headerName: 'Power',
                field: 'power_kw',
                width: 130,
                cellRenderer: (
                    params: CustomCellRendererProps<CatalogEngine>,
                ) => (
                    <TextCell
                        value={
                            params.data?.power_kw !== null &&
                            params.data?.power_kw !== undefined
                                ? `${params.data.power_kw} kW / ${params.data.power_ps ?? '—'} PS`
                                : null
                        }
                    />
                ),
            },
            {
                colId: 'displacement',
                headerName: 'Displacement',
                field: 'displacement',
                width: 120,
                cellRenderer: (
                    params: CustomCellRendererProps<CatalogEngine>,
                ) => (
                    <TextCell
                        value={
                            params.data?.displacement !== null &&
                            params.data?.displacement !== undefined
                                ? `${params.data.displacement} ${params.data.displacement_unit ?? ''}`
                                : null
                        }
                    />
                ),
            },
            {
                colId: 'emission_class',
                headerName: 'Emission class',
                field: 'emission_class',
                width: 130,
                cellRenderer: (
                    params: CustomCellRendererProps<CatalogEngine>,
                ) => <TextCell value={params.data?.emission_class ?? null} />,
            },
            {
                colId: 'body_types',
                headerName: 'Body types',
                field: 'body_types_count',
                width: 110,
                cellRenderer: (
                    params: CustomCellRendererProps<CatalogEngine>,
                ) => <CountCell value={params.data?.body_types_count ?? 0} />,
            },
            {
                colId: 'variants',
                headerName: 'Variants',
                field: 'variants_count',
                width: 100,
                cellRenderer: (
                    params: CustomCellRendererProps<CatalogEngine>,
                ) => <CountCell value={params.data?.variants_count ?? 0} />,
            },
            {
                colId: 'emissions',
                headerName: 'Emissions',
                field: 'emissions_count',
                width: 100,
                cellRenderer: (
                    params: CustomCellRendererProps<CatalogEngine>,
                ) => <CountCell value={params.data?.emissions_count ?? 0} />,
            },
        ];
    });

    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 onSortChanged = (event: SortChangedEvent<CatalogEngine>) => {
        if (event.source === 'api') {
            return;
        }

        const sorted = event.api
            .getColumnState()
            .find(
                (column) => column.sort !== undefined && column.sort !== null,
            );

        updateQuery({
            ...filters,
            sort: sorted ? SORT_COLUMNS[sorted.colId] : null,
            direction: sorted?.sort ?? null,
        });
    };

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

    return (
        <div className="flex flex-1 flex-col overflow-hidden">
            <PageHeader
                title="Engines"
                subtitle="Global engine dictionary — brand-scoped keys"
            />

            <div className="custom-scroll flex-1 overflow-y-auto p-4 md:p-6">
                <div className="mb-4 flex flex-col gap-3">
                    <div className="relative w-full max-w-md">
                        <Input
                            value={searchInput}
                            onChange={(event) =>
                                setSearchInput(event.target.value)
                            }
                            placeholder="Search engine key or name..."
                            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>
                </div>

                {engines.meta.total === 0 ? (
                    <div className="rounded-xl border border-[rgba(30,25,50,0.06)] bg-white shadow-[0_2px_8px_rgba(30,25,50,0.04)]">
                        <EmptyState
                            title="No engines match the current filters"
                            description="Adjust the search or brand filter — or reset everything."
                            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>
                ) : (
                    <div className="flex flex-col overflow-hidden rounded-xl border border-[rgba(30,25,50,0.06)] bg-white shadow-[0_2px_8px_rgba(30,25,50,0.04)]">
                        <div className="h-[560px]">
                            <AgGridReact<CatalogEngine>
                                theme={astaraGridTheme}
                                rowData={engines.data}
                                columnDefs={columnDefs}
                                getRowId={(params) => String(params.data.id)}
                                onCellClicked={(event) => {
                                    if (event.data) {
                                        router.visit(
                                            engineDetail({
                                                engine: event.data.id,
                                            }),
                                        );
                                    }
                                }}
                                onSortChanged={onSortChanged}
                                rowClass="cursor-pointer"
                                rowHeight={40}
                                headerHeight={36}
                                suppressCellFocus
                                defaultColDef={{ resizable: true }}
                            />
                        </div>
                        <Pagination links={engines.links} meta={engines.meta} />
                    </div>
                )}
            </div>
        </div>
    );
}
