import { Head, Link, router } from '@inertiajs/react';
import { Boxes, PackagePlus, Plus, SearchX } from 'lucide-react';
import { useEffect, useState } from 'react';
import { EmptyState, PageHeader } from '@/components/crm/page-header';
import {
    StockStatusBadge,
    VerificationBadge,
} from '@/components/crm/stock-badge';
import {
    DataPagination,
    FilterBar,
    FilterField,
    SearchInput,
    TableCard,
} from '@/components/crm/toolbar';
import { NativeSelect } from '@/components/crm/native-select';
import { Button } from '@/components/ui/button';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import { cn } from '@/lib/utils';
import {
    create as productsCreate,
    index as productsIndex,
    show as productShow,
} from '@/routes/warehouse/products';
import { inventory } from '@/routes/warehouse';
import type {
    Option,
    Paginated,
    ProductSummary,
    ProductVerification,
    WarehouseAbilities,
} from '@/types';

type Filters = {
    search: string | null;
    category: number | null;
    status: string;
    stock: string | null;
    verification: string | null;
};

type Props = {
    products: Paginated<ProductSummary>;
    filters: Filters;
    filterOptions: {
        categories: Array<{ value: number; label: string }>;
        verifications: ProductVerification[];
        statuses: Option[];
    };
    counts: { all: number; low: number; out: number };
    can: WarehouseAbilities;
};

