/*
* 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 * as graphic from '../../util/graphic';
import { toggleHoverEmphasis, SPECIAL_STATES, DISPLAY_STATES } from '../../util/states';
import {createTextStyle} from '../../label/labelStyle';
import { TreeNode } from '../../data/Tree';
import SunburstSeriesModel, { SunburstSeriesNodeItemOption, SunburstSeriesOption } from './SunburstSeries';
import GlobalModel from '../../model/Global';
import { PathStyleProps } from 'zrender/src/graphic/Path';
import { ColorString } from '../../util/types';
import Model from '../../model/Model';
import { getECData } from '../../util/innerStore';
import { getSectorCornerRadius } from '../helper/pieHelper';
import {createOrUpdatePatternFromDecal} from '../../util/decal';
import ExtensionAPI from '../../core/ExtensionAPI';
import { saveOldStyle } from '../../animation/basicTransition';

const DEFAULT_SECTOR_Z = 2;
const DEFAULT_TEXT_Z = 4;
interface DrawTreeNode extends TreeNode {
    piece: SunburstPiece
}
/**
 * Sunburstce of Sunburst including Sector, Label, LabelLine
 */
class SunburstPiece extends graphic.Sector {

    node: TreeNode;

    private _seriesModel: SunburstSeriesModel;
    private _ecModel: GlobalModel;

    constructor(node: TreeNode, seriesModel: SunburstSeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
        super();

        this.z2 = DEFAULT_SECTOR_Z;
        this.textConfig = {
            inside: true
        };

        getECData(this).seriesIndex = seriesModel.seriesIndex;

        const text = new graphic.Text({
            z2: DEFAULT_TEXT_Z,
            silent: node.getModel<SunburstSeriesNodeItemOption>().get(['label', 'silent'])
        });
        this.setTextContent(text);

        this.updateData(true, node, seriesModel, ecModel, api);
    }

