import Handsontable, { GridSettings } from '@sc/handsontable';

declare namespace ContextMenu {
    interface IContextMenuComponent {
        // 隐藏
        Hide: () => void;
    }

    // 菜单项的每一个 item
    interface IMenuItem {
        text: (() => string) | string;
        icon?: string;
        hidden?: (() => boolean) | boolean;
        disable?: (() => Promise<boolean> | boolean) | boolean;
        callback?: (inputVal?: number | string) => void;
        submenu?: IMenuItem[][];
    }

    // 菜单项分组
    type MenuGroup = IMenuItem[];
}

declare namespace ResizableLayout {
    interface IDataParam {
        index: number;
        instance: any;
        minSize: number;
    }

    interface IMoveParam {
        index: number; // 当前layoutItem是父组件的第几个子组件
        distance: number; // 鼠标移动的距离，负数代表左移，正数代表右移
        moveId: symbol; // move事件的唯一标志
    }

    interface IResizableLayoutComponent {
        Refresh: () => void;
    }
}


type Renderer = (
    instance: Handsontable,
    TD: HTMLElement,
    row: number,
    col: number,
    prop: string | number,
    value: any,
    cellProperties: GridSettings
) => HTMLElement;

declare namespace Hot {
    interface IHandsontableComponent {
        // 重新渲染(如容器宽高发生改变)，供外界调用
        Render: () => void;
        // 更新 Settings，供外界调用（如增加或减少列）
        Update: (settings: any) => void;
        // 重新加载数据(如引用的数据发生改变)，供外界调用
        Load: (data?: any) => void;
        // 获取 instance，供外界调用
        GetInstance: () => Handsontable;
    }

    interface ICoords {
        startRow: number;
        startCol: number;
        endRow: number;
        endCol: number;
    }

    interface IColumnMeta {
        title: string;
        data: string;
        renderer?: | string | Renderer | ((
            instance: Handsontable,
            td: HTMLElement,
            row: number,
            col: number,
            prop: string | number,
            value: any,
            cellProperties: IColumnMeta
        ) => void);
        editor?: string;
        readOnly?: boolean;
        showButton?: boolean; // 默认readOnly为true时，右上角的按钮也不显示，对于readOnly为true,又要显示按钮的情况，这里也要设置为true
        width: number;
        // 小数位数，如果存在此项配置，搭配'wc.numeric' cellType后，会将数值string转换为number，并进行四舍五入
        decimal?: number | (() => number);
        // 允许输入空值,转换成null
        numberAllowEmpty?: boolean;
        type?: string;
        checkedTemplate?: any;
        uncheckedTemplate?: any;
        numericFormat?: { pattern?: string; zeroFormat?: string };
        source?: string[] | any[];
        className?: string;
        required?: boolean;
        isTemporary?: boolean;
    }

    type MouseKey = 'left' | 'middle' | 'right';
    type ClickPosition = 'outside' | 'barren' | 'content';

    interface IGroupHeaderCell {
        label: string;
        colspan?: number;
        rowspan?: number;
    }

    type GroupHeaderCell = IGroupHeaderCell | string;

    interface ISettings extends GridSettings {
        columnsMeta?: IColumnMeta[];
        /**
         * 获取鼠标点击的区域
         * @param isOutside 是否在表格外面
         * @param isBarren 是否在表格内部的空白区域
         * @param isContent 是否在表格内容的内同区域
         */
        onClickPosition?: (whichKey: MouseKey, clickPosition: ClickPosition) => void;
        // 表头分组
        groupingHeaders?: GroupHeaderCell[][];
        // contextMenu?: { callback: (...args: any) => void; items: any };
    }

    interface IHandsontableProps {
        data: any[];
        settings: ISettings;
        tree: boolean;
        readOnly: boolean;
        border: string;
        loading: boolean;
    }

    interface IRenderer {
        (
            instance: Handsontable,
            row: number,
            col: number,
            prop: string | number,
            value: any,
            cellProperties: GridSettings
        ): HTMLElement;
    }

    type CellChangeParam = [/* row */ number, /* prop */ string, /* oldValue */ any, /* newValue */ any];

    type RendererItem = [string, ComponentObjectPropsOptions | IRenderer];
}