/*
* 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.
*/

// FIXME emphasis label position is not same with normal label position
import {parsePercent} from '../../util/number';
import PieSeriesModel, { PieSeriesOption, PieDataItemOption } from './PieSeries';
import { VectorArray } from 'zrender/src/core/vector';
import { HorizontalAlign, ZRTextAlign } from '../../util/types';
import { Sector, Polyline, Point } from '../../util/graphic';
import ZRText from 'zrender/src/graphic/Text';
import BoundingRect, {RectLike} from 'zrender/src/core/BoundingRect';
import { each, isNumber } from 'zrender/src/core/util';
import { limitTurnAngle, limitSurfaceAngle } from '../../label/labelGuideHelper';
import { shiftLayoutOnY } from '../../label/labelLayoutHelper';

const RADIAN = Math.PI / 180;

interface LabelLayout {
    label: ZRText
    labelLine: Polyline
    position: PieSeriesOption['label']['position']
    len: number
    len2: number
    minTurnAngle: number
    maxSurfaceAngle: number
    surfaceNormal: Point
    linePoints: VectorArray[]
    textAlign: HorizontalAlign
    labelDistance: number
    labelAlignTo: PieSeriesOption['label']['alignTo']
    edgeDistance: number
    bleedMargin: PieSeriesOption['label']['bleedMargin']
    rect: BoundingRect
    /**
     * user-set style.width.
     * This is useful because label.style.width might be changed
     * by constrainTextWidth.
     */
    labelStyleWidth: number
    unconstrainedWidth: number
    targetTextWidth?: number
}

function adjustSingleSide(
    list: LabelLayout[],
    cx: number,
    cy: number,
    r: number,
    dir: -1 | 1,
    viewWidth: number,
    viewHeight: number,
    viewLeft: number,
    viewTop: number,
    farthestX: number
) {
    if (list.length < 2) {
        return;
    }

    interface SemiInfo {
        list: LabelLayout[]
        rB: number
        maxY: number
    };

    function recalculateXOnSemiToAlignOnEllipseCurve(semi: SemiInfo) {
        const rB = semi.rB;
        const rB2 = rB * rB;
        for (let i = 0; i < semi.list.length; i++) {
            const item = semi.list[i];
            const dy = Math.abs(item.label.y - cy);
            // horizontal r is always same with original r because x is not changed.
            const rA = r + item.len;
            const rA2 = rA * rA;
            // Use ellipse implicit function to calculate x
            const dx = Math.sqrt((1 - Math.abs(dy * dy / rB2)) * rA2);
            const newX = cx + (dx + item.len2) * dir;
            const deltaX = newX - item.label.x;
            const newTargetWidth = item.targetTextWidth - deltaX * dir;
            // text x is changed, so need to recalculate width.
            constrainTextWidth(item, newTargetWidth, true);
            item.label.x = newX;
        }
    }

    // Adjust X based on the shifted y. Make tight labels aligned on an ellipse curve.
    function recalculateX(items: LabelLayout[]) {
        // Extremes of
        const topSemi = { list: [], maxY: 0} as SemiInfo;
        const bottomSemi = { list: [], maxY: 0 } as SemiInfo;

        for (let i = 0; i < items.length; i++) {
            if (items[i].labelAlignTo !== 'none') {
                continue;
            }
            const item = items[i];
            const semi = item.label.y > cy ? bottomSemi : topSemi;
            const dy = Math.abs(item.label.y - cy);
            if (dy >= semi.maxY) {
                const dx = item.label.x - cx - item.len2 * dir;
                // horizontal r is always same with original r because x is not changed.
                const rA = r + item.len;
                // Canculate rB based on the topest / bottemest label.
                const rB = Math.abs(dx) < rA
                    ? Math.sqrt(dy * dy / (1 - dx * dx / rA / rA))
                    : rA;
                semi.rB = rB;
                semi.maxY = dy;
            }
            semi.list.push(item);
        }

        recalculateXOnSemiToAlignOnEllipseCurve(topSemi);
        recalculateXOnSemiToAlignOnEllipseCurve(bottomSemi);
    }

    const len = list.length;
    for (let i = 0; i < len; i++) {
        if (list[i].position === 'outer' && list[i].labelAlignTo === 'labelLine') {
            const dx = list[i].label.x - farthestX;
            list[i].linePoints[1][0] += dx;
            list[i].label.x = farthestX;
        }
    }

    if (shiftLayoutOnY(list, viewTop, viewTop + viewHeight)) {
        recalculateX(list);
    }
}

