/*
* 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 {
    Point,
    Path,
    Polyline
} from '../util/graphic';
import PathProxy from 'zrender/src/core/PathProxy';
import { RectLike } from 'zrender/src/core/BoundingRect';
import { normalizeRadian } from 'zrender/src/contain/util';
import { cubicProjectPoint, quadraticProjectPoint } from 'zrender/src/core/curve';
import Element from 'zrender/src/Element';
import { defaults, retrieve2 } from 'zrender/src/core/util';
import { LabelLineOption, DisplayState, StatesOptionMixin } from '../util/types';
import Model from '../model/Model';
import { invert } from 'zrender/src/core/matrix';
import * as vector from 'zrender/src/core/vector';
import { DISPLAY_STATES, SPECIAL_STATES } from '../util/states';

const PI2 = Math.PI * 2;
const CMD = PathProxy.CMD;

const DEFAULT_SEARCH_SPACE = ['top', 'right', 'bottom', 'left'] as const;

type CandidatePosition = typeof DEFAULT_SEARCH_SPACE[number];

function getCandidateAnchor(
    pos: CandidatePosition,
    distance: number,
    rect: RectLike,
    outPt: Point,
    outDir: Point
) {
    const width = rect.width;
    const height = rect.height;
    switch (pos) {
        case 'top':
            outPt.set(
                rect.x + width / 2,
                rect.y - distance
            );
            outDir.set(0, -1);
            break;
        case 'bottom':
            outPt.set(
                rect.x + width / 2,
                rect.y + height + distance
            );
            outDir.set(0, 1);
            break;
        case 'left':
            outPt.set(
                rect.x - distance,
                rect.y + height / 2
            );
            outDir.set(-1, 0);
            break;
        case 'right':
            outPt.set(
                rect.x + width + distance,
                rect.y + height / 2
            );
            outDir.set(1, 0);
            break;
    }
}


function projectPointToArc(
    cx: number, cy: number, r: number, startAngle: number, endAngle: number, anticlockwise: boolean,
    x: number, y: number, out: number[]
): number {
    x -= cx;
    y -= cy;
    const d = Math.sqrt(x * x + y * y);
    x /= d;
    y /= d;

    // Intersect point.
    const ox = x * r + cx;
    const oy = y * r + cy;

    if (Math.abs(startAngle - endAngle) % PI2 < 1e-4) {
        // Is a circle
        out[0] = ox;
        out[1] = oy;
        return d - r;
    }

    if (anticlockwise) {
        const tmp = startAngle;
        startAngle = normalizeRadian(endAngle);
        endAngle = normalizeRadian(tmp);
    }
    else {
        startAngle = normalizeRadian(startAngle);
        endAngle = normalizeRadian(endAngle);
    }
    if (startAngle > endAngle) {
        endAngle += PI2;
    }

    let angle = Math.atan2(y, x);
    if (angle < 0) {
        angle += PI2;
    }
    if ((angle >= startAngle && angle <= endAngle)
        || (angle + PI2 >= startAngle && angle + PI2 <= endAngle)) {
        // Project point is on the arc.
        out[0] = ox;
        out[1] = oy;
        return d - r;
    }

    const x1 = r * Math.cos(startAngle) + cx;
    const y1 = r * Math.sin(startAngle) + cy;

    const x2 = r * Math.cos(endAngle) + cx;
    const y2 = r * Math.sin(endAngle) + cy;

    const d1 = (x1 - x) * (x1 - x) + (y1 - y) * (y1 - y);
    const d2 = (x2 - x) * (x2 - x) + (y2 - y) * (y2 - y);

    if (d1 < d2) {
        out[0] = x1;
        out[1] = y1;
        return Math.sqrt(d1);
    }
    else {
        out[0] = x2;
        out[1] = y2;
        return Math.sqrt(d2);
    }
}

function projectPointToLine(
    x1: number, y1: number, x2: number, y2: number, x: number, y: number, out: number[], limitToEnds: boolean
) {
    const dx = x - x1;
    const dy = y - y1;

    let dx1 = x2 - x1;
    let dy1 = y2 - y1;

    const lineLen = Math.sqrt(dx1 * dx1 + dy1 * dy1);
    dx1 /= lineLen;
    dy1 /= lineLen;

    // dot product
    const projectedLen = dx * dx1 + dy * dy1;
    let t = projectedLen / lineLen;
    if (limitToEnds) {
        t = Math.min(Math.max(t, 0), 1);
    }
    t *= lineLen;
    const ox = out[0] = x1 + t * dx1;
    const oy = out[1] = y1 + t * dy1;

    return Math.sqrt((ox - x) * (ox - x) + (oy - y) * (oy - y));
}

function projectPointToRect(
    x1: number, y1: number, width: number, height: number, x: number, y: number, out: number[]
): number {
    if (width < 0) {
        x1 = x1 + width;
        width = -width;
    }
    if (height < 0) {
        y1 = y1 + height;
        height = -height;
    }
    const x2 = x1 + width;
    const y2 = y1 + height;

    const ox = out[0] = Math.min(Math.max(x, x1), x2);
    const oy = out[1] = Math.min(Math.max(y, y1), y2);

    return Math.sqrt((ox - x) * (ox - x) + (oy - y) * (oy - y));
}

const tmpPt: number[] = [];

function nearestPointOnRect(pt: Point, rect: RectLike, out: Point) {
    const dist = projectPointToRect(
        rect.x, rect.y, rect.width, rect.height,
        pt.x, pt.y, tmpPt
    );
    out.set(tmpPt[0], tmpPt[1]);
    return dist;
}
/**
 * Calculate min distance corresponding point.
 * This method won't evaluate if point is in the path.
 */
