/*!
 * Copyright (c) Microsoft. All rights reserved.
 * Licensed under the MIT license. See LICENSE file in the project.
 */ import { DataType } from '@datashaper/schema';
import { useMemo } from 'react';
import { createRenderColumnHeader, createRenderCommandBarColumnHeader, createRenderDefaultColumnHeader, createRenderFeaturesCell, createRenderHistogramColumnHeader, createRenderSmartCell, createRenderStatsColumnHeader } from '../renderers/index.js';
import { useCellClickhandler, useCellDropdownSelectHandler, useColumnNamesList, useColumnStyles, useIncrementingColumnColorScale } from './index.js';
import { useCountMinWidth } from './useCountMinWidth.js';
/**
 * Overlays a number of special features onto the IColumn objects for a table.
 * This includes overridden renderers to support our sorting, selection, and data visualization.
 * @param table -
 * @param columns -
 * @param options -
 * @returns
 */ export function useColumns(table, metadata, columns, handleColumnHeaderClick, options = {}, virtualColumns) {
    const { features ={} , sortColumn , sortDirection , selectedColumn , onColumnClick , onCellDropdownSelect , isClickable =false , isDefaultHeaderClickable =false , showColumnBorders =false , compact =false , resizable =true ,  } = options;
    const handleCellClick = useCellClickhandler(isClickable, onColumnClick);
    const handleCellDropdownSelect = useCellDropdownSelectHandler(isClickable, onCellDropdownSelect);
    const colorScale = useIncrementingColumnColorScale(metadata);
    const styles = useColumnStyles(isClickable, showColumnBorders);
    const names = useColumnNamesList(table, columns);
    //get column width based on min value or on commandBar item passed
    const columnMinWidth = useCountMinWidth(features.commandBar);
    return useMemo(()=>{
        const columnMap = reduce([
            ...columns || [],
            ...virtualColumns || []
        ]);
        const virtualNames = virtualColumns?.map((c)=>c.key) || [];
        return [
            ...names,
            ...virtualNames
        ].map((name)=>{
            const column = columnMap[name] || {
                key: name,
                name,
                minWidth: columnMinWidth,
                fieldName: name
            };
            // HACK: if we let an iconName through, the rendering messes with our layout.
            // In order to control this we'll pass the original props to the generators,
            // but omit from what gets sent to the top-level table.
            // As far as I can tell there's no other way to force the table to let us control this icon rendering
            // without completely recreating the details header render
            const { iconName , ...defaults } = column;
            const meta = metadata?.columns[name] || {
                name
            };
            const color = meta && meta.type === DataType.Number ? colorScale() : undefined;
            const onRender = features.smartCells && meta ? createRenderSmartCell(meta, color, handleCellClick, handleCellDropdownSelect) : createRenderFeaturesCell(features, meta, color, handleCellClick, handleCellDropdownSelect);
            const headerRenderers = [
                createRenderDefaultColumnHeader(column, isDefaultHeaderClickable, handleColumnHeaderClick), 
            ];
            if (features.commandBar) {
                headerRenderers.push(createRenderCommandBarColumnHeader(features.commandBar));
            }
            if ((features.smartHeaders || features.statsColumnHeaders) && meta) {
                headerRenderers.push(createRenderStatsColumnHeader(meta, features.onStatsColumnHeaderClick, features.statsColumnTypes));
            }
            if ((features.smartHeaders || features.histogramColumnHeaders) && meta) {
                headerRenderers.push(createRenderHistogramColumnHeader(meta, color, features.onHistogramColumnHeaderClick));
            }
            return {
                onRender,
                onRenderHeader: createRenderColumnHeader(headerRenderers),
                onColumnClick,
                isSorted: !!sortDirection && column.fieldName === sortColumn ? true : false,
                isSortedDescending: sortDirection === 'desc',
                styles,
                ...defaults,
                data: {
                    selected: column.key === selectedColumn,
                    compact,
                    ...column.data
                },
                isResizable: resizable
            };
        });
    }, [
        columns,
        names,
        features,
        sortColumn,
        sortDirection,
        selectedColumn,
        onColumnClick,
        handleCellClick,
        styles,
        compact,
        resizable,
        metadata,
        colorScale,
        handleCellDropdownSelect,
        isDefaultHeaderClickable,
        handleColumnHeaderClick,
        columnMinWidth,
        virtualColumns, 
    ]);
}
function reduce(columns) {
    return columns.reduce((acc, cur)=>{
        acc[cur.key] = cur;
        return acc;
    }, {});
}
