import { ChevronDown, ChevronUp, ChevronsUpDown } from 'lucide-react';
import { useMemo, useState } from 'react';

export type SortDirection = 'asc' | 'desc';

export function useSort<T>(items: T[], defaultColumn: keyof T & string, defaultDirection: SortDirection = 'asc', getters?: Partial<Record<string, (item: T) => unknown>>) {
    const [sortColumn, setSortColumn] = useState<string>(defaultColumn);
    const [sortDirection, setSortDirection] = useState<SortDirection>(defaultDirection);

    const sorted = useMemo(() => {
        return [...items].sort((a, b) => {
            const getter = getters?.[sortColumn];
            const aVal = getter ? getter(a) : (a as Record<string, unknown>)[sortColumn];
            const bVal = getter ? getter(b) : (b as Record<string, unknown>)[sortColumn];
            if (aVal == null && bVal == null) return 0;
            if (aVal == null) return 1;
            if (bVal == null) return -1;
            const cmp =
                typeof aVal === 'string' && typeof bVal === 'string'
                    ? aVal.localeCompare(bVal)
                    : typeof aVal === 'boolean'
                      ? (aVal === bVal ? 0 : aVal ? -1 : 1)
                      : Number(aVal) - Number(bVal);
            return sortDirection === 'asc' ? cmp : -cmp;
        });
    }, [items, sortColumn, sortDirection]);

    function toggleSort(column: string) {
        if (column === sortColumn) {
            setSortDirection((d) => (d === 'asc' ? 'desc' : 'asc'));
        } else {
            setSortColumn(column);
            setSortDirection('asc');
        }
    }

    return { sorted, sortColumn, sortDirection, toggleSort };
}

export function SortableHeader({
    label,
    column,
    sortColumn,
    sortDirection,
    onSort,
    title,
}: {
    label: string;
    column: string;
    sortColumn: string;
    sortDirection: SortDirection;
    onSort: (column: string) => void;
    title?: string;
}) {
    const active = column === sortColumn;
    return (
        <th className="px-4 py-3 cursor-pointer select-none" onClick={() => onSort(column)} title={title}>
            <span className="inline-flex items-center gap-1">
                {label}
                {active ? (
                    sortDirection === 'asc' ? (
                        <ChevronUp className="size-3.5" />
                    ) : (
                        <ChevronDown className="size-3.5" />
                    )
                ) : (
                    <ChevronsUpDown className="size-3.5 text-zinc-400" />
                )}
            </span>
        </th>
    );
}