function nearestPointOnPath(pt: Point, path: PathProxy, out: Point) {
    let xi = 0;
    let yi = 0;
    let x0 = 0;
    let y0 = 0;
    let x1;
    let y1;

    let minDist = Infinity;

    const data = path.data;
    const x = pt.x;
    const y = pt.y;

    for (let i = 0; i < data.length;) {
        const cmd = data[i++];

        if (i === 1) {
            xi = data[i];
            yi = data[i + 1];
            x0 = xi;
            y0 = yi;
        }

        let d = minDist;

        switch (cmd) {
            case CMD.M:
                // moveTo 命令重新创建一个新的 subpath, 并且更新新的起点
                // 在 closePath 的时候使用
                x0 = data[i++];
                y0 = data[i++];
                xi = x0;
                yi = y0;
                break;
            case CMD.L:
                d = projectPointToLine(xi, yi, data[i], data[i + 1], x, y, tmpPt, true);
                xi = data[i++];
                yi = data[i++];
                break;
            case CMD.C:
                d = cubicProjectPoint(
                    xi, yi,
                    data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1],
                    x, y, tmpPt
                );

                xi = data[i++];
                yi = data[i++];
                break;
            case CMD.Q:
                d = quadraticProjectPoint(
                    xi, yi,
                    data[i++], data[i++], data[i], data[i + 1],
                    x, y, tmpPt
                );
                xi = data[i++];
                yi = data[i++];
                break;
            case CMD.A:
                // TODO Arc 判断的开销比较大
                const cx = data[i++];
                const cy = data[i++];
                const rx = data[i++];
                const ry = data[i++];
                const theta = data[i++];
                const dTheta = data[i++];
                // TODO Arc 旋转
                i += 1;
                const anticlockwise = !!(1 - data[i++]);
                x1 = Math.cos(theta) * rx + cx;
                y1 = Math.sin(theta) * ry + cy;
                // 不是直接使用 arc 命令
                if (i <= 1) {
                    // 第一个命令起点还未定义
                    x0 = x1;
                    y0 = y1;
                }
                // zr 使用scale来模拟椭圆, 这里也对x做一定的缩放
                const _x = (x - cx) * ry / rx + cx;
                d = projectPointToArc(
                    cx, cy, ry, theta, theta + dTheta, anticlockwise,
                    _x, y, tmpPt
                );
                xi = Math.cos(theta + dTheta) * rx + cx;
                yi = Math.sin(theta + dTheta) * ry + cy;
                break;
            case CMD.R:
                x0 = xi = data[i++];
                y0 = yi = data[i++];
                const width = data[i++];
                const height = data[i++];
                d = projectPointToRect(x0, y0, width, height, x, y, tmpPt);
                break;
            case CMD.Z:
                d = projectPointToLine(xi, yi, x0, y0, x, y, tmpPt, true);

                xi = x0;
                yi = y0;
                break;
        }

        if (d < minDist) {
            minDist = d;
            out.set(tmpPt[0], tmpPt[1]);
        }
    }

    return minDist;
}

