import {
    ChevronLeft,
    ChevronRight,
    ChevronsLeft,
    ChevronsRight,
} from 'lucide-react';
import * as React from 'react';
import type { PaginationState } from '@/components/data-table';
import { useDebounce } from '@/components/data-table';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { Input } from '@/components/ui/input';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';

export type { PaginationState } from '@/components/data-table';

interface DataCardsProps<TData> {
    data: TData[];
    renderCard: (item: TData, index: number) => React.ReactNode;
    getRowId?: (item: TData) => string | number;
    searchKey?: string;
    searchPlaceholder?: string;
    emptyText?: string;
    toolbar?: React.ReactNode;
    pagination: PaginationState;
    onPageChange: (page: number) => void;
    onPerPageChange?: (perPage: number) => void;
    onSearchChange?: (search: string) => void;
    searchValue?: string;
}

export function DataCards<TData>({
    data,
    renderCard,
    getRowId,
    searchKey,
    searchPlaceholder = 'Ketikkan sesuatu...',
    emptyText = 'Tidak ada data.',
    toolbar,
    pagination,
    onPageChange,
    onPerPageChange,
    onSearchChange,
    searchValue,
}: DataCardsProps<TData>) {
    const [localSearch, setLocalSearch] = React.useState(searchValue ?? '');
    const [previousSearchValue, setPreviousSearchValue] =
        React.useState(searchValue);

    if (searchValue !== previousSearchValue) {
        setPreviousSearchValue(searchValue);
        setLocalSearch(searchValue ?? '');
    }

    const handleSearchDebounced = useDebounce(
        (value: string) => onSearchChange?.(value),
        300,
    );

    function handleSearchChange(value: string) {
        setLocalSearch(value);
        handleSearchDebounced(value);
    }

    const currentPage = pagination.current_page;
    const totalPages = pagination.last_page;

    return (
        <>
            {(searchKey || toolbar || onPerPageChange) && (
                <div className="flex items-center gap-2">
                    {searchKey && (
                        <Input
                            placeholder={searchPlaceholder}
                            value={localSearch}
                            onChange={(event) =>
                                handleSearchChange(event.target.value)
                            }
                            className="max-w-sm"
                        />
                    )}
                    {toolbar}
                    <div className="ml-auto flex items-center gap-2">
                        {onPerPageChange && (
                            <Select
                                value={String(pagination.per_page)}
                                onValueChange={(value) =>
                                    onPerPageChange(Number(value))
                                }
                            >
                                <SelectTrigger className="h-8 w-[70px]">
                                    <SelectValue />
                                </SelectTrigger>
                                <SelectContent>
                                    <SelectItem value="25">25</SelectItem>
                                    <SelectItem value="50">50</SelectItem>
                                    <SelectItem value="100">100</SelectItem>
                                    <SelectItem value="999999">
                                        Semua
                                    </SelectItem>
                                </SelectContent>
                            </Select>
                        )}
                    </div>
                </div>
            )}

            {data.length ? (
                <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
                    {data.map((item, index) => (
                        <Card
                            key={getRowId ? getRowId(item) : index}
                            className="overflow-hidden"
                        >
                            <CardContent>{renderCard(item, index)}</CardContent>
                        </Card>
                    ))}
                </div>
            ) : (
                <Card>
                    <CardContent className="flex h-24 items-center justify-center text-center text-muted-foreground">
                        {emptyText}
                    </CardContent>
                </Card>
            )}

            <div className="flex items-center justify-end gap-2">
                <span className="text-sm text-muted-foreground">
                    {`Halaman ${currentPage} dari ${totalPages}`}
                </span>
                <div className="flex items-center gap-1">
                    <Button
                        variant="outline"
                        size="sm"
                        onClick={() => onPageChange(1)}
                        disabled={currentPage <= 1}
                    >
                        <ChevronsLeft className="h-4 w-4" />
                    </Button>
                    <Button
                        variant="outline"
                        size="sm"
                        onClick={() => onPageChange(currentPage - 1)}
                        disabled={currentPage <= 1}
                    >
                        <ChevronLeft className="h-4 w-4" />
                    </Button>
                    <Button
                        variant="outline"
                        size="sm"
                        onClick={() => onPageChange(currentPage + 1)}
                        disabled={currentPage >= totalPages}
                    >
                        <ChevronRight className="h-4 w-4" />
                    </Button>
                    <Button
                        variant="outline"
                        size="sm"
                        onClick={() => onPageChange(totalPages)}
                        disabled={currentPage >= totalPages}
                    >
                        <ChevronsRight className="h-4 w-4" />
                    </Button>
                </div>
            </div>
        </>
    );
}