export default function ProductsIndex({
    products,
    filters,
    filterOptions,
    counts,
    can,
}: Props) {
    const [search, setSearch] = useState(filters.search ?? '');

    useEffect(() => {
        setSearch(filters.search ?? '');
    }, [filters.search]);

    const apply = (patch: Partial<Filters>) => {
        const next = { ...filters, ...patch };
        const params: Record<string, string> = {};

        if (next.search) params.search = next.search;
        if (next.category) params.category = String(next.category);
        if (next.status && next.status !== 'active')
            params.status = next.status;
        if (next.stock) params.stock = next.stock;
        if (next.verification) params.verification = next.verification;

        router.get(productsIndex().url, params, {
            preserveState: true,
            preserveScroll: true,
            replace: true,
        });
    };

    const reset = () => {
        setSearch('');
        router.get(
            productsIndex().url,
            {},
            { preserveState: true, replace: true },
        );
    };

    const hasFilters =
        Boolean(filters.search) ||
        Boolean(filters.category) ||
        Boolean(filters.stock) ||
        Boolean(filters.verification) ||
        filters.status !== 'active';

    return (
        <>
            <Head title="Product catalogue" />

            <div className="flex flex-col gap-5">
                <PageHeader
                    eyebrow={
                        <>
                            <Boxes className="size-3.5 text-solar" />
                            <span>Warehouse</span>
                        </>
                    }
                    title="Product catalogue"
                    description="Every product the company buys and installs, held as data rather than in code. Quantities change only through recorded movements."
                    actions={
                        <>
                            <Button variant="outline" size="sm" asChild>
                                <Link href={inventory().url}>Stock levels</Link>
                            </Button>
                            {can.manage ? (
                                <Button size="sm" asChild>
                                    <Link href={productsCreate().url}>
                                        <Plus className="size-4" />
                                        New product
                                    </Link>
                                </Button>
                            ) : null}
                        </>
                    }
                />

                <form
                    onSubmit={(event) => {
                        event.preventDefault();
                        apply({ search });
                    }}
                >
                    <FilterBar>
                        <SearchInput
                            value={search}
                            onChange={setSearch}
                            placeholder="Code, name, brand, model or location"
                            className="min-w-[16rem]"
                        />
                        <FilterField label="Category" className="w-52">
                            <NativeSelect
                                value={
                                    filters.category
                                        ? String(filters.category)
                                        : ''
                                }
                                onChange={(event) =>
                                    apply({
                                        category: event.target.value
                                            ? Number(event.target.value)
                                            : null,
                                    })
                                }
                            >
                                <option value="">All categories</option>
                                {filterOptions.categories.map((category) => (
                                    <option
                                        key={category.value}
                                        value={String(category.value)}
                                    >
                                        {category.label}
                                    </option>
                                ))}
                            </NativeSelect>
                        </FilterField>

                        <FilterField label="Stock" className="w-40">
                            <NativeSelect
                                value={filters.stock ?? ''}
                                onChange={(event) =>
                                    apply({
                                        stock: event.target.value || null,
                                    })
                                }
                            >
                                <option value="">Any stock level</option>
                                <option value="low">
                                    Low stock ({counts.low})
                                </option>
                                <option value="out">
                                    Out of stock ({counts.out})
                                </option>
                            </NativeSelect>
                        </FilterField>

                        <FilterField label="Verification" className="w-48">
                            <NativeSelect
                                value={filters.verification ?? ''}
                                onChange={(event) =>
                                    apply({
                                        verification:
                                            event.target.value || null,
                                    })
                                }
                            >
                                <option value="">Any provenance</option>
                                {filterOptions.verifications.map(
                                    (verification) => (
                                        <option
                                            key={verification.value}
                                            value={verification.value}
                                        >
                                            {verification.label}
                                        </option>
                                    ),
                                )}
                            </NativeSelect>
                        </FilterField>

                        <FilterField label="Status" className="w-32">
                            <NativeSelect
                                value={filters.status}
                                onChange={(event) =>
                                    apply({ status: event.target.value })
                                }
                            >
                                {filterOptions.statuses.map((status) => (
                                    <option
                                        key={status.value}
                                        value={status.value}
                                    >
                                        {status.label}
                                    </option>
                                ))}
                            </NativeSelect>
                        </FilterField>

                        {hasFilters ? (
                            <button
                                type="button"
                                onClick={reset}
                                className="mt-4 text-xs text-muted-foreground underline-offset-2 hover:text-foreground hover:underline"
                            >
                                Clear
                            </button>
                        ) : null}
                    </FilterBar>
                </form>

                {products.data.length === 0 ? (
                    <TableCard>
                        <EmptyState
                            icon={hasFilters ? SearchX : PackagePlus}
                            title={
                                hasFilters
                                    ? 'No products match those filters'
                                    : 'The catalogue is empty'
                            }
                            description={
                                hasFilters
                                    ? 'Try a different category or clear the filters.'
                                    : 'Add the first product, or run the starter catalogue seeder to create the generic headings.'
                            }
                            action={
                                can.manage ? (
                                    <Button size="sm" asChild>
                                        <Link href={productsCreate().url}>
                                            <Plus className="size-4" />
                                            New product
                                        </Link>
                                    </Button>
                                ) : undefined
                            }
                        />
                    </TableCard>
                ) : (
                    <TableCard>
                        <Table>
                            <TableHeader>
                                <TableRow className="hover:bg-transparent">
                                    <TableHead className="bg-surface/60 text-[11px] font-semibold tracking-wide uppercase">
                                        Product
                                    </TableHead>
                                    <TableHead className="bg-surface/60 text-[11px] font-semibold tracking-wide uppercase">
                                        Category
                                    </TableHead>
                                    <TableHead className="bg-surface/60 text-[11px] font-semibold tracking-wide uppercase">
                                        Provenance
                                    </TableHead>
                                    <TableHead className="bg-surface/60 text-right text-[11px] font-semibold tracking-wide uppercase">
                                        On hand
                                    </TableHead>
                                    <TableHead className="bg-surface/60 text-right text-[11px] font-semibold tracking-wide uppercase">
                                        Reserved
                                    </TableHead>
                                    <TableHead className="bg-surface/60 text-right text-[11px] font-semibold tracking-wide uppercase">
                                        Available
                                    </TableHead>
                                    <TableHead className="bg-surface/60 text-[11px] font-semibold tracking-wide uppercase">
                                        Status
                                    </TableHead>
                                    {can.viewCosts ? (
                                        <TableHead className="bg-surface/60 text-right text-[11px] font-semibold tracking-wide uppercase">
                                            Stock value
                                        </TableHead>
                                    ) : null}
                                </TableRow>
                            </TableHeader>
                            <TableBody>
                                {products.data.map((product) => (
                                    <TableRow key={product.id}>
                                        <TableCell>
                                            <Link
                                                href={
                                                    productShow(product.id).url
                                                }
                                                className="group/cell block"
                                            >
                                                <span className="block font-medium group-hover/cell:underline">
                                                    {product.name}
                                                </span>
                                                <span className="block font-mono text-xs text-muted-foreground">
                                                    {product.sku}
                                                    {product.brand
                                                        ? ` · ${product.brand}`
                                                        : ''}
                                                    {product.model_number
                                                        ? ` · ${product.model_number}`
                                                        : ''}
                                                </span>
                                            </Link>
                                        </TableCell>
                                        <TableCell className="text-sm text-muted-foreground">
                                            {product.category?.name ?? '—'}
                                        </TableCell>
                                        <TableCell>
                                            <VerificationBadge
                                                verification={
                                                    product.verification
                                                }
                                            />
                                        </TableCell>
                                        <TableCell className="text-right tabular-nums crm-num">
                                            {product.physical_quantity}
                                        </TableCell>
                                        <TableCell className="text-right text-muted-foreground tabular-nums crm-num">
                                            {product.reserved_quantity}
                                        </TableCell>
                                        <TableCell className="text-right font-medium tabular-nums crm-num">
                                            {product.available_quantity}
                                        </TableCell>
                                        <TableCell>
                                            <StockStatusBadge
                                                status={product.stock_status}
                                            />
                                        </TableCell>
                                        {can.viewCosts ? (
                                            <TableCell
                                                className={cn(
                                                    'text-right tabular-nums crm-num',
                                                    product.stock_value ===
                                                        null &&
                                                        'text-muted-foreground/60',
                                                )}
                                            >
                                                {product.stock_value === null
                                                    ? '—'
                                                    : `$${product.stock_value.toLocaleString(
                                                          'en-AU',
                                                          {
                                                              minimumFractionDigits: 2,
                                                              maximumFractionDigits: 2,
                                                          },
                                                      )}`}
                                            </TableCell>
                                        ) : null}
                                    </TableRow>
                                ))}
                            </TableBody>
                        </Table>
                        <DataPagination page={products} noun="products" />
                    </TableCard>
                )}
            </div>
        </>
    );
}