// Temporal variable for intermediate usage.
const pt0 = new Point();
const pt1 = new Point();
const pt2 = new Point();
const dir = new Point();
const dir2 = new Point();

/**
 * Calculate a proper guide line based on the label position and graphic element definition
 * @param label
 * @param labelRect
 * @param target
 * @param targetRect
 */
export function updateLabelLinePoints(
    target: Element,
    labelLineModel: Model<LabelLineOption>
) {
    if (!target) {
        return;
    }

    const labelLine = target.getTextGuideLine();
    const label = target.getTextContent();
    // Needs to create text guide in each charts.
    if (!(label && labelLine)) {
        return;
    }

    const labelGuideConfig = target.textGuideLineConfig || {};

    const points = [[0, 0], [0, 0], [0, 0]];

    const searchSpace = labelGuideConfig.candidates || DEFAULT_SEARCH_SPACE;
    const labelRect = label.getBoundingRect().clone();
    labelRect.applyTransform(label.getComputedTransform());

    let minDist = Infinity;
    const anchorPoint = labelGuideConfig.anchor;
    const targetTransform = target.getComputedTransform();
    const targetInversedTransform = targetTransform && invert([], targetTransform);
    const len = labelLineModel.get('length2') || 0;

    if (anchorPoint) {
        pt2.copy(anchorPoint);
    }
    for (let i = 0; i < searchSpace.length; i++) {
        const candidate = searchSpace[i];
        getCandidateAnchor(candidate, 0, labelRect, pt0, dir);
        Point.scaleAndAdd(pt1, pt0, dir, len);

        // Transform to target coord space.
        pt1.transform(targetInversedTransform);

        // Note: getBoundingRect will ensure the `path` being created.
        const boundingRect = target.getBoundingRect();
        const dist = anchorPoint ? anchorPoint.distance(pt1)
            : (target instanceof Path
                ? nearestPointOnPath(pt1, target.path, pt2)
                : nearestPointOnRect(pt1, boundingRect, pt2));

        // TODO pt2 is in the path
        if (dist < minDist) {
            minDist = dist;
            // Transform back to global space.
            pt1.transform(targetTransform);
            pt2.transform(targetTransform);

            pt2.toArray(points[0]);
            pt1.toArray(points[1]);
            pt0.toArray(points[2]);
        }
    }

    limitTurnAngle(points, labelLineModel.get('minTurnAngle'));

    labelLine.setShape({ points });
}

// Temporal variable for the limitTurnAngle function
const tmpArr: number[] = [];
const tmpProjPoint = new Point();
/**
 * Reduce the line segment attached to the label to limit the turn angle between two segments.
 * @param linePoints
 * @param minTurnAngle Radian of minimum turn angle. 0 - 180
 */
export function limitTurnAngle(linePoints: number[][], minTurnAngle: number) {
    if (!(minTurnAngle <= 180 && minTurnAngle > 0)) {
        return;
    }
    minTurnAngle = minTurnAngle / 180 * Math.PI;
    // The line points can be
    //      /pt1----pt2 (label)
    //     /
    // pt0/
    pt0.fromArray(linePoints[0]);
    pt1.fromArray(linePoints[1]);
    pt2.fromArray(linePoints[2]);

    Point.sub(dir, pt0, pt1);
    Point.sub(dir2, pt2, pt1);

    const len1 = dir.len();
    const len2 = dir2.len();
    if (len1 < 1e-3 || len2 < 1e-3) {
        return;
    }

    dir.scale(1 / len1);
    dir2.scale(1 / len2);

    const angleCos = dir.dot(dir2);
    const minTurnAngleCos = Math.cos(minTurnAngle);
    if (minTurnAngleCos < angleCos) {    // Smaller than minTurnAngle
        // Calculate project point of pt0 on pt1-pt2
        const d = projectPointToLine(pt1.x, pt1.y, pt2.x, pt2.y, pt0.x, pt0.y, tmpArr, false);
        tmpProjPoint.fromArray(tmpArr);
        // Calculate new projected length with limited minTurnAngle and get the new connect point
        tmpProjPoint.scaleAndAdd(dir2, d / Math.tan(Math.PI - minTurnAngle));
        // Limit the new calculated connect point between pt1 and pt2.
        const t = pt2.x !== pt1.x
            ? (tmpProjPoint.x - pt1.x) / (pt2.x - pt1.x)
            : (tmpProjPoint.y - pt1.y) / (pt2.y - pt1.y);
        if (isNaN(t)) {
            return;
        }

        if (t < 0) {
            Point.copy(tmpProjPoint, pt1);
        }
        else if (t > 1) {
            Point.copy(tmpProjPoint, pt2);
        }

        tmpProjPoint.toArray(linePoints[1]);
    }
}

