/*
* 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 {wrapTreePathInfo} from '../helper/treeHelper';
import {
    SeriesOption,
    CircleLayoutOptionMixin,
    SeriesLabelOption,
    ItemStyleOption,
    OptionDataValue,
    CallbackDataParams,
    StatesOptionMixin,
    OptionDataItemObject,
    DefaultEmphasisFocus,
    SunburstColorByMixin
} from '../../util/types';
import GlobalModel from '../../model/Global';
import SeriesData from '../../data/SeriesData';
import Model from '../../model/Model';
import enableAriaDecalForTree from '../helper/enableAriaDecalForTree';

interface SunburstItemStyleOption<TCbParams = never> extends ItemStyleOption<TCbParams> {
    // can be 10
    // which means that both innerCornerRadius and outerCornerRadius are 10
    // can also be an array [20, 10]
    // which means that innerCornerRadius is 20
    // and outerCornerRadius is 10
    // can also be a string or string array, such as ['20%', '50%']
    // which means that innerCornerRadius is 20% of the innerRadius
    // and outerCornerRadius is half of outerRadius.
    borderRadius?: (number | string)[] | number | string
}

interface SunburstLabelOption extends Omit<SeriesLabelOption, 'rotate' | 'position'> {
    rotate?: 'radial' | 'tangential' | number
    minAngle?: number
    silent?: boolean
    position?: SeriesLabelOption['position'] | 'outside'
}

interface SunburstDataParams extends CallbackDataParams {
    treePathInfo: {
        name: string,
        dataIndex: number
        value: SunburstSeriesNodeItemOption['value']
    }[]
}

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

export interface SunburstStateOption<TCbParams = never> {
    itemStyle?: SunburstItemStyleOption<TCbParams>
    label?: SunburstLabelOption
}

export interface SunburstSeriesNodeItemOption extends
    SunburstStateOption<CallbackDataParams>,
    StatesOptionMixin<SunburstStateOption<CallbackDataParams>, SunburstStatesMixin>,
    OptionDataItemObject<OptionDataValue>
{
    nodeClick?: 'rootToNode' | 'link' | false
    // Available when nodeClick is link
    link?: string
    target?: string

    children?: SunburstSeriesNodeItemOption[]

    collapsed?: boolean

    cursor?: string
}
export interface SunburstSeriesLevelOption
    extends SunburstStateOption, StatesOptionMixin<SunburstStateOption, SunburstStatesMixin> {

    radius?: (number | string)[]
    /**
     * @deprecated use radius instead
     */
    r?: number | string
    /**
     * @deprecated use radius instead
     */
    r0?: number | string

    highlight?: {
        itemStyle?: SunburstItemStyleOption
        label?: SunburstLabelOption
    }
}

interface SortParam {
    dataIndex: number
    depth: number
    height: number
    getValue(): number
}
export interface SunburstSeriesOption extends
    SeriesOption<SunburstStateOption, SunburstStatesMixin>, SunburstStateOption,
    SunburstColorByMixin,
    CircleLayoutOptionMixin {

    type?: 'sunburst'

    clockwise?: boolean
    startAngle?: number
    minAngle?: number
    /**
     * If still show when all data zero.
     */
    stillShowZeroSum?: boolean
    /**
     * Policy of highlighting pieces when hover on one
     * Valid values: 'none' (for not downplay others), 'descendant',
     * 'ancestor', 'self'
     */
    // highlightPolicy?: 'descendant' | 'ancestor' | 'self'

    nodeClick?: 'rootToNode' | 'link' | false

    renderLabelForZeroData?: boolean

    levels?: SunburstSeriesLevelOption[]

    animationType?: 'expansion' | 'scale'

    sort?: 'desc' | 'asc' | ((a: SortParam, b: SortParam) => number)
}

interface SunburstSeriesModel {
    getFormattedLabel(
        dataIndex: number,
        state?: 'emphasis' | 'normal' | 'highlight' | 'blur' | 'select'
    ): string
}
class SunburstSeriesModel extends SeriesModel<SunburstSeriesOption> {

    static readonly type = 'series.sunburst';
    readonly type = SunburstSeriesModel.type;

    ignoreStyleOnData = true;

    private _viewRoot: TreeNode;
    private _levelModels: Model<SunburstSeriesLevelOption>[];

    getInitialData(option: SunburstSeriesOption, ecModel: GlobalModel) {
        // Create a virtual root.
        const root = { name: option.name, children: option.data } as SunburstSeriesNodeItemOption;

        completeTreeValue(root);

        const levelModels = this._levelModels =
            zrUtil.map(option.levels || [], function (levelDefine) {
                return new Model(levelDefine, this, 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 = levelModels[node.depth];
                levelModel && (model.parentModel = levelModel);
                return model;
            });
        }
        return tree.data;
    }

    optionUpdated() {
        this.resetViewRoot();
    }

    /*
     * @override
     */
    getDataParams(dataIndex: number) {
        const params = super.getDataParams.apply(this, arguments as any) as SunburstDataParams;

        const node = this.getData().tree.getNodeByDataIndex(dataIndex);
        params.treePathInfo = wrapTreePathInfo<SunburstSeriesNodeItemOption['value']>(node, this);

        return params;
    }

    getLevelModel(node: TreeNode) {
        return this._levelModels && this._levelModels[node.depth];
    }

    static defaultOption: SunburstSeriesOption = {
        // zlevel: 0,
        z: 2,

        // 默认全局居中
        center: ['50%', '50%'],
        radius: [0, '75%'],
        // 默认顺时针
        clockwise: true,
        startAngle: 90,
        // 最小角度改为0
        minAngle: 0,

        // If still show when all data zero.
        stillShowZeroSum: true,

        // 'rootToNode', 'link', or false
        nodeClick: 'rootToNode',

        renderLabelForZeroData: false,

        label: {
            // could be: 'radial', 'tangential', or 'none'
            rotate: 'radial',
            show: true,
            opacity: 1,
            // 'left' is for inner side of inside, and 'right' is for outer
            // side for inside
            align: 'center',
            position: 'inside',
            distance: 5,
            silent: true
        },
        itemStyle: {
            borderWidth: 1,
            borderColor: 'white',
            borderType: 'solid',
            shadowBlur: 0,
            shadowColor: 'rgba(0, 0, 0, 0.2)',
            shadowOffsetX: 0,
            shadowOffsetY: 0,
            opacity: 1
        },

        emphasis: {
            focus: 'descendant'
        },

        blur: {
            itemStyle: {
                opacity: 0.2
            },
            label: {
                opacity: 0.1
            }
        },

        // Animation type can be expansion, scale.
        animationType: 'expansion',
        animationDuration: 1000,
        animationDurationUpdate: 500,

        data: [],

        /**
         * Sort order.
         *
         * Valid values: 'desc', 'asc', null, or callback function.
         * 'desc' and 'asc' for descend and ascendant order;
         * null for not sorting;
         * example of callback function:
         * function(nodeA, nodeB) {
         *     return nodeA.getValue() - nodeB.getValue();
         * }
         */
        sort: 'desc'
    };

    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);
    }
}



function completeTreeValue(dataNode: SunburstSeriesNodeItemOption) {
    // 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;
        // TODO First value of array must be a number
        zrUtil.isArray(childValue) && (childValue = childValue[0]);
        sum += childValue as number;
    });

    let thisValue = dataNode.value as number;
    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);
}


export default SunburstSeriesModel;
