/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import * as zrUtil from 'zrender/src/core/util';
import SeriesModel from '../../model/Series';
import Tree, { TreeNode } from '../../data/Tree';
import Model from '../../model/Model';
import {wrapTreePathInfo} from '../helper/treeHelper';
import {
    SeriesOption,
    BoxLayoutOptionMixin,
    ItemStyleOption,
    LabelOption,
    RoamOptionMixin,
    CallbackDataParams,
    ColorString,
    StatesOptionMixin,
    OptionId,
    OptionName,
    DecalObject,
    SeriesLabelOption,
    DefaultEmphasisFocus,
    AriaOptionMixin,
    BlurScope
} from '../../util/types';
import GlobalModel from '../../model/Global';
import { LayoutRect } from '../../util/layout';
import SeriesData from '../../data/SeriesData';
import { normalizeToArray } from '../../util/model';
import { createTooltipMarkup } from '../../component/tooltip/tooltipMarkup';
import enableAriaDecalForTree from '../helper/enableAriaDecalForTree';

// Only support numeric value.
type TreemapSeriesDataValue = number | number[];

interface BreadcrumbItemStyleOption extends ItemStyleOption {
    // TODO: textStyle should be in breadcrumb.label
    textStyle?: LabelOption
}

interface TreemapSeriesLabelOption extends SeriesLabelOption {
    formatter?: string | ((params: CallbackDataParams) => string)
}

interface TreemapSeriesItemStyleOption<TCbParams = never> extends ItemStyleOption<TCbParams> {
    borderRadius?: number | number[]

    colorAlpha?: number
    colorSaturation?: number

    borderColorSaturation?: number

    gapWidth?: number
}

interface TreePathInfo {
    name: string
    dataIndex: number
    value: TreemapSeriesDataValue
}

interface TreemapSeriesCallbackDataParams extends CallbackDataParams {
    /**
     * @deprecated
     */
    treePathInfo?: TreePathInfo[]

    treeAncestors?: TreePathInfo[]
}

interface ExtraStateOption {
    emphasis?: {
        focus?: DefaultEmphasisFocus | 'descendant' | 'ancestor'
    }
}

export interface TreemapStateOption<TCbParams = never> {
    itemStyle?: TreemapSeriesItemStyleOption<TCbParams>
    label?: TreemapSeriesLabelOption
    upperLabel?: TreemapSeriesLabelOption
}

export interface TreemapSeriesVisualOption {
    /**
     * Which dimension will be applied with the visual properties.
     */
    visualDimension?: number | string

    /**
     * @deprecated Use colorBy instead
     */
    colorMappingBy?: 'value' | 'index' | 'id'

    visualMin?: number
    visualMax?: number

    colorAlpha?: number[] | 'none'
    colorSaturation?: number[] | 'none'
    // A color list for a level. Each node in the level will obtain a color from the color list.
    // Only support ColorString for interpolation.
    // color?: ColorString[]

    /**
     * A node will not be shown when its area size is smaller than this value (unit: px square).
     */
    visibleMin?: number
    /**
     * Children will not be shown when area size of a node is smaller than this value (unit: px square).
     */
    childrenVisibleMin?: number
}

export interface TreemapSeriesLevelOption extends TreemapSeriesVisualOption,
    TreemapStateOption, StatesOptionMixin<TreemapStateOption, ExtraStateOption> {

    color?: ColorString[] | 'none',
    decal?: DecalObject[] | 'none'
}

export interface TreemapSeriesNodeItemOption extends TreemapSeriesVisualOption,
    TreemapStateOption, StatesOptionMixin<TreemapStateOption, ExtraStateOption> {
    id?: OptionId
    name?: OptionName

    value?: TreemapSeriesDataValue

    children?: TreemapSeriesNodeItemOption[]

    color?: ColorString[] | 'none'

    decal?: DecalObject[] | 'none'
}

