/*
* 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 { enableHoverEmphasis, 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/basicTrasition';

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;

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

    _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') {
                    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 (typeof rotateType === 'number') {
                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;