    updateData(
        firstCreate: boolean,
        node: TreeNode,
        // state: 'emphasis' | 'normal' | 'highlight' | 'downplay',
        seriesModel: SunburstSeriesModel,
        ecModel: GlobalModel,
        api: ExtensionAPI
    ) {
        this.node = node;
        (node as DrawTreeNode).piece = this;

        seriesModel = seriesModel || this._seriesModel;
        ecModel = ecModel || this._ecModel;

        const sector = this;
        getECData(sector).dataIndex = node.dataIndex;

        const itemModel = node.getModel<SunburstSeriesNodeItemOption>();
        const emphasisModel = itemModel.getModel('emphasis');
        const layout = node.getLayout();

        const sectorShape = zrUtil.extend({}, layout);
        sectorShape.label = null;

        const normalStyle = node.getVisual('style') as PathStyleProps;
        normalStyle.lineJoin = 'bevel';

        const decal = node.getVisual('decal');
        if (decal) {
            normalStyle.decal = createOrUpdatePatternFromDecal(decal, api);
        }

        const cornerRadius = getSectorCornerRadius(itemModel.getModel('itemStyle'), sectorShape, true);
        zrUtil.extend(sectorShape, cornerRadius);

        zrUtil.each(SPECIAL_STATES, function (stateName) {
            const state = sector.ensureState(stateName);
            const itemStyleModel = itemModel.getModel([stateName, 'itemStyle']);
            state.style = itemStyleModel.getItemStyle();
            // border radius
            const cornerRadius = getSectorCornerRadius(itemStyleModel, sectorShape);
            if (cornerRadius) {
                state.shape = cornerRadius;
            }
        });

        if (firstCreate) {
            sector.setShape(sectorShape);
            sector.shape.r = layout.r0;
            graphic.updateProps(
                sector,
                {
                    shape: {
                        r: layout.r
                    }
                },
                seriesModel,
                node.dataIndex
            );
        }
        else {
            // Disable animation for gradient since no interpolation method
            // is supported for gradient
            graphic.updateProps(sector, {
                shape: sectorShape
            }, seriesModel);

            saveOldStyle(sector);
        }

        sector.useStyle(normalStyle);

        this._updateLabel(seriesModel);

        const cursorStyle = itemModel.getShallow('cursor');
        cursorStyle && sector.attr('cursor', cursorStyle);

        this._seriesModel = seriesModel || this._seriesModel;
        this._ecModel = ecModel || this._ecModel;

        const focus = emphasisModel.get('focus');

        const focusOrIndices =
            focus === 'ancestor' ? node.getAncestorsIndices()
            : focus === 'descendant' ? node.getDescendantIndices()
            : focus;

        toggleHoverEmphasis(this, focusOrIndices, emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
    }

    _updateLabel(
        seriesModel: SunburstSeriesModel
    ) {
        const itemModel = this.node.getModel<SunburstSeriesNodeItemOption>();
        const normalLabelModel = itemModel.getModel('label');

        const layout = this.node.getLayout();
        const angle = layout.endAngle - layout.startAngle;

        const midAngle = (layout.startAngle + layout.endAngle) / 2;
        const dx = Math.cos(midAngle);
        const dy = Math.sin(midAngle);

        const sector = this;
        const label = sector.getTextContent();
        const dataIndex = this.node.dataIndex;
        const labelMinAngle = normalLabelModel.get('minAngle') / 180 * Math.PI;
        const isNormalShown = normalLabelModel.get('show')
            && !(labelMinAngle != null && Math.abs(angle) < labelMinAngle);
        label.ignore = !isNormalShown;

        // TODO use setLabelStyle
        zrUtil.each(DISPLAY_STATES, (stateName) => {

            const labelStateModel = stateName === 'normal' ? itemModel.getModel('label')
                : itemModel.getModel([stateName, 'label']);
            const isNormal = stateName === 'normal';

            const state = isNormal ? label : label.ensureState(stateName);
            let text = seriesModel.getFormattedLabel(dataIndex, stateName);
            if (isNormal) {
                text = text || this.node.name;
            }

            state.style = createTextStyle(labelStateModel, {}, null, stateName !== 'normal', true);
            if (text) {
                state.style.text = text;
            }
            // Not displaying text when angle is too small
            const isShown = labelStateModel.get('show');
            if (isShown != null && !isNormal) {
                state.ignore = !isShown;
            }

            const labelPosition = getLabelAttr(labelStateModel, 'position');

            const sectorState = isNormal ? sector : sector.states[stateName];
            const labelColor = sectorState.style.fill as ColorString;
            sectorState.textConfig = {
                outsideFill: labelStateModel.get('color') === 'inherit' ? labelColor : null,
                inside: labelPosition !== 'outside'
            };

            let r;
            const labelPadding = getLabelAttr(labelStateModel, 'distance') || 0;
            let textAlign = getLabelAttr(labelStateModel, 'align');
            if (labelPosition === 'outside') {
                r = layout.r + labelPadding;
                textAlign = midAngle > Math.PI / 2 ? 'right' : 'left';
            }
            else {
                if (!textAlign || textAlign === 'center') {
                    // Put label in the center if it's a circle
                    if (angle === 2 * Math.PI && layout.r0 === 0) {
                        r = 0;
                    }
                    else {
                        r = (layout.r + layout.r0) / 2;
                    }
                    textAlign = 'center';
                }
                else if (textAlign === 'left') {
                    r = layout.r0 + labelPadding;
                    if (midAngle > Math.PI / 2) {
                        textAlign = 'right';
                    }
                }
                else if (textAlign === 'right') {
                    r = layout.r - labelPadding;
                    if (midAngle > Math.PI / 2) {
                        textAlign = 'left';
                    }
                }
            }

            state.style.align = textAlign;
            state.style.verticalAlign = getLabelAttr(labelStateModel, 'verticalAlign') || 'middle';

            state.x = r * dx + layout.cx;
            state.y = r * dy + layout.cy;

            const rotateType = getLabelAttr(labelStateModel, 'rotate');
            let rotate = 0;
            if (rotateType === 'radial') {
                rotate = -midAngle;
                if (rotate < -Math.PI / 2) {
                    rotate += Math.PI;
                }
            }
            else if (rotateType === 'tangential') {
                rotate = Math.PI / 2 - midAngle;
                if (rotate > Math.PI / 2) {
                    rotate -= Math.PI;
                }
                else if (rotate < -Math.PI / 2) {
                    rotate += Math.PI;
                }
            }
            else if (zrUtil.isNumber(rotateType)) {
                rotate = rotateType * Math.PI / 180;
            }

            state.rotation = rotate;
        });


        type LabelOpt = SunburstSeriesOption['label'];
        function getLabelAttr<T extends keyof LabelOpt>(model: Model<LabelOpt>, name: T): LabelOpt[T] {
            const stateAttr = model.get(name);
            if (stateAttr == null) {
                return normalLabelModel.get(name) as LabelOpt[T];
            }
            return stateAttr;
        }

        label.dirtyStyle();
    }
}


export default SunburstPiece;