export interface TreemapSeriesOption
    extends SeriesOption<TreemapStateOption<TreemapSeriesCallbackDataParams>, ExtraStateOption>,
    TreemapStateOption<TreemapSeriesCallbackDataParams>,
    BoxLayoutOptionMixin,
    RoamOptionMixin,
    TreemapSeriesVisualOption {

    type?: 'treemap'

    /**
     * configuration in echarts2
     * @deprecated
     */
    size?: (number | string)[]

    /**
     * If sort in desc order.
     * Default to be desc. asc has strange effect
     */
    sort?: boolean | 'asc' | 'desc'

    /**
     * Size of clipped window when zooming. 'origin' or 'fullscreen'
     */
    clipWindow?: 'origin' | 'fullscreen'

    squareRatio?: number
    /**
     * Nodes on depth from root are regarded as leaves.
     * Count from zero (zero represents only view root).
     */
    leafDepth?: number

    drillDownIcon?: string

    /**
     * Be effective when using zoomToNode. Specify the proportion of the
     * target node area in the view area.
     */
    zoomToNodeRatio?: number
    /**
     * Leaf node click behaviour: 'zoomToNode', 'link', false.
     * If leafDepth is set and clicking a node which has children but
     * be on left depth, the behaviour would be changing root. Otherwise
     * use behaviour defined above.
     */
    nodeClick?: 'zoomToNode' | 'link' | false

    breadcrumb?: BoxLayoutOptionMixin & {
        show?: boolean
        height?: number

        emptyItemWidth?: number  // With of empty width
        itemStyle?: BreadcrumbItemStyleOption

        emphasis?: {
            disabled?: boolean
            focus?: DefaultEmphasisFocus
            blurScope?: BlurScope
            itemStyle?: BreadcrumbItemStyleOption
        }
    }

    levels?: TreemapSeriesLevelOption[]

    data?: TreemapSeriesNodeItemOption[]
}

class TreemapSeriesModel extends SeriesModel<TreemapSeriesOption> {

    static type = 'series.treemap';
    type = TreemapSeriesModel.type;

    static layoutMode = 'box' as const;

    preventUsingHoverLayer = true;

    layoutInfo: LayoutRect;

    designatedVisualItemStyle: TreemapSeriesItemStyleOption;

    private _viewRoot: TreeNode;
    private _idIndexMap: zrUtil.HashMap<number>;
    private _idIndexMapCount: number;

    static defaultOption: TreemapSeriesOption = {
        // Disable progressive rendering
        progressive: 0,
        // size: ['80%', '80%'],            // deprecated, compatible with ec2.
        left: 'center',
        top: 'middle',
        width: '80%',
        height: '80%',
        sort: true,

        clipWindow: 'origin',
        squareRatio: 0.5 * (1 + Math.sqrt(5)), // golden ratio
        leafDepth: null,

        drillDownIcon: '▶',                 // Use html character temporarily because it is complicated
                                            // to align specialized icon. ▷▶❒❐▼✚

        zoomToNodeRatio: 0.32 * 0.32,

        roam: true,
        nodeClick: 'zoomToNode',
        animation: true,
        animationDurationUpdate: 900,
        animationEasing: 'quinticInOut',
        breadcrumb: {
            show: true,
            height: 22,
            left: 'center',
            top: 'bottom',
            // right
            // bottom
            emptyItemWidth: 25,             // Width of empty node.
            itemStyle: {
                color: 'rgba(0,0,0,0.7)', // '#5793f3',
                textStyle: {
                    color: '#fff'
                }
            },
            emphasis: {
                itemStyle: {
                    color: 'rgba(0,0,0,0.9)' // '#5793f3',
                }
            }
        },
        label: {
            show: true,
            // Do not use textDistance, for ellipsis rect just the same as treemap node rect.
            distance: 0,
            padding: 5,
            position: 'inside', // Can be [5, '5%'] or position string like 'insideTopLeft', ...
            // formatter: null,
            color: '#fff',
            overflow: 'truncate'
            // align
            // verticalAlign
        },
        upperLabel: {                   // Label when node is parent.
            show: false,
            position: [0, '50%'],
            height: 20,
            // formatter: null,
            // color: '#fff',
            overflow: 'truncate',
            // align: null,
            verticalAlign: 'middle'
        },
        itemStyle: {
            color: null,            // Can be 'none' if not necessary.
            colorAlpha: null,       // Can be 'none' if not necessary.
            colorSaturation: null,  // Can be 'none' if not necessary.
            borderWidth: 0,
            gapWidth: 0,
            borderColor: '#fff',
            borderColorSaturation: null // If specified, borderColor will be ineffective, and the
                                        // border color is evaluated by color of current node and
                                        // borderColorSaturation.
        },
        emphasis: {
            upperLabel: {
                show: true,
                position: [0, '50%'],
                overflow: 'truncate',
                verticalAlign: 'middle'
            }
        },

        visualDimension: 0,                 // Can be 0, 1, 2, 3.
        visualMin: null,
        visualMax: null,

        color: [],                  // + treemapSeries.color should not be modified. Please only modified
                                    // level[n].color (if necessary).
                                    // + Specify color list of each level. level[0].color would be global
                                    // color list if not specified. (see method `setDefault`).
                                    // + But set as a empty array to forbid fetch color from global palette
                                    // when using nodeModel.get('color'), otherwise nodes on deep level
                                    // will always has color palette set and are not able to inherit color
                                    // from parent node.
                                    // + TreemapSeries.color can not be set as 'none', otherwise effect
                                    // legend color fetching (see seriesColor.js).
        colorAlpha: null,           // Array. Specify color alpha range of each level, like [0.2, 0.8]
        colorSaturation: null,      // Array. Specify color saturation of each level, like [0.2, 0.5]
        colorMappingBy: 'index',    // 'value' or 'index' or 'id'.
        visibleMin: 10,             // If area less than this threshold (unit: pixel^2), node will not
                                    // be rendered. Only works when sort is 'asc' or 'desc'.
        childrenVisibleMin: null,   // If area of a node less than this threshold (unit: pixel^2),
                                    // grandchildren will not show.
                                    // Why grandchildren? If not grandchildren but children,
                                    // some siblings show children and some not,
                                    // the appearance may be mess and not consistent,
        levels: []                  // Each item: {
                                    //     visibleMin, itemStyle, visualDimension, label
                                    // }
    };