/**
 * Limit the angle of line and the surface
 * @param maxSurfaceAngle Radian of minimum turn angle. 0 - 180. 0 is same direction to normal. 180 is opposite
 */
export function limitSurfaceAngle(linePoints: vector.VectorArray[], surfaceNormal: Point, maxSurfaceAngle: number) {
    if (!(maxSurfaceAngle <= 180 && maxSurfaceAngle > 0)) {
        return;
    }
    maxSurfaceAngle = maxSurfaceAngle / 180 * Math.PI;

    pt0.fromArray(linePoints[0]);
    pt1.fromArray(linePoints[1]);
    pt2.fromArray(linePoints[2]);

    Point.sub(dir, pt1, pt0);
    Point.sub(dir2, pt2, pt1);

    const len1 = dir.len();
    const len2 = dir2.len();

    if (len1 < 1e-3 || len2 < 1e-3) {
        return;
    }

    dir.scale(1 / len1);
    dir2.scale(1 / len2);

    const angleCos = dir.dot(surfaceNormal);
    const maxSurfaceAngleCos = Math.cos(maxSurfaceAngle);

    if (angleCos < maxSurfaceAngleCos) {
        // Calculate project point of pt0 on pt1-pt2
        const d = projectPointToLine(pt1.x, pt1.y, pt2.x, pt2.y, pt0.x, pt0.y, tmpArr, false);
        tmpProjPoint.fromArray(tmpArr);

        const HALF_PI = Math.PI / 2;
        const angle2 = Math.acos(dir2.dot(surfaceNormal));
        const newAngle = HALF_PI + angle2 - maxSurfaceAngle;
        if (newAngle >= HALF_PI) {
            // parallel
            Point.copy(tmpProjPoint, pt2);
        }
        else {
            // Calculate new projected length with limited minTurnAngle and get the new connect point
            tmpProjPoint.scaleAndAdd(dir2, d / Math.tan(Math.PI / 2 - newAngle));
            // Limit the new calculated connect point between pt1 and pt2.
            const t = pt2.x !== pt1.x
                ? (tmpProjPoint.x - pt1.x) / (pt2.x - pt1.x)
                : (tmpProjPoint.y - pt1.y) / (pt2.y - pt1.y);
            if (isNaN(t)) {
                return;
            }

            if (t < 0) {
                Point.copy(tmpProjPoint, pt1);
            }
            else if (t > 1) {
                Point.copy(tmpProjPoint, pt2);
            }
        }

        tmpProjPoint.toArray(linePoints[1]);
    }
}


type LabelLineModel = Model<LabelLineOption>;

function setLabelLineState(
    labelLine: Polyline,
    ignore: boolean,
    stateName: string,
    stateModel: Model
) {
    const isNormal = stateName === 'normal';
    const stateObj = isNormal ? labelLine : labelLine.ensureState(stateName);
    // Make sure display.
    stateObj.ignore = ignore;
    // Set smooth
    let smooth = stateModel.get('smooth');
    if (smooth && smooth === true) {
        smooth = 0.3;
    }
    stateObj.shape = stateObj.shape || {};
    if (smooth > 0) {
        (stateObj.shape as Polyline['shape']).smooth = smooth as number;
    }

    const styleObj = stateModel.getModel('lineStyle').getLineStyle();
    isNormal ? labelLine.useStyle(styleObj) : stateObj.style = styleObj;
}

