import _ from 'lodash';
import { PlusCircle } from 'lucide-react';

import type {
    AllFieldsEnum,
    StructureType,
} from '@/api/types';
import { MenuData } from '@/components/AnyDropdownMenu';

import TableItem from './components/TableItem/TableItem';

export type ColumnsType = {
    key: string;
    dataIndex: string;
    sorter: boolean;
    width: number;
    showSorterTooltip: boolean;
    render: (value: any, record: any) => React.ReactNode;
    title: () => React.ReactNode;
    children?: ColumnsType[];
}

export const getColumnsInternal = (sorter: boolean, structure: StructureType, keyPrefix: string = '', titlePrefix: string[] = []): ColumnsType[] => {
    let columns: ColumnsType[] = [];

    const splitKey = ' → ';

    const origin = structure;


    if (!structure) return columns;




    const items = _(structure.items ?? {})
        .toPairs() // [['key1', {...}], ...]
        .orderBy(([_, value]) => value.tablePriority || 0, 'desc') // сортировка по tablePriority по убыванию
        .fromPairs() // обратно в объект
        .value();



    _.map(items, (item) => {
        if (item.inAdmin && item.inTable && !item.hide) {
            if (item.type == "structure" || item.type == "range") {


                let children = getColumnsInternal(false, item, `${keyPrefix}${item.key}.`, [...titlePrefix, item.title ?? item.key ?? ""]);

                children.map((child) => {
                    columns.push({
                        ...child,

                    })
                });
                return;


            }

            columns.push({
                key: keyPrefix + item.key,
                dataIndex: keyPrefix + item.key,
                sorter: true,
                width: item.columnsWidth ?? 150,
                showSorterTooltip: false,
                render: (valueItem: any, record: any) => {
                    let value = _.get(record, keyPrefix + item.key);

                    return <TableItem
                        structure={item ?? null}
                        value={value}
                    />

                },
                title: () => {



                    let length = (item.title ?? item.key ?? "").length;
                    let title = '';

                    if (length > 2) {
                        title = (item.title ?? item.key ?? "");
                    } else {
                        title = [...titlePrefix, item.title].join(splitKey);
                    }

                    return <div className="text-xs truncate ...">{title}</div>

                },
            });
        } else {
            //     console.log('Skipping column', item.key, 'because inAdmin:', item.inAdmin, 'inTable:', item.inTable, 'hide:', item.hide);
        }
    });



    return columns;
};







type MenuByFilterStructureParams = {
    onSelect?: (structure: StructureType) => void;
    structure: StructureType | null;
    selectBefore: string[];
    rootStructure?: StructureType;
}

const transformStructure = (structure: StructureType, path: string[]): StructureType => {
    if (path.length === 0) {
        return structure;
    }

    let firstPath = path[0];

    let includeStructure = { ...structure.items?.[firstPath] };

    if (!includeStructure) {
        return structure;
    }

    includeStructure.title = `${structure.title} → ${includeStructure.title}`;

    if (structure.key) {
        includeStructure.key = `${structure.key}.${includeStructure.key}`;
    } else {
        includeStructure.key = includeStructure.key;
    }

    includeStructure.col = 24;

    return transformStructure(includeStructure, path.slice(1));
}

export const flatFilterStructure = ({ structure, selectBefore, rootStructure }: { structure: StructureType, selectBefore?: string[], rootStructure?: StructureType }): StructureType[] => {
    if (!structure) return [];

    if (!rootStructure) {
        rootStructure = structure;
    }


    if (!selectBefore) {
        selectBefore = [];
    }
    let result: StructureType[] = [];

    _.map(structure.items, (item, key) => {
        if (item.hide) return;
        if (!item.inAdmin) return;
        if (!item.editable) return;

        if (item.items) {

            result.push(...flatFilterStructure({ structure: item, selectBefore: [...selectBefore, item.key!], rootStructure: rootStructure }));


        } else {

            result.push(transformStructure(rootStructure!, [...selectBefore, item.key!]));

        }
    })

    return result;
}

export const menuByFilterStructure = ({ onSelect, structure, selectBefore, rootStructure }: MenuByFilterStructureParams) => {
    if (!structure) return [];

    if (!rootStructure) {
        rootStructure = structure;
    }

    let menu: MenuData[] = [];

    _.map(structure.items, (item, key) => {
        if (item.hide) return;
        if (!item.inAdmin) return;
        if (!item.editable) return;

        if (item.items) {
            menu.push({
                label: item.title ?? item.key,
                htmlIcon: <PlusCircle />,
                submenu: menuByFilterStructure({
                    onSelect: onSelect,
                    structure: item,
                    selectBefore: [...selectBefore, item.key!],
                    rootStructure: rootStructure,
                }),
            })
        } else {
            menu.push({
                label: item.title ?? item.key,
                htmlIcon: <PlusCircle />,
                click: () => {
                    let _selectBefore = [...selectBefore, item.key!];
                    console.log('_selectBefore', _selectBefore);
                    let newStructure = transformStructure(rootStructure!, _selectBefore);
                    console.log('newStructure', newStructure);
                    onSelect?.(newStructure);
                }
            })
        }
    })

    return menu;
}



export const prepareFilterValues = (values: any) => {



    let result: any = {};

    _.forEach(values, (value, key) => {
        let keys = key.split('.');

        _.set(result, keys, value);

    });


    return result;


}


export const structureHaveType = (type: AllFieldsEnum, structure: StructureType | null): boolean => {
    if (!structure) return false;

    let have = false;

    _.map(structure.items, (field, key) => {
        if (field.type === type) {
            have = true;
        }
    });

    return have;
}