    /**
     * @override
     */
    getInitialData(option: TreemapSeriesOption, ecModel: GlobalModel) {
        // Create a virtual root.
        const root: TreemapSeriesNodeItemOption = {
            name: option.name,
            children: option.data
        };

        completeTreeValue(root);

        let levels = option.levels || [];

        // Used in "visual priority" in `treemapVisual.js`.
        // This way is a little tricky, must satisfy the precondition:
        //   1. There is no `treeNode.getModel('itemStyle.xxx')` used.
        //   2. The `Model.prototype.getModel()` will not use any clone-like way.
        const designatedVisualItemStyle = this.designatedVisualItemStyle = {};
        const designatedVisualModel = new Model({itemStyle: designatedVisualItemStyle}, this, ecModel);

        levels = option.levels = setDefault(levels, ecModel);
        const levelModels = zrUtil.map(levels || [], function (levelDefine) {
            return new Model(levelDefine, designatedVisualModel, ecModel);
        }, this);

        // Make sure always a new tree is created when setOption,
        // in TreemapView, we check whether oldTree === newTree
        // to choose mappings approach among old shapes and new shapes.
        const tree = Tree.createTree(root, this, beforeLink);

        function beforeLink(nodeData: SeriesData) {
            nodeData.wrapMethod('getItemModel', function (model, idx) {
                const node = tree.getNodeByDataIndex(idx);
                const levelModel = node ? levelModels[node.depth] : null;
                // If no levelModel, we also need `designatedVisualModel`.
                model.parentModel = levelModel || designatedVisualModel;
                return model;
            });
        }

        return tree.data;
    }

    optionUpdated() {
        this.resetViewRoot();
    }

    /**
     * @override
     * @param {number} dataIndex
     * @param {boolean} [mutipleSeries=false]
     */
    formatTooltip(
        dataIndex: number,
        multipleSeries: boolean,
        dataType: string
    ) {
        const data = this.getData();
        const value = this.getRawValue(dataIndex) as TreemapSeriesDataValue;
        const name = data.getName(dataIndex);

        return createTooltipMarkup('nameValue', { name: name, value: value });
    }

    /**
     * Add tree path to tooltip param
     *
     * @override
     * @param {number} dataIndex
     * @return {Object}
     */
    getDataParams(dataIndex: number) {
        const params = super.getDataParams.apply(this, arguments as any) as TreemapSeriesCallbackDataParams;

        const node = this.getData().tree.getNodeByDataIndex(dataIndex);
        params.treeAncestors = wrapTreePathInfo(node, this);
        // compatitable the previous code.
        params.treePathInfo = params.treeAncestors;

        return params;
    }