function avoidOverlap(
    labelLayoutList: LabelLayout[],
    cx: number,
    cy: number,
    r: number,
    viewWidth: number,
    viewHeight: number,
    viewLeft: number,
    viewTop: number
) {
    const leftList = [];
    const rightList = [];
    let leftmostX = Number.MAX_VALUE;
    let rightmostX = -Number.MAX_VALUE;
    for (let i = 0; i < labelLayoutList.length; i++) {
        const label = labelLayoutList[i].label;
        if (isPositionCenter(labelLayoutList[i])) {
            continue;
        }
        if (label.x < cx) {
            leftmostX = Math.min(leftmostX, label.x);
            leftList.push(labelLayoutList[i]);
        }
        else {
            rightmostX = Math.max(rightmostX, label.x);
            rightList.push(labelLayoutList[i]);
        }
    }

    for (let i = 0; i < labelLayoutList.length; i++) {
        const layout = labelLayoutList[i];
        if (!isPositionCenter(layout) && layout.linePoints) {
            if (layout.labelStyleWidth != null) {
                continue;
            }

            const label = layout.label;
            const linePoints = layout.linePoints;

            let targetTextWidth;
            if (layout.labelAlignTo === 'edge') {
                if (label.x < cx) {
                    targetTextWidth = linePoints[2][0] - layout.labelDistance
                            - viewLeft - layout.edgeDistance;
                }
                else {
                    targetTextWidth = viewLeft + viewWidth - layout.edgeDistance
                            - linePoints[2][0] - layout.labelDistance;
                }
            }
            else if (layout.labelAlignTo === 'labelLine') {
                if (label.x < cx) {
                    targetTextWidth = leftmostX - viewLeft - layout.bleedMargin;
                }
                else {
                    targetTextWidth = viewLeft + viewWidth - rightmostX - layout.bleedMargin;
                }
            }
            else {
                if (label.x < cx) {
                    targetTextWidth = label.x - viewLeft - layout.bleedMargin;
                }
                else {
                    targetTextWidth = viewLeft + viewWidth - label.x - layout.bleedMargin;
                }
            }
            layout.targetTextWidth = targetTextWidth;

            constrainTextWidth(layout, targetTextWidth);
        }
    }

    adjustSingleSide(rightList, cx, cy, r, 1, viewWidth, viewHeight, viewLeft, viewTop, rightmostX);
    adjustSingleSide(leftList, cx, cy, r, -1, viewWidth, viewHeight, viewLeft, viewTop, leftmostX);

    for (let i = 0; i < labelLayoutList.length; i++) {
        const layout = labelLayoutList[i];
        if (!isPositionCenter(layout) && layout.linePoints) {
            const label = layout.label;
            const linePoints = layout.linePoints;
            const isAlignToEdge = layout.labelAlignTo === 'edge';
            const padding = label.style.padding as number[];
            const paddingH = padding ? padding[1] + padding[3] : 0;
            // textRect.width already contains paddingH if bgColor is set
            const extraPaddingH = label.style.backgroundColor ? 0 : paddingH;
            const realTextWidth = layout.rect.width + extraPaddingH;
            const dist = linePoints[1][0] - linePoints[2][0];
            if (isAlignToEdge) {
                if (label.x < cx) {
                    linePoints[2][0] = viewLeft + layout.edgeDistance + realTextWidth + layout.labelDistance;
                }
                else {
                    linePoints[2][0] = viewLeft + viewWidth - layout.edgeDistance
                            - realTextWidth - layout.labelDistance;
                }
            }
            else {
                if (label.x < cx) {
                    linePoints[2][0] = label.x + layout.labelDistance;
                }
                else {
                    linePoints[2][0] = label.x - layout.labelDistance;
                }
                linePoints[1][0] = linePoints[2][0] + dist;
            }
            linePoints[1][1] = linePoints[2][1] = label.y;
        }
    }
}

/**
 * Set max width of each label, and then wrap each label to the max width.
 *
 * @param layout label layout
 * @param availableWidth max width for the label to display
 * @param forceRecalculate recaculate the text layout even if the current width
 * is smaller than `availableWidth`. This is useful when the text was previously
 * wrapped by calling `constrainTextWidth` but now `availableWidth` changed, in
 * which case, previous wrapping should be redo.
 */