function buildLabelLinePath(path: CanvasRenderingContext2D, shape: Polyline['shape']) {
    const smooth = shape.smooth as number;
    const points = shape.points;
    if (!points) {
        return;
    }
    path.moveTo(points[0][0], points[0][1]);
    if (smooth > 0 && points.length >= 3) {
        const len1 = vector.dist(points[0], points[1]);
        const len2 = vector.dist(points[1], points[2]);
        if (!len1 || !len2) {
            path.lineTo(points[1][0], points[1][1]);
            path.lineTo(points[2][0], points[2][1]);
            return;
        }

        const moveLen = Math.min(len1, len2) * smooth;

        const midPoint0 = vector.lerp([], points[1], points[0], moveLen / len1);
        const midPoint2 = vector.lerp([], points[1], points[2], moveLen / len2);

        const midPoint1 = vector.lerp([], midPoint0, midPoint2, 0.5);
        path.bezierCurveTo(midPoint0[0], midPoint0[1], midPoint0[0], midPoint0[1], midPoint1[0], midPoint1[1]);
        path.bezierCurveTo(midPoint2[0], midPoint2[1], midPoint2[0], midPoint2[1], points[2][0], points[2][1]);
    }
    else {
        for (let i = 1; i < points.length; i++) {
            path.lineTo(points[i][0], points[i][1]);
        }
    }
}

/**
 * Create a label line if necessary and set it's style.
 */
export function setLabelLineStyle(
    targetEl: Element,
    statesModels: Record<DisplayState, LabelLineModel>,
    defaultStyle?: Polyline['style']
) {
    let labelLine = targetEl.getTextGuideLine();
    const label = targetEl.getTextContent();
    if (!label) {
        // Not show label line if there is no label.
        if (labelLine) {
            targetEl.removeTextGuideLine();
        }
        return;
    }

    const normalModel = statesModels.normal;
    const showNormal = normalModel.get('show');
    const labelIgnoreNormal = label.ignore;

    for (let i = 0; i < DISPLAY_STATES.length; i++) {
        const stateName = DISPLAY_STATES[i];
        const stateModel = statesModels[stateName];
        const isNormal = stateName === 'normal';
        if (stateModel) {
            const stateShow = stateModel.get('show');
            const isLabelIgnored = isNormal
                ? labelIgnoreNormal
                : retrieve2(label.states[stateName] && label.states[stateName].ignore, labelIgnoreNormal);
            if (isLabelIgnored  // Not show when label is not shown in this state.
                || !retrieve2(stateShow, showNormal) // Use normal state by default if not set.
            ) {
                const stateObj = isNormal ? labelLine : (labelLine && labelLine.states[stateName]);
                if (stateObj) {
                    stateObj.ignore = true;
                }
                continue;
            }
            // Create labelLine if not exists
            if (!labelLine) {
                labelLine = new Polyline();
                targetEl.setTextGuideLine(labelLine);
                // Reset state of normal because it's new created.
                // NOTE: NORMAL should always been the first!
                if (!isNormal && (labelIgnoreNormal || !showNormal)) {
                    setLabelLineState(labelLine, true, 'normal', statesModels.normal);
                }

                // Use same state proxy.
                if (targetEl.stateProxy) {
                    labelLine.stateProxy = targetEl.stateProxy;
                }
            }

            setLabelLineState(labelLine, false, stateName, stateModel);
        }
    }

    if (labelLine) {
        defaults(labelLine.style, defaultStyle);
        // Not fill.
        labelLine.style.fill = null;

        const showAbove = normalModel.get('showAbove');

        const labelLineConfig = (targetEl.textGuideLineConfig = targetEl.textGuideLineConfig || {});
        labelLineConfig.showAbove = showAbove || false;

        // Custom the buildPath.
        labelLine.buildPath = buildLabelLinePath;
    }
}


export function getLabelLineStatesModels<LabelName extends string = 'labelLine'>(
    itemModel: Model<StatesOptionMixin<any, any> & Partial<Record<LabelName, any>>>,
    labelLineName?: LabelName
): Record<DisplayState, LabelLineModel> {
    labelLineName = (labelLineName || 'labelLine') as LabelName;
    const statesModels = {
        normal: itemModel.getModel(labelLineName) as LabelLineModel
    } as Record<DisplayState, LabelLineModel>;
    for (let i = 0; i < SPECIAL_STATES.length; i++) {
        const stateName = SPECIAL_STATES[i];
        statesModels[stateName] = itemModel.getModel([stateName, labelLineName]);
    }
    return statesModels;
}