    /**
     * @public
     * @param {Object} layoutInfo {
     *                                x: containerGroup x
     *                                y: containerGroup y
     *                                width: containerGroup width
     *                                height: containerGroup height
     *                            }
     */
    setLayoutInfo(layoutInfo: LayoutRect) {
        /**
         * @readOnly
         * @type {Object}
         */
        this.layoutInfo = this.layoutInfo || {} as LayoutRect;
        zrUtil.extend(this.layoutInfo, layoutInfo);
    }

    /**
     * @param  {string} id
     * @return {number} index
     */
    mapIdToIndex(id: string): number {
        // A feature is implemented:
        // index is monotone increasing with the sequence of
        // input id at the first time.
        // This feature can make sure that each data item and its
        // mapped color have the same index between data list and
        // color list at the beginning, which is useful for user
        // to adjust data-color mapping.

        /**
         * @private
         * @type {Object}
         */
        let idIndexMap = this._idIndexMap;

        if (!idIndexMap) {
            idIndexMap = this._idIndexMap = zrUtil.createHashMap();
            /**
             * @private
             * @type {number}
             */
            this._idIndexMapCount = 0;
        }

        let index = idIndexMap.get(id);
        if (index == null) {
            idIndexMap.set(id, index = this._idIndexMapCount++);
        }

        return index;
    }

    getViewRoot() {
        return this._viewRoot;
    }

    resetViewRoot(viewRoot?: TreeNode) {
        viewRoot
            ? (this._viewRoot = viewRoot)
            : (viewRoot = this._viewRoot);

        const root = this.getRawData().tree.root;

        if (!viewRoot
            || (viewRoot !== root && !root.contains(viewRoot))
        ) {
            this._viewRoot = root;
        }
    }

    enableAriaDecal() {
        enableAriaDecalForTree(this);
    }
}

/**
 * @param {Object} dataNode
 */
function completeTreeValue(dataNode: TreemapSeriesNodeItemOption) {
    // Postorder travel tree.
    // If value of none-leaf node is not set,
    // calculate it by suming up the value of all children.
    let sum = 0;

    zrUtil.each(dataNode.children, function (child) {

        completeTreeValue(child);

        let childValue = child.value;
        zrUtil.isArray(childValue) && (childValue = childValue[0]);

        sum += childValue;
    });

    let thisValue = dataNode.value;
    if (zrUtil.isArray(thisValue)) {
        thisValue = thisValue[0];
    }

    if (thisValue == null || isNaN(thisValue)) {
        thisValue = sum;
    }
    // Value should not less than 0.
    if (thisValue < 0) {
        thisValue = 0;
    }

    zrUtil.isArray(dataNode.value)
        ? (dataNode.value[0] = thisValue)
        : (dataNode.value = thisValue);
}

/**
 * set default to level configuration
 */
function setDefault(levels: TreemapSeriesLevelOption[], ecModel: GlobalModel) {
    const globalColorList = normalizeToArray(ecModel.get('color')) as ColorString[];
    const globalDecalList = normalizeToArray(
        (ecModel as Model<AriaOptionMixin>).get(['aria', 'decal', 'decals'])
    ) as DecalObject[];

    if (!globalColorList) {
        return;
    }

    levels = levels || [];
    let hasColorDefine;
    let hasDecalDefine;
    zrUtil.each(levels, function (levelDefine) {
        const model = new Model(levelDefine);
        const modelColor = model.get('color');
        const modelDecal = model.get('decal');

        if (model.get(['itemStyle', 'color'])
            || (modelColor && modelColor !== 'none')
        ) {
            hasColorDefine = true;
        }
        if (model.get(['itemStyle', 'decal'])
            || (modelDecal && modelDecal !== 'none')
        ) {
            hasDecalDefine = true;
        }
    });

    const level0 = levels[0] || (levels[0] = {});
    if (!hasColorDefine) {
        level0.color = globalColorList.slice();
    }
    if (!hasDecalDefine && globalDecalList) {
        level0.decal = globalDecalList.slice();
    }

    return levels;
}

export default TreemapSeriesModel;