function constrainTextWidth(
    layout: LabelLayout,
    availableWidth: number,
    forceRecalculate: boolean = false
) {
    if (layout.labelStyleWidth != null) {
        // User-defined style.width has the highest priority.
        return;
    }

    const label = layout.label;
    const style = label.style;
    const textRect = layout.rect;
    const bgColor = style.backgroundColor;
    const padding = style.padding as number[];
    const paddingH = padding ? padding[1] + padding[3] : 0;
    const overflow = style.overflow;

    // textRect.width already contains paddingH if bgColor is set
    const oldOuterWidth = textRect.width + (bgColor ? 0 : paddingH);
    if (availableWidth < oldOuterWidth || forceRecalculate) {
        const oldHeight = textRect.height;
        if (overflow && overflow.match('break')) {
            // Temporarily set background to be null to calculate
            // the bounding box without background.
            label.setStyle('backgroundColor', null);
            // Set constraining width
            label.setStyle('width', availableWidth - paddingH);

            // This is the real bounding box of the text without padding.
            const innerRect = label.getBoundingRect();

            label.setStyle('width', Math.ceil(innerRect.width));
            label.setStyle('backgroundColor', bgColor);
        }
        else {
            const availableInnerWidth = availableWidth - paddingH;
            const newWidth = availableWidth < oldOuterWidth
                // Current text is too wide, use `availableWidth` as max width.
                ? availableInnerWidth
                : (
                    // Current available width is enough, but the text may have
                    // already been wrapped with a smaller available width.
                    forceRecalculate
                        ? (availableInnerWidth > layout.unconstrainedWidth
                            // Current available is larger than text width,
                            // so don't constrain width (otherwise it may have
                            // empty space in the background).
                            ? null
                            // Current available is smaller than text width, so
                            // use the current available width as constraining
                            // width.
                            : availableInnerWidth
                        )
                    // Current available width is enough, so no need to
                    // constrain.
                    : null
                );
            label.setStyle('width', newWidth);
        }

        const newRect = label.getBoundingRect();
        textRect.width = newRect.width;
        const margin = (label.style.margin || 0) + 2.1;
        textRect.height = newRect.height + margin;
        textRect.y -= (textRect.height - oldHeight) / 2;
    }
}

function isPositionCenter(sectorShape: LabelLayout) {
    // Not change x for center label
    return sectorShape.position === 'center';
}

