import { Head, router } from '@inertiajs/react';
import type { Row } from '@tanstack/react-table';
import { Filter, Plus, X } from 'lucide-react';
import { useCallback, useMemo, useState } from 'react';
import { ConfirmDialog } from '@/components/confirm-dialog';
import type { PaginationState, SortState } from '@/components/data-table';
import { DataTable } from '@/components/data-table';
import { ImagePreviewModal } from '@/components/image-preview-modal';
import { Button } from '@/components/ui/button';
import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem, ComboboxList } from '@/components/ui/combobox';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import { destroy, create as productCreate, index as productIndex, edit as productEdit, toggleStatus } from '@/routes/admin/master/products';
import type { Product } from './columns';
import { createProductColumns } from './columns';

type Props = {
    products: {
        data: Product[];
        current_page: number;
        last_page: number;
        per_page: number;
        total: number;
    };
    filters: {
        status?: string;
        name?: string;
    };
};

function formatCurrency(amount: number): string {
    return new Intl.NumberFormat('id-ID', {
        style: 'currency',
        currency: 'IDR',
        minimumFractionDigits: 0,
    }).format(amount);
}

function formatNumber(num: number): string {
    return new Intl.NumberFormat('id-ID').format(num);
}

function VariantPhotoPreview({ url, title }: { url: string; title: string }) {
    const [open, setOpen] = useState(false);

    return (
        <>
            <button
                onClick={() => setOpen(true)}
                className="block h-10 w-10 overflow-hidden rounded-md border bg-muted transition-opacity hover:opacity-80"
            >
                <img
                    src={url}
                    alt={title}
                    className="h-full w-full object-cover"
                />
            </button>
            <ImagePreviewModal
                open={open}
                onOpenChange={setOpen}
                src={url}
                title={title}
            />
        </>
    );
}

function VariantSubRow({ row, searchValue }: { row: Row<Product>; searchValue?: string }) {
    const allVariants = row.original.product_variants ?? [];
    const query = (searchValue ?? '').toLowerCase().trim();
    const variants = query
        ? allVariants.filter((v) => v.name.toLowerCase().includes(query))
        : allVariants;

    return (
        <Table>
            <TableHeader>
                <TableRow>
                    <TableHead className="w-[60px]">Foto</TableHead>
                    <TableHead className="w-[200px]">Nama Varian</TableHead>
                    <TableHead className="text-center">Stok Bagus</TableHead>
                    <TableHead className="text-center">Stok Reject</TableHead>
                    <TableHead className="text-center">Stok Ecer</TableHead>
                    <TableHead>Harga</TableHead>
                </TableRow>
            </TableHeader>
            <TableBody>
                {variants.length === 0 ? (
                    <TableRow>
                        <TableCell colSpan={6} className="text-center text-muted-foreground">
                            Tidak ada varian.
                        </TableCell>
                    </TableRow>
                ) : (
                    variants.map((variant) => (
                        <TableRow key={variant.id}>
                            <TableCell>
                                {variant.photo_url ? (
                                    <VariantPhotoPreview
                                        url={variant.photo_url}
                                        title={variant.name}
                                    />
                                ) : (
                                    <div className="flex h-10 w-10 items-center justify-center rounded-md bg-muted text-xs text-muted-foreground">
                                        N/A
                                    </div>
                                )}
                            </TableCell>
                            <TableCell className="font-medium">{variant.name}</TableCell>
                            <TableCell className="text-center">{formatNumber(variant.stock)}</TableCell>
                            <TableCell className="text-center">{formatNumber(variant.reject_stock)}</TableCell>
                            <TableCell className="text-center">{formatNumber(variant.retail_stock)}</TableCell>
                            <TableCell>
                                {variant.product_prices?.length > 0 ? (
                                    <div className="flex flex-col gap-0.5">
                                        {variant.product_prices.map((p) => (
                                            <span key={p.id} className="text-xs">
                                                <span className="text-muted-foreground">{p.type_label}:</span>{' '}
                                                {formatCurrency(p.price)}
                                            </span>
                                        ))}
                                    </div>
                                ) : '-'}
                            </TableCell>
                        </TableRow>
                    ))
                )}
            </TableBody>
        </Table>
    );
}

