/*
* 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 {getECData} from '../../util/innerStore';
import SymbolClz from '../helper/Symbol';
import {radialCoordinate} from './layoutHelper';
import * as bbox from 'zrender/src/core/bbox';
import View from '../../coord/View';
import * as roamHelper from '../../component/helper/roamHelper';
import RoamController, { RoamControllerHost } from '../../component/helper/RoamController';
import {onIrrelevantElement} from '../../component/helper/cursorHelper';
import {parsePercent} from '../../util/number';
import ChartView from '../../view/Chart';
import TreeSeriesModel, { TreeSeriesOption, TreeSeriesNodeItemOption } from './TreeSeries';
import Path, { PathProps } from 'zrender/src/graphic/Path';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../core/ExtensionAPI';
import { TreeNode } from '../../data/Tree';
import List from '../../data/List';
import { setStatesStylesFromModel, setStatesFlag, setDefaultStateProxy, HOVER_STATE_BLUR } from '../../util/states';
import { ECElement } from '../../util/types';

type TreeSymbol = SymbolClz & {
    __edge: graphic.BezierCurve | TreePath

    __radialOldRawX: number
    __radialOldRawY: number
    __radialRawX: number
    __radialRawY: number

    __oldX: number
    __oldY: number
};

class TreeEdgeShape {
    parentPoint: number[] = [];
    childPoints: number[][] = [];
    orient: TreeSeriesOption['orient'];
    forkPosition: TreeSeriesOption['edgeForkPosition'];
}

interface TreeEdgePathProps extends PathProps {
    shape?: Partial<TreeEdgeShape>
}

interface TreeNodeLayout {
    x: number
    y: number
    rawX: number
    rawY: number
}

class TreePath extends Path<TreeEdgePathProps> {
    shape: TreeEdgeShape;
    constructor(opts?: TreeEdgePathProps) {
        super(opts);
    }

    getDefaultStyle() {
        return {
            stroke: '#000',
            fill: null as string
        };
    }

    getDefaultShape() {
        return new TreeEdgeShape();
    }

    buildPath(ctx: CanvasRenderingContext2D, shape: TreeEdgeShape) {
        const childPoints = shape.childPoints;
        const childLen = childPoints.length;
        const parentPoint = shape.parentPoint;
        const firstChildPos = childPoints[0];
        const lastChildPos = childPoints[childLen - 1];

        if (childLen === 1) {
            ctx.moveTo(parentPoint[0], parentPoint[1]);
            ctx.lineTo(firstChildPos[0], firstChildPos[1]);
            return;
        }

        const orient = shape.orient;
        const forkDim = (orient === 'TB' || orient === 'BT') ? 0 : 1;
        const otherDim = 1 - forkDim;
        const forkPosition = parsePercent(shape.forkPosition, 1);
        const tmpPoint = [];
        tmpPoint[forkDim] = parentPoint[forkDim];
        tmpPoint[otherDim] = parentPoint[otherDim] + (lastChildPos[otherDim] - parentPoint[otherDim]) * forkPosition;

        ctx.moveTo(parentPoint[0], parentPoint[1]);
        ctx.lineTo(tmpPoint[0], tmpPoint[1]);
        ctx.moveTo(firstChildPos[0], firstChildPos[1]);
        tmpPoint[forkDim] = firstChildPos[forkDim];
        ctx.lineTo(tmpPoint[0], tmpPoint[1]);
        tmpPoint[forkDim] = lastChildPos[forkDim];
        ctx.lineTo(tmpPoint[0], tmpPoint[1]);
        ctx.lineTo(lastChildPos[0], lastChildPos[1]);

        for (let i = 1; i < childLen - 1; i++) {
            const point = childPoints[i];
            ctx.moveTo(point[0], point[1]);
            tmpPoint[forkDim] = point[forkDim];
            ctx.lineTo(tmpPoint[0], tmpPoint[1]);
        }
    }
}

class TreeView extends ChartView {

    static readonly type = 'tree';
    readonly type = TreeView.type;

    private _mainGroup = new graphic.Group();

    private _controller: RoamController;
    private _controllerHost: RoamControllerHost;

    private _data: List<TreeSeriesModel>;

    private _nodeScaleRatio: number;
    private _min: number[];
    private _max: number[];

    init(ecModel: GlobalModel, api: ExtensionAPI) {


        this._controller = new RoamController(api.getZr());

        this._controllerHost = {
            target: this.group
        } as RoamControllerHost;

        this.group.add(this._mainGroup);
    }

    render(
        seriesModel: TreeSeriesModel,
        ecModel: GlobalModel,
        api: ExtensionAPI
    ) {
        const data = seriesModel.getData();

        const layoutInfo = seriesModel.layoutInfo;

        const group = this._mainGroup;

        const layout = seriesModel.get('layout');

        if (layout === 'radial') {
            group.x = layoutInfo.x + layoutInfo.width / 2;
            group.y = layoutInfo.y + layoutInfo.height / 2;
        }
        else {
            group.x = layoutInfo.x;
            group.y = layoutInfo.y;
        }

        this._updateViewCoordSys(seriesModel);
        this._updateController(seriesModel, ecModel, api);

        const oldData = this._data;

        data.diff(oldData)
            .add(function (newIdx) {
                if (symbolNeedsDraw(data, newIdx)) {
                    // Create node and edge
                    updateNode(data, newIdx, null, group, seriesModel);
                }
            })
            .update(function (newIdx, oldIdx) {
                const symbolEl = oldData.getItemGraphicEl(oldIdx) as TreeSymbol;
                if (!symbolNeedsDraw(data, newIdx)) {
                    symbolEl && removeNode(oldData, oldIdx, symbolEl, group, seriesModel);
                    return;
                }
                // Update node and edge
                updateNode(data, newIdx, symbolEl, group, seriesModel);
            })
            .remove(function (oldIdx) {
                const symbolEl = oldData.getItemGraphicEl(oldIdx) as TreeSymbol;
                // When remove a collapsed node of subtree, since the collapsed
                // node haven't been initialized with a symbol element,
                // you can't found it's symbol element through index.
                // so if we want to remove the symbol element we should insure
                // that the symbol element is not null.
                if (symbolEl) {
                    removeNode(oldData, oldIdx, symbolEl, group, seriesModel);
                }
            })
            .execute();

        this._nodeScaleRatio = seriesModel.get('nodeScaleRatio');

        this._updateNodeAndLinkScale(seriesModel);

        if (seriesModel.get('expandAndCollapse') === true) {
            data.eachItemGraphicEl(function (el, dataIndex) {
                el.off('click').on('click', function () {
                    api.dispatchAction({
                        type: 'treeExpandAndCollapse',
                        seriesId: seriesModel.id,
                        dataIndex: dataIndex
                    });
                });
            });
        }
        this._data = data;
    }

    _updateViewCoordSys(seriesModel: TreeSeriesModel) {
        const data = seriesModel.getData();
        const points: number[][] = [];
        data.each(function (idx) {
            const layout = data.getItemLayout(idx);
            if (layout && !isNaN(layout.x) && !isNaN(layout.y)) {
                points.push([+layout.x, +layout.y]);
            }
        });
        const min: number[] = [];
        const max: number[] = [];
        bbox.fromPoints(points, min, max);

        // If don't Store min max when collapse the root node after roam,
        // the root node will disappear.
        const oldMin = this._min;
        const oldMax = this._max;

        // If width or height is 0
        if (max[0] - min[0] === 0) {
            min[0] = oldMin ? oldMin[0] : min[0] - 1;
            max[0] = oldMax ? oldMax[0] : max[0] + 1;
        }
        if (max[1] - min[1] === 0) {
            min[1] = oldMin ? oldMin[1] : min[1] - 1;
            max[1] = oldMax ? oldMax[1] : max[1] + 1;
        }

        const viewCoordSys = seriesModel.coordinateSystem = new View();
        viewCoordSys.zoomLimit = seriesModel.get('scaleLimit');

        viewCoordSys.setBoundingRect(min[0], min[1], max[0] - min[0], max[1] - min[1]);

        viewCoordSys.setCenter(seriesModel.get('center'));
        viewCoordSys.setZoom(seriesModel.get('zoom'));

        // Here we use viewCoordSys just for computing the 'position' and 'scale' of the group
        this.group.attr({
            x: viewCoordSys.x,
            y: viewCoordSys.y,
            scaleX: viewCoordSys.scaleX,
            scaleY: viewCoordSys.scaleY
        });

        this._min = min;
        this._max = max;
    }

    _updateController(
        seriesModel: TreeSeriesModel,
        ecModel: GlobalModel,
        api: ExtensionAPI
    ) {
        const controller = this._controller;
        const controllerHost = this._controllerHost;
        const group = this.group;
        controller.setPointerChecker(function (e, x, y) {
            const rect = group.getBoundingRect();
            rect.applyTransform(group.transform);
            return rect.contain(x, y)
                && !onIrrelevantElement(e, api, seriesModel);
        });

        controller.enable(seriesModel.get('roam'));
        controllerHost.zoomLimit = seriesModel.get('scaleLimit');
        controllerHost.zoom = seriesModel.coordinateSystem.getZoom();

        controller
            .off('pan')
            .off('zoom')
            .on('pan', (e) => {
                roamHelper.updateViewOnPan(controllerHost, e.dx, e.dy);
                api.dispatchAction({
                    seriesId: seriesModel.id,
                    type: 'treeRoam',
                    dx: e.dx,
                    dy: e.dy
                });
            })
            .on('zoom', (e) => {
                roamHelper.updateViewOnZoom(controllerHost, e.scale, e.originX, e.originY);
                api.dispatchAction({
                    seriesId: seriesModel.id,
                    type: 'treeRoam',
                    zoom: e.scale,
                    originX: e.originX,
                    originY: e.originY
                });
                this._updateNodeAndLinkScale(seriesModel);
                // Only update label layout on zoom
                api.updateLabelLayout();
            });
    }

    _updateNodeAndLinkScale(seriesModel: TreeSeriesModel) {
        const data = seriesModel.getData();

        const nodeScale = this._getNodeGlobalScale(seriesModel);

        data.eachItemGraphicEl(function (el: SymbolClz, idx) {
            el.setSymbolScale(nodeScale);
        });
    }

    _getNodeGlobalScale(seriesModel: TreeSeriesModel) {
        const coordSys = seriesModel.coordinateSystem;
        if (coordSys.type !== 'view') {
            return 1;
        }

        const nodeScaleRatio = this._nodeScaleRatio;

        const groupZoom = coordSys.scaleX || 1;
        // Scale node when zoom changes
        const roamZoom = coordSys.getZoom();
        const nodeScale = (roamZoom - 1) * nodeScaleRatio + 1;

        return nodeScale / groupZoom;
    }

    dispose() {
        this._controller && this._controller.dispose();
        this._controllerHost = null;
    }

    remove() {
        this._mainGroup.removeAll();
        this._data = null;
    }

}

function symbolNeedsDraw(data: List, dataIndex: number) {
    const layout = data.getItemLayout(dataIndex);

    return layout
        && !isNaN(layout.x) && !isNaN(layout.y);
}


function updateNode(
    data: List,
    dataIndex: number,
    symbolEl: TreeSymbol,
    group: graphic.Group,
    seriesModel: TreeSeriesModel
) {
    const isInit = !symbolEl;
    const node = data.tree.getNodeByDataIndex(dataIndex);
    const itemModel = node.getModel<TreeSeriesNodeItemOption>();
    const visualColor = node.getVisual('style').fill;
    const symbolInnerColor = node.isExpand === false && node.children.length !== 0
            ? visualColor : '#fff';

    const virtualRoot = data.tree.root;

    const source = node.parentNode === virtualRoot ? node : node.parentNode || node;
    const sourceSymbolEl = data.getItemGraphicEl(source.dataIndex) as TreeSymbol;
    const sourceLayout = source.getLayout() as TreeNodeLayout;
    const sourceOldLayout = sourceSymbolEl
        ? {
            x: sourceSymbolEl.__oldX,
            y: sourceSymbolEl.__oldY,
            rawX: sourceSymbolEl.__radialOldRawX,
            rawY: sourceSymbolEl.__radialOldRawY
        }
        : sourceLayout;
    const targetLayout = node.getLayout();

    if (isInit) {
        symbolEl = new SymbolClz(data, dataIndex, null, {
            symbolInnerColor,
            useNameLabel: true
        }) as TreeSymbol;
        symbolEl.x = sourceOldLayout.x;
        symbolEl.y = sourceOldLayout.y;
    }
    else {
        symbolEl.updateData(data, dataIndex, null, {
            symbolInnerColor,
            useNameLabel: true
        });
    }

    symbolEl.__radialOldRawX = symbolEl.__radialRawX;
    symbolEl.__radialOldRawY = symbolEl.__radialRawY;
    symbolEl.__radialRawX = targetLayout.rawX;
    symbolEl.__radialRawY = targetLayout.rawY;

    group.add(symbolEl);
    data.setItemGraphicEl(dataIndex, symbolEl);

    symbolEl.__oldX = symbolEl.x;
    symbolEl.__oldY = symbolEl.y;

    graphic.updateProps(symbolEl, {
        x: targetLayout.x,
        y: targetLayout.y
    }, seriesModel);

    const symbolPath = symbolEl.getSymbolPath();

    if (seriesModel.get('layout') === 'radial') {
        const realRoot = virtualRoot.children[0];
        const rootLayout = realRoot.getLayout();
        const length = realRoot.children.length;
        let rad;
        let isLeft;

        if (targetLayout.x === rootLayout.x && node.isExpand === true) {
            const center = {
                x: (realRoot.children[0].getLayout().x + realRoot.children[length - 1].getLayout().x) / 2,
                y: (realRoot.children[0].getLayout().y + realRoot.children[length - 1].getLayout().y) / 2
            };
            rad = Math.atan2(center.y - rootLayout.y, center.x - rootLayout.x);
            if (rad < 0) {
                rad = Math.PI * 2 + rad;
            }
            isLeft = center.x < rootLayout.x;
            if (isLeft) {
                rad = rad - Math.PI;
            }
        }
        else {
            rad = Math.atan2(targetLayout.y - rootLayout.y, targetLayout.x - rootLayout.x);
            if (rad < 0) {
                rad = Math.PI * 2 + rad;
            }
            if (node.children.length === 0 || (node.children.length !== 0 && node.isExpand === false)) {
                isLeft = targetLayout.x < rootLayout.x;
                if (isLeft) {
                    rad = rad - Math.PI;
                }
            }
            else {
                isLeft = targetLayout.x > rootLayout.x;
                if (!isLeft) {
                    rad = rad - Math.PI;
                }
            }
        }

        const textPosition = isLeft ? 'left' as const : 'right' as const;
        const normalLabelModel = itemModel.getModel('label');
        const rotate = normalLabelModel.get('rotate');
        const labelRotateRadian = rotate * (Math.PI / 180);

        const textContent = symbolPath.getTextContent();
        if (textContent) {
            symbolPath.setTextConfig({
                position: normalLabelModel.get('position') || textPosition,
                rotation: rotate == null ? -rad : labelRotateRadian,
                origin: 'center'
            });
            textContent.setStyle('verticalAlign', 'middle');
        }

    }

    // Handle status
    const focus = itemModel.get(['emphasis', 'focus']);
    const focusDataIndices: number[] = focus === 'ancestor'
        ? node.getAncestorsIndices()
        : focus === 'descendant' ? node.getDescendantIndices() : null;

    if (focusDataIndices) {
        // Modify the focus to data indices.
        getECData(symbolEl).focus = focusDataIndices;
    }

    drawEdge(
        seriesModel, node, virtualRoot, symbolEl, sourceOldLayout,
        sourceLayout, targetLayout, group
    );

    if (symbolEl.__edge) {
        (symbolEl as ECElement).onHoverStateChange = function (toState) {
            if (toState !== 'blur') {
                // NOTE: Ensure the parent elements will been blurred firstly.
                // According to the return of getAncestorsIndices and getDescendantIndices
                // TODO: A bit tricky.
                const parentEl = node.parentNode
                    && data.getItemGraphicEl(node.parentNode.dataIndex);
                if (!(parentEl && (parentEl as ECElement).hoverState === HOVER_STATE_BLUR)) {
                    setStatesFlag(symbolEl.__edge, toState);
                }
            }
        };
    }
}

function drawEdge(
    seriesModel: TreeSeriesModel,
    node: TreeNode,
    virtualRoot: TreeNode,
    symbolEl: TreeSymbol,
    sourceOldLayout: TreeNodeLayout,
    sourceLayout: TreeNodeLayout,
    targetLayout: TreeNodeLayout,
    group: graphic.Group
) {
    const itemModel = node.getModel<TreeSeriesNodeItemOption>();
    const edgeShape = seriesModel.get('edgeShape');
    const layout = seriesModel.get('layout');
    const orient = seriesModel.getOrient();
    const curvature = seriesModel.get(['lineStyle', 'curveness']);
    const edgeForkPosition = seriesModel.get('edgeForkPosition');
    const lineStyle = itemModel.getModel('lineStyle').getLineStyle();
    let edge = symbolEl.__edge;
    if (edgeShape === 'curve') {
        if (node.parentNode && node.parentNode !== virtualRoot) {
            if (!edge) {
                edge = symbolEl.__edge = new graphic.BezierCurve({
                    shape: getEdgeShape(layout, orient, curvature, sourceOldLayout, sourceOldLayout)
                });
            }

            graphic.updateProps(edge as Path, {
                shape: getEdgeShape(layout, orient, curvature, sourceLayout, targetLayout)
            }, seriesModel);
        }
    }
    else if (edgeShape === 'polyline') {
        if (layout === 'orthogonal') {
            if (node !== virtualRoot && node.children && (node.children.length !== 0) && (node.isExpand === true)) {
                const children = node.children;
                const childPoints = [];
                for (let i = 0; i < children.length; i++) {
                    const childLayout = children[i].getLayout();
                    childPoints.push([childLayout.x, childLayout.y]);
                }

                if (!edge) {
                    edge = symbolEl.__edge = new TreePath({
                        shape: {
                            parentPoint: [targetLayout.x, targetLayout.y],
                            childPoints: [[targetLayout.x, targetLayout.y]],
                            orient: orient,
                            forkPosition: edgeForkPosition
                        }
                    });
                }
                graphic.updateProps(edge as Path, {
                    shape: {
                        parentPoint: [targetLayout.x, targetLayout.y],
                        childPoints: childPoints
                    }
                }, seriesModel);
            }
        }
        else {
            if (__DEV__) {
                throw new Error('The polyline edgeShape can only be used in orthogonal layout');
            }
        }
    }

    if (edge) {
        edge.useStyle(zrUtil.defaults({
            strokeNoScale: true, fill: null
        }, lineStyle));

        setStatesStylesFromModel(edge, itemModel, 'lineStyle');
        setDefaultStateProxy(edge);

        group.add(edge);
    }
}

function removeNode(
    data: List,
    dataIndex: number,
    symbolEl: TreeSymbol,
    group: graphic.Group,
    seriesModel: TreeSeriesModel
) {
    const node = data.tree.getNodeByDataIndex(dataIndex);
    const virtualRoot = data.tree.root;

    let source = node.parentNode === virtualRoot ? node : node.parentNode || node;
    // let edgeShape = seriesScope.edgeShape;
    let sourceLayout;
    while (sourceLayout = source.getLayout(), sourceLayout == null) {
        source = source.parentNode === virtualRoot ? source : source.parentNode || source;
    }

    // Use same duration and easing with update to have more consistent animation.
    const removeAnimationOpt = {
        duration: seriesModel.get('animationDurationUpdate') as number,
        easing: seriesModel.get('animationEasingUpdate')
    };

    graphic.removeElement(symbolEl, {
        x: sourceLayout.x + 1,
        y: sourceLayout.y + 1
    }, seriesModel, {
        cb() {
            group.remove(symbolEl);
            data.setItemGraphicEl(dataIndex, null);
        },
        removeOpt: removeAnimationOpt
    });

    symbolEl.fadeOut(null, {
        fadeLabel: true,
        animation: removeAnimationOpt
    });

    const sourceSymbolEl = data.getItemGraphicEl(source.dataIndex) as TreeSymbol;
    const sourceEdge = sourceSymbolEl.__edge;

    // 1. when expand the sub tree, delete the children node should delete the edge of
    // the source at the same time. because the polyline edge shape is only owned by the source.
    // 2.when the node is the only children of the source, delete the node should delete the edge of
    // the source at the same time. the same reason as above.
    const edge = symbolEl.__edge
        || ((source.isExpand === false || source.children.length === 1) ? sourceEdge : undefined);

    const edgeShape = seriesModel.get('edgeShape');
    const layoutOpt = seriesModel.get('layout');
    const orient = seriesModel.get('orient');
    const curvature = seriesModel.get(['lineStyle', 'curveness']);

    if (edge) {
        if (edgeShape === 'curve') {
            graphic.removeElement(edge as Path, {
                shape: getEdgeShape(
                    layoutOpt,
                    orient,
                    curvature,
                    sourceLayout,
                    sourceLayout
                ),
                style: {
                    opacity: 0
                }
            }, seriesModel, {
                cb() {
                    group.remove(edge);
                },
                removeOpt: removeAnimationOpt
            });
        }
        else if (edgeShape === 'polyline' && seriesModel.get('layout') === 'orthogonal') {
            graphic.removeElement(edge as Path, {
                shape: {
                    parentPoint: [sourceLayout.x, sourceLayout.y],
                    childPoints: [[sourceLayout.x, sourceLayout.y]]
                },
                style: {
                    opacity: 0
                }
            }, seriesModel, {
                cb() {
                    group.remove(edge);
                },
                removeOpt: removeAnimationOpt
            });
        }
    }
}

function getEdgeShape(
    layoutOpt: TreeSeriesOption['layout'],
    orient: TreeSeriesOption['orient'],
    curvature: number,
    sourceLayout: TreeNodeLayout,
    targetLayout: TreeNodeLayout
) {
    let cpx1: number;
    let cpy1: number;
    let cpx2: number;
    let cpy2: number;
    let x1: number;
    let x2: number;
    let y1: number;
    let y2: number;

    if (layoutOpt === 'radial') {
        x1 = sourceLayout.rawX;
        y1 = sourceLayout.rawY;
        x2 = targetLayout.rawX;
        y2 = targetLayout.rawY;

        const radialCoor1 = radialCoordinate(x1, y1);
        const radialCoor2 = radialCoordinate(x1, y1 + (y2 - y1) * curvature);
        const radialCoor3 = radialCoordinate(x2, y2 + (y1 - y2) * curvature);
        const radialCoor4 = radialCoordinate(x2, y2);

        return {
            x1: radialCoor1.x || 0,
            y1: radialCoor1.y || 0,
            x2: radialCoor4.x || 0,
            y2: radialCoor4.y || 0,
            cpx1: radialCoor2.x || 0,
            cpy1: radialCoor2.y || 0,
            cpx2: radialCoor3.x || 0,
            cpy2: radialCoor3.y || 0
        };
    }
    else {
        x1 = sourceLayout.x;
        y1 = sourceLayout.y;
        x2 = targetLayout.x;
        y2 = targetLayout.y;

        if (orient === 'LR' || orient === 'RL') {
            cpx1 = x1 + (x2 - x1) * curvature;
            cpy1 = y1;
            cpx2 = x2 + (x1 - x2) * curvature;
            cpy2 = y2;
        }
        if (orient === 'TB' || orient === 'BT') {
            cpx1 = x1;
            cpy1 = y1 + (y2 - y1) * curvature;
            cpx2 = x2;
            cpy2 = y2 + (y1 - y2) * curvature;
        }
    }

    return {
        x1: x1,
        y1: y1,
        x2: x2,
        y2: y2,
        cpx1: cpx1,
        cpy1: cpy1,
        cpx2: cpx2,
        cpy2: cpy2
    };
}

export default TreeView;