export default function pieLabelLayout(
    seriesModel: PieSeriesModel
) {
    const data = seriesModel.getData();
    const labelLayoutList: LabelLayout[] = [];
    let cx;
    let cy;
    let hasLabelRotate = false;
    const minShowLabelRadian = (seriesModel.get('minShowLabelAngle') || 0) * RADIAN;

    const viewRect = data.getLayout('viewRect') as RectLike;
    const r = data.getLayout('r') as number;
    const viewWidth = viewRect.width;
    const viewLeft = viewRect.x;
    const viewTop = viewRect.y;
    const viewHeight = viewRect.height;

    function setNotShow(el: {ignore: boolean}) {
        el.ignore = true;
    }

    function isLabelShown(label: ZRText) {
        if (!label.ignore) {
            return true;
        }
        for (const key in label.states) {
            if (label.states[key].ignore === false) {
                return true;
            }
        }
        return false;
    }

    data.each(function (idx) {
        const sector = data.getItemGraphicEl(idx) as Sector;
        const sectorShape = sector.shape;
        const label = sector.getTextContent();
        const labelLine = sector.getTextGuideLine();

        const itemModel = data.getItemModel<PieDataItemOption>(idx);
        const labelModel = itemModel.getModel('label');
        // Use position in normal or emphasis
        const labelPosition = labelModel.get('position') || itemModel.get(['emphasis', 'label', 'position']);
        const labelDistance = labelModel.get('distanceToLabelLine');
        const labelAlignTo = labelModel.get('alignTo');
        const edgeDistance = parsePercent(labelModel.get('edgeDistance'), viewWidth);
        const bleedMargin = labelModel.get('bleedMargin');

        const labelLineModel = itemModel.getModel('labelLine');
        let labelLineLen = labelLineModel.get('length');
        labelLineLen = parsePercent(labelLineLen, viewWidth);
        let labelLineLen2 = labelLineModel.get('length2');
        labelLineLen2 = parsePercent(labelLineLen2, viewWidth);

        if (Math.abs(sectorShape.endAngle - sectorShape.startAngle) < minShowLabelRadian) {
            each(label.states, setNotShow);
            label.ignore = true;
            if (labelLine) {
                each(labelLine.states, setNotShow);
                labelLine.ignore = true;
            }
            return;
        }

        if (!isLabelShown(label)) {
            return;
        }

        const midAngle = (sectorShape.startAngle + sectorShape.endAngle) / 2;
        const nx = Math.cos(midAngle);
        const ny = Math.sin(midAngle);

        let textX;
        let textY;
        let linePoints;
        let textAlign: ZRTextAlign;

        cx = sectorShape.cx;
        cy = sectorShape.cy;


        const isLabelInside = labelPosition === 'inside' || labelPosition === 'inner';
        if (labelPosition === 'center') {
            textX = sectorShape.cx;
            textY = sectorShape.cy;
            textAlign = 'center';
        }
        else {
            const x1 = (isLabelInside ? (sectorShape.r + sectorShape.r0) / 2 * nx : sectorShape.r * nx) + cx;
            const y1 = (isLabelInside ? (sectorShape.r + sectorShape.r0) / 2 * ny : sectorShape.r * ny) + cy;

            textX = x1 + nx * 3;
            textY = y1 + ny * 3;

            if (!isLabelInside) {
                // For roseType
                const x2 = x1 + nx * (labelLineLen + r - sectorShape.r);
                const y2 = y1 + ny * (labelLineLen + r - sectorShape.r);
                const x3 = x2 + ((nx < 0 ? -1 : 1) * labelLineLen2);
                const y3 = y2;

                if (labelAlignTo === 'edge') {
                    // Adjust textX because text align of edge is opposite
                    textX = nx < 0
                        ? viewLeft + edgeDistance
                        : viewLeft + viewWidth - edgeDistance;
                }
                else {
                    textX = x3 + (nx < 0 ? -labelDistance : labelDistance);
                }
                textY = y3;
                linePoints = [[x1, y1], [x2, y2], [x3, y3]];
            }

            textAlign = isLabelInside
                ? 'center'
                : (labelAlignTo === 'edge'
                    ? (nx > 0 ? 'right' : 'left')
                    : (nx > 0 ? 'left' : 'right'));
        }

        const PI = Math.PI;
        let labelRotate = 0;
        const rotate = labelModel.get('rotate');
        if (isNumber(rotate)) {
            labelRotate = rotate * (PI / 180);
        }
        else if (labelPosition === 'center') {
            labelRotate = 0;
        }
        else if (rotate === 'radial' || rotate === true) {
            const radialAngle = nx < 0 ? -midAngle + PI : -midAngle;
            labelRotate = radialAngle;
        }
        else if (rotate === 'tangential'
            && labelPosition !== 'outside' && labelPosition !== 'outer'
        ) {
            let rad = Math.atan2(nx, ny);
            if (rad < 0) {
                rad = PI * 2 + rad;
            }
            const isDown = ny > 0;
            if (isDown) {
                rad = PI + rad;
            }
            labelRotate = rad - PI;
        }

        hasLabelRotate = !!labelRotate;

        label.x = textX;
        label.y = textY;
        label.rotation = labelRotate;

        label.setStyle({
            verticalAlign: 'middle'
        });

        // Not sectorShape the inside label
        if (!isLabelInside) {
            const textRect = label.getBoundingRect().clone();
            textRect.applyTransform(label.getComputedTransform());
            // Text has a default 1px stroke. Exclude this.
            const margin = (label.style.margin || 0) + 2.1;
            textRect.y -= margin / 2;
            textRect.height += margin;

            labelLayoutList.push({
                label,
                labelLine,
                position: labelPosition,
                len: labelLineLen,
                len2: labelLineLen2,
                minTurnAngle: labelLineModel.get('minTurnAngle'),
                maxSurfaceAngle: labelLineModel.get('maxSurfaceAngle'),
                surfaceNormal: new Point(nx, ny),
                linePoints: linePoints,
                textAlign: textAlign,
                labelDistance: labelDistance,
                labelAlignTo: labelAlignTo,
                edgeDistance: edgeDistance,
                bleedMargin: bleedMargin,
                rect: textRect,
                unconstrainedWidth: textRect.width,
                labelStyleWidth: label.style.width
            });
        }
        else {
            label.setStyle({
                align: textAlign
            });
            const selectState = label.states.select;
            if (selectState) {
                selectState.x += label.x;
                selectState.y += label.y;
            }
        }
        sector.setTextConfig({
            inside: isLabelInside
        });
    });

    if (!hasLabelRotate && seriesModel.get('avoidLabelOverlap')) {
        avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, viewLeft, viewTop);
    }

    for (let i = 0; i < labelLayoutList.length; i++) {
        const layout = labelLayoutList[i];
        const label = layout.label;
        const labelLine = layout.labelLine;
        const notShowLabel = isNaN(label.x) || isNaN(label.y);
        if (label) {
            label.setStyle({
                align: layout.textAlign
            });
            if (notShowLabel) {
                each(label.states, setNotShow);
                label.ignore = true;
            }
            const selectState = label.states.select;
            if (selectState) {
                selectState.x += label.x;
                selectState.y += label.y;
            }
        }
        if (labelLine) {
            const linePoints = layout.linePoints;
            if (notShowLabel || !linePoints) {
                each(labelLine.states, setNotShow);
                labelLine.ignore = true;
            }
            else {
                limitTurnAngle(linePoints, layout.minTurnAngle);
                limitSurfaceAngle(linePoints, layout.surfaceNormal, layout.maxSurfaceAngle);

                labelLine.setShape({ points: linePoints });

                // Set the anchor to the midpoint of sector
                label.__hostTarget.textGuideLineConfig = {
                    anchor: new Point(linePoints[0][0], linePoints[0][1])
                };
            }
        }
    }
}