export default function ProductIndex({ products, filters }: Props) {
    const [deleting, setDeleting] = useState<Product | null>(null);
    const [filterOpen, setFilterOpen] = useState(false);
    const [search, setSearch] = useState('');
    const [sort, setSort] = useState<SortState>({ column: 'created_at', direction: 'desc' });

    const hasActiveFilters = filters.status || filters.name;

    const pagination: PaginationState = {
        current_page: products.current_page,
        last_page: products.last_page,
        per_page: products.per_page,
        total: products.total,
    };

    const productNames = useMemo(() => {
        const names = products.data.map((p) => p.name);

        return [...new Set(names)].sort();
    }, [products.data]);

    function applyFilter(key: string, value: string) {
        const newFilters = { ...filters };

        if (value === '' || value === 'all') {
            delete newFilters[key as keyof typeof newFilters];
        } else {
            newFilters[key as keyof typeof newFilters] = value;
        }

        router.get(productIndex(), newFilters, {
            preserveState: true,
            replace: true,
        });
    }

    function clearFilters() {
        router.get(productIndex(), {}, {
            preserveState: true,
            replace: true,
        });
        setFilterOpen(false);
    }

    function handlePageChange(page: number) {
        router.get(productIndex.url(), {
            page,
            per_page: pagination.per_page,
            search,
            sort: sort.column,
            direction: sort.direction,
            ...filters,
        }, { preserveState: true, replace: true });
    }

    function handlePerPageChange(perPage: number) {
        router.get(productIndex.url(), {
            page: 1,
            per_page: perPage,
            search,
            sort: sort.column,
            direction: sort.direction,
            ...filters,
        }, { preserveState: true, replace: true });
    }

    const handleSearchChange = useCallback((value: string) => {
        setSearch(value);
        router.get(productIndex.url(), {
            page: 1,
            per_page: pagination.per_page,
            search: value,
            sort: sort.column,
            direction: sort.direction,
            ...filters,
        }, { preserveState: true, replace: true });
    }, [pagination.per_page, sort, filters]);

    function handleSortChange(column: string, direction: 'asc' | 'desc') {
        setSort({ column, direction });
        router.get(productIndex.url(), {
            page: 1,
            per_page: pagination.per_page,
            search,
            sort: column,
            direction,
            ...filters,
        }, { preserveState: true, replace: true });
    }

    function handleDelete() {
        if (!deleting) {
            return;
        }

        router.delete(destroy.url(deleting.id), {
            onSuccess: () => setDeleting(null),
        });
    }

    const columns = createProductColumns({
        handleEdit: (product) => {
            window.location.href = productEdit.url(product.id);
        },
        handleDeleteClick: (product) => setDeleting(product),
        toggleStatusUrl: (id) => toggleStatus.url(id),
    });

    const filterToolbar = (
        <Popover open={filterOpen} onOpenChange={setFilterOpen}>
            <PopoverTrigger asChild>
                <Button variant="outline" size="sm">
                    <Filter className="h-4 w-4" />
                    Filter
                    {hasActiveFilters && (
                        <span className="ml-1 flex h-5 w-5 items-center justify-center rounded-full bg-primary text-xs text-primary-foreground">
                            {Object.values(filters).filter(Boolean).length}
                        </span>
                    )}
                </Button>
            </PopoverTrigger>
            <PopoverContent className="w-64" align="end">
                <div className="flex flex-col gap-4">
                    <div className="flex items-center justify-between">
                        <span className="text-sm font-medium">Filter</span>
                        {hasActiveFilters && (
                            <Button
                                variant="ghost"
                                size="sm"
                                className="h-6 px-2 text-xs"
                                onClick={clearFilters}
                            >
                                <X className="mr-1 h-3 w-3" />
                                Hapus Semua
                            </Button>
                        )}
                    </div>

                    <div className="flex flex-col gap-2">
                        <label className="text-xs text-muted-foreground">
                            Nama Produk
                        </label>
                        <Combobox
                            value={filters.name ?? ''}
                            onValueChange={(value) => applyFilter('name', value as string)}
                        >
                            <ComboboxInput placeholder="Pilih produk..." className="w-full" />
                            <ComboboxContent>
                                <ComboboxEmpty>Tidak ada produk ditemukan.</ComboboxEmpty>
                                <ComboboxList>
                                    {productNames.map((name) => (
                                        <ComboboxItem key={name} value={name}>
                                            {name}
                                        </ComboboxItem>
                                    ))}
                                </ComboboxList>
                            </ComboboxContent>
                        </Combobox>
                    </div>

                    <div className="flex flex-col gap-2">
                        <label className="text-xs text-muted-foreground">
                            Status
                        </label>
                        <Select
                            value={filters.status ?? 'all'}
                            onValueChange={(value) => applyFilter('status', value)}
                        >
                            <SelectTrigger className="w-full">
                                <SelectValue placeholder="Semua Status" />
                            </SelectTrigger>
                            <SelectContent>
                                <SelectItem value="all">Semua Status</SelectItem>
                                <SelectItem value="active">Aktif</SelectItem>
                                <SelectItem value="inactive">Non Aktif</SelectItem>
                                <SelectItem value="draft">Draft</SelectItem>
                            </SelectContent>
                        </Select>
                    </div>
                </div>
            </PopoverContent>
        </Popover>
    );

    return (
        <>
            <Head title="Produk" />

            <div className="flex h-full flex-1 flex-col gap-6 overflow-x-auto p-4 md:p-6">
                <div className="flex items-center justify-between">
                    <div>
                        <h2 className="text-2xl font-semibold tracking-tight">
                            Produk
                        </h2>
                    </div>
                    <Button asChild>
                        <a href={productCreate.url()}>
                            <Plus className="h-4 w-4" />
                            Tambah
                        </a>
                    </Button>
                </div>

                <DataTable
                    columns={columns}
                    data={products.data}
                    searchKey="name"
                    searchPlaceholder="Cari produk..."
                    emptyText="Belum ada data produk."
                    pagination={pagination}
                    onPageChange={handlePageChange}
                    onPerPageChange={handlePerPageChange}
                    onSearchChange={handleSearchChange}
                    onSortChange={handleSortChange}
                    currentSort={sort}
                    searchValue={search}
                    renderSubRow={(row, searchValue) => <VariantSubRow row={row} searchValue={searchValue} />}
                    defaultExpanded
                    toolbar={filterToolbar}
                />

                <ConfirmDialog
                    open={deleting !== null}
                    onOpenChange={(open) => {
                        if (!open) {
                            setDeleting(null);
                        }
                    }}
                    title="Hapus Produk"
                    description={`Apakah Anda yakin ingin menghapus produk "${deleting?.name}"? Tindakan ini tidak dapat dibatalkan.`}
                    confirmLabel="Hapus"
                    onConfirm={handleDelete}
                />
            </div>
        </>
    );
}

ProductIndex.layout = {
    breadcrumbs: [
        {
            title: 'Master',
            href: productIndex.url(),
        },
        {
            title: 'Produk',
            href: productIndex.url(),
        },
    ],
};
