'use client';
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
// packages/ui/src/crud/components/EntityList.tsx
/**
 * @fileoverview Entity List Component
 * @description Table view for admin/internal CRUD operations.
 * Features: Filters section + Results section with DataTable
 *
 * **Routing:** Convention basePath = `/${collection}`. View/Edit = basePath/:id, Create = basePath/new.
 * Override basePath for nested routes; use onClick(id) to open sheet instead of navigating.
 *
 * @version 0.4.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
import { RefreshCw, Plus, Trash2, Edit, Search } from 'lucide-react';
import { useMemo, useCallback, useState } from 'react';
import { DataTable, Button, Stack, ActionButton, Section, Input, } from '@donotdev/components';
import { useTranslation } from '@donotdev/core';
import { isCrudModuleAvailable, translateFieldLabel, useCrud, useCrudList, EntityFilters, formatValue, useReferenceResolver, } from '../crudImports';
import { useNavigate } from '../../routing';
/**
 * Entity List Component - Table view for admin/internal operations
 *
 * Features:
 * - Filters section (collapsible) with actions and filter inputs
 * - Results section (collapsible) with DataTable
 * - Excel-like table display with formatted values
 * - Edit and Delete actions (admin only)
 * - Auto-routing when handlers not provided
 */
export function EntityList({ entity, basePath, onClick, hideFilters = false, pagination = 'auto', pageSize: pageSizeProp, queryOptions, exportable = true, }) {
    // Safe guard: isCrudModuleAvailable is a module-level constant (immutable after load).
    // eslint-disable-next-line react-hooks/rules-of-hooks
    if (!isCrudModuleAvailable)
        return null;
    const navigate = useNavigate();
    const base = basePath ?? `/${entity.collection}`;
    // Pre-fetch referenced collections for display resolution
    const referenceData = useReferenceResolver(entity);
    // Server-side pagination state (only used when pagination='server')
    const [currentPage, setCurrentPage] = useState(1);
    // For server-side, we need to track pageSize state (DataTable will call onPageSizeChange)
    // For client-side, we just pass pageSizeProp to DataTable and it handles its own state
    const [serverPageSize, setServerPageSize] = useState(pageSizeProp);
    const [searchQuery, setSearchQuery] = useState('');
    // useCrudList now handles client-side filter + search + sort via `processed`
    // effectiveMode tells us if auto-mode switched to server (for DataTable props)
    const { data: listData, items: rawData, processed: filteredData, loading, mutate: refreshList, effectiveMode, } = useCrudList(entity, {
        pagination,
        searchQuery,
        ...(queryOptions && { queryOptions }),
        ...((pagination === 'server' || pagination === 'auto') && {
            page: currentPage,
            pageSize: serverPageSize,
        }),
    });
    // useCrud -> handles actions (delete)
    const { delete: deleteItem } = useCrud(entity);
    const { t: tCrud } = useTranslation('crud');
    // Entity + crud namespaces so formatValue can resolve crud:price.* etc.
    const { t } = useTranslation([entity.namespace, 'crud']);
    // Refresh handler - triggers manual refetch in useList
    const handleRefresh = useCallback(async () => {
        await refreshList();
    }, [refreshList]);
    // Edit button: always navigate to basePath/:id
    const handleEdit = useCallback((id) => {
        navigate(`${base}/${id}`);
    }, [base, navigate]);
    // Row click: onClick(id) if provided, else navigate to basePath/:id
    const handleView = useCallback((id) => {
        if (onClick) {
            onClick(id);
        }
        else {
            navigate(`${base}/${id}`);
        }
    }, [base, navigate, onClick]);
    // Add New: navigate to basePath/new
    const handleCreate = useCallback(() => {
        navigate(`${base}/new`);
    }, [base, navigate]);
    // Delete handler - store handles optimistic removal automatically
    const handleDelete = useCallback(async (itemId) => {
        await deleteItem(itemId);
    }, [deleteItem]);
    // Generate columns from entity.listFields or entity.fields
    const columns = useMemo(() => {
        const fieldsToShow = entity.listFields || Object.keys(entity.fields);
        const baseColumns = fieldsToShow
            .map((fieldName) => {
            const fieldConfig = entity.fields[fieldName];
            if (!fieldConfig)
                return null;
            const label = translateFieldLabel(fieldName, fieldConfig, t);
            const fieldType = fieldConfig.type || 'text';
            const isNumeric = fieldType === 'number' || fieldType === 'range';
            const align = isNumeric ? 'end' : 'start';
            return {
                key: fieldName,
                title: label,
                dataIndex: fieldName,
                sortable: true,
                filterable: true,
                align,
                render: (value, record) => formatValue(value, fieldConfig, t, {
                    compact: true,
                    referenceData,
                }),
            };
        })
            .filter(Boolean);
        // Add actions column at the front (for mobile accessibility)
        baseColumns.unshift({
            key: '_actions',
            title: tCrud('actions.label', { defaultValue: 'Actions' }),
            dataIndex: undefined,
            sortable: false,
            width: 120,
            align: 'center',
            render: (_, record) => (_jsxs(Stack, { direction: "row", gap: "tight", align: "center", justify: "center", children: [_jsx(Button, { variant: "outline", icon: Edit, onClick: (e) => {
                            e.stopPropagation();
                            handleEdit(record.id);
                        }, "aria-label": tCrud('edit', { defaultValue: 'Edit' }) }), _jsx(ActionButton, { action: async () => {
                            await handleDelete(record.id);
                        }, confirmText: tCrud('delete.confirm', {
                            defaultValue: 'Are you sure you want to delete this item?',
                        }), confirmTitle: tCrud('delete.title', {
                            defaultValue: 'Delete Item',
                        }), loadingText: tCrud('delete.loading', {
                            defaultValue: 'Deleting...',
                        }), variant: "destructive", icon: Trash2, "aria-label": tCrud('delete', { defaultValue: 'Delete' }), children: tCrud('delete', { defaultValue: 'Delete' }) })] })),
        });
        return baseColumns;
        // Note: 't' and 'tCrud' are assumed stable across renders (i18next returns the same reference
        // unless the language changes). If i18n language switching causes stale columns, add i18n.language to deps.
    }, [entity, t, tCrud, handleEdit, handleDelete]);
    // Entity name for section title
    const entityName = t('name', { defaultValue: entity.name });
    // Result count
    const resultCount = filteredData.length;
    // Always show table structure - DataTable will show skeleton rows when loading
    return (_jsxs(_Fragment, { children: [_jsx(Section, { title: tCrud('filters.title', {
                    entity: entityName,
                    defaultValue: `Browse ${entityName} - Filters`,
                }), collapsible: true, defaultOpen: true, children: _jsxs(Stack, { children: [_jsxs(Stack, { direction: "row", gap: "tight", align: "center", className: "dndev-w-full", style: { display: 'grid', gridTemplateColumns: '1fr auto auto' }, children: [_jsx(Input, { placeholder: tCrud('search.placeholder', {
                                        defaultValue: 'Search...',
                                    }), value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), icon: Search, className: "dndev-w-full" }), _jsx(Button, { icon: RefreshCw, variant: "outline", onClick: handleRefresh, disabled: loading, display: "compact", "aria-label": tCrud('refresh', { defaultValue: 'Refresh' }) }), _jsx(Button, { icon: Plus, onClick: handleCreate, display: "compact", children: tCrud('addNew', { defaultValue: 'Add New' }) })] }), !hideFilters && (_jsx(EntityFilters, { entity: entity, data: rawData, fieldsToFilter: entity.listFields }))] }) }), _jsx(Section, { title: loading
                    ? tCrud('results.title.fetching', {
                        defaultValue: 'Fetching...',
                    })
                    : tCrud('results.title.count', {
                        count: resultCount,
                        defaultValue: resultCount === 1
                            ? 'Found 1 occurrence'
                            : `Found ${resultCount} occurrences`,
                    }), collapsible: true, defaultOpen: true, children: _jsx(DataTable, { data: filteredData, columns: columns, sortable: true, searchable: false, pagination: true, loading: loading, onRowClick: (item) => handleView(item.id), 
                    // Pagination labels (translated)
                    showingLabel: tCrud('pagination.showing', {
                        defaultValue: 'Showing {{from}} to {{to}} of {{total}} entries',
                    }), paginationPreviousLabel: tCrud('pagination.previous', {
                        defaultValue: 'Previous',
                    }), paginationNextLabel: tCrud('pagination.next', {
                        defaultValue: 'Next',
                    }), paginationItemsPerPagePlaceholder: tCrud('pagination.itemsPerPagePlaceholder', {
                        defaultValue: 'Items per page',
                    }), ...(pageSizeProp && { pageSize: pageSizeProp }), ...(effectiveMode === 'server' && {
                        currentPage,
                        pageSize: serverPageSize,
                        total: listData?.total,
                        onPageChange: setCurrentPage,
                        onPageSizeChange: setServerPageSize,
                    }), 
                    // Export functionality
                    exportable: exportable, exportFilename: `${entity.collection}-export`, exportLabel: tCrud('export', { defaultValue: 'Export' }) }) })] }));
}
