/*
* 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 SeriesData from '../../data/SeriesData';
import * as zrUtil from 'zrender/src/core/util';
import {defaultEmphasis} from '../../util/model';
import Model from '../../model/Model';
import createGraphFromNodeEdge from '../helper/createGraphFromNodeEdge';
import LegendVisualProvider from '../../visual/LegendVisualProvider';
import {
    SeriesOption,
    SeriesOnCartesianOptionMixin,
    SeriesOnPolarOptionMixin,
    SeriesOnCalendarOptionMixin,
    SeriesOnGeoOptionMixin,
    SeriesOnSingleOptionMixin,
    OptionDataValue,
    RoamOptionMixin,
    SeriesLabelOption,
    ItemStyleOption,
    LineStyleOption,
    SymbolOptionMixin,
    BoxLayoutOptionMixin,
    Dictionary,
    SeriesLineLabelOption,
    StatesOptionMixin,
    GraphEdgeItemObject,
    OptionDataValueNumeric,
    CallbackDataParams,
    DefaultEmphasisFocus
} from '../../util/types';
import SeriesModel from '../../model/Series';
import Graph from '../../data/Graph';
import GlobalModel from '../../model/Global';
import { VectorArray } from 'zrender/src/core/vector';
import { ForceLayoutInstance } from './forceLayout';
import { LineDataVisual } from '../../visual/commonVisualTypes';
import { createTooltipMarkup } from '../../component/tooltip/tooltipMarkup';
import { defaultSeriesFormatTooltip } from '../../component/tooltip/seriesFormatTooltip';
import {initCurvenessList, createEdgeMapForCurveness} from '../helper/multipleGraphEdgeHelper';


type GraphDataValue = OptionDataValue | OptionDataValue[];

interface GraphEdgeLineStyleOption extends LineStyleOption {
    curveness?: number
}

export interface GraphNodeStateOption<TCbParams = never> {
    itemStyle?: ItemStyleOption<TCbParams>
    label?: SeriesLabelOption
}


interface ExtraEmphasisState {
    focus?: DefaultEmphasisFocus | 'adjacency'
}
interface GraphNodeStatesMixin {
    emphasis?: ExtraEmphasisState
}

interface GraphEdgeStatesMixin {
    emphasis?: ExtraEmphasisState
}

export interface GraphNodeItemOption extends SymbolOptionMixin, GraphNodeStateOption,
    GraphNodeStateOption, StatesOptionMixin<GraphNodeStateOption, GraphNodeStatesMixin> {

    id?: string
    name?: string
    value?: GraphDataValue

    /**
     * Fixed x position
     */
    x?: number
    /**
     * Fixed y position
     */
    y?: number

    /**
     * If this node is fixed during force layout.
     */
    fixed?: boolean

    /**
     * Index or name of category
     */
    category?: number | string

    draggable?: boolean
    cursor?: string
}

export interface GraphEdgeStateOption {
    lineStyle?: GraphEdgeLineStyleOption
    label?: SeriesLineLabelOption
}
export interface GraphEdgeItemOption extends
        GraphEdgeStateOption,
        StatesOptionMixin<GraphEdgeStateOption, GraphEdgeStatesMixin>,
        GraphEdgeItemObject<OptionDataValueNumeric> {

    value?: number

    /**
     * Symbol of both line ends
     */
    symbol?: string | string[]

    symbolSize?: number | number[]

    ignoreForceLayout?: boolean
}

export interface GraphCategoryItemOption extends SymbolOptionMixin,
    GraphNodeStateOption, StatesOptionMixin<GraphNodeStateOption, GraphNodeStatesMixin> {
    name?: string

    value?: OptionDataValue
}

export interface GraphSeriesOption
    extends SeriesOption<GraphNodeStateOption<CallbackDataParams>, GraphNodeStatesMixin>,
    SeriesOnCartesianOptionMixin, SeriesOnPolarOptionMixin, SeriesOnCalendarOptionMixin,
    SeriesOnGeoOptionMixin, SeriesOnSingleOptionMixin,
    SymbolOptionMixin<CallbackDataParams>,
    RoamOptionMixin,
    BoxLayoutOptionMixin {

    type?: 'graph'

    coordinateSystem?: string

    legendHoverLink?: boolean

    layout?: 'none' | 'force' | 'circular'

    data?: (GraphNodeItemOption | GraphDataValue)[]
    nodes?: (GraphNodeItemOption | GraphDataValue)[]

    edges?: GraphEdgeItemOption[]
    links?: GraphEdgeItemOption[]

    categories?: GraphCategoryItemOption[]

    /**
     * @deprecated
     */
    focusNodeAdjacency?: boolean

    /**
     * Symbol size scale ratio in roam
     */
    nodeScaleRatio?: 0.6,

    draggable?: boolean

    edgeSymbol?: string | string[]
    edgeSymbolSize?: number | number[]

    edgeLabel?: SeriesLineLabelOption
    label?: SeriesLabelOption

    itemStyle?: ItemStyleOption<CallbackDataParams>
    lineStyle?: GraphEdgeLineStyleOption

    emphasis?: {
        focus?: Exclude<GraphNodeItemOption['emphasis'], undefined>['focus']
        scale?: boolean | number
        label?: SeriesLabelOption
        edgeLabel?: SeriesLabelOption
        itemStyle?: ItemStyleOption
        lineStyle?: LineStyleOption
    }

    blur?: {
        label?: SeriesLabelOption
        edgeLabel?: SeriesLabelOption
        itemStyle?: ItemStyleOption
        lineStyle?: LineStyleOption
    }

    select?: {
        label?: SeriesLabelOption
        edgeLabel?: SeriesLabelOption
        itemStyle?: ItemStyleOption
        lineStyle?: LineStyleOption
    }

    // Configuration of circular layout
    circular?: {
        rotateLabel?: boolean
    }

    // Configuration of force directed layout
    force?: {
        initLayout?: 'circular' | 'none'
        // Node repulsion. Can be an array to represent range.
        repulsion?: number | number[]
        gravity?: number
        // Initial friction
        friction?: number

        // Edge length. Can be an array to represent range.
        edgeLength?: number | number[]

        layoutAnimation?: boolean
    }

    /**
     * auto curveness for multiple edge, invalid when `lineStyle.curveness` is set
     */
    autoCurveness?: boolean | number | number[]
}

class GraphSeriesModel extends SeriesModel<GraphSeriesOption> {
    static readonly type = 'series.graph';
    readonly type = GraphSeriesModel.type;

    static readonly dependencies = ['grid', 'polar', 'geo', 'singleAxis', 'calendar'];

    private _categoriesData: SeriesData;
    private _categoriesModels: Model<GraphCategoryItemOption>[];

    /**
     * Preserved points during layouting
     */
    preservedPoints?: Dictionary<VectorArray>;

    forceLayout?: ForceLayoutInstance;

    hasSymbolVisual = true;

    init(option: GraphSeriesOption) {
        super.init.apply(this, arguments as any);

        const self = this;
        function getCategoriesData() {
            return self._categoriesData;
        }
        // Provide data for legend select
        this.legendVisualProvider = new LegendVisualProvider(
            getCategoriesData, getCategoriesData
        );

        this.fillDataTextStyle(option.edges || option.links);

        this._updateCategoriesData();
    }

    mergeOption(option: GraphSeriesOption) {
        super.mergeOption.apply(this, arguments as any);

        this.fillDataTextStyle(option.edges || option.links);

        this._updateCategoriesData();
    }

    mergeDefaultAndTheme(option: GraphSeriesOption) {
        super.mergeDefaultAndTheme.apply(this, arguments as any);
        defaultEmphasis(option, 'edgeLabel', ['show']);
    }

    getInitialData(option: GraphSeriesOption, ecModel: GlobalModel): SeriesData {
        const edges = option.edges || option.links || [];
        const nodes = option.data || option.nodes || [];
        const self = this;

        if (nodes && edges) {
            // auto curveness
            initCurvenessList(this);
            const graph = createGraphFromNodeEdge(nodes as GraphNodeItemOption[], edges, this, true, beforeLink);
            zrUtil.each(graph.edges, function (edge) {
                createEdgeMapForCurveness(edge.node1, edge.node2, this, edge.dataIndex);
            }, this);
            return graph.data;
        }

        function beforeLink(nodeData: SeriesData, edgeData: SeriesData) {
            // Overwrite nodeData.getItemModel to
            nodeData.wrapMethod('getItemModel', function (model) {
                const categoriesModels = self._categoriesModels;
                const categoryIdx = model.getShallow('category');
                const categoryModel = categoriesModels[categoryIdx];
                if (categoryModel) {
                    categoryModel.parentModel = model.parentModel;
                    model.parentModel = categoryModel;
                }
                return model;
            });

            // TODO Inherit resolveParentPath by default in Model#getModel?
            const oldGetModel = Model.prototype.getModel;
            function newGetModel(this: Model, path: any, parentModel?: Model) {
                const model = oldGetModel.call(this, path, parentModel);
                model.resolveParentPath = resolveParentPath;
                return model;
            }

            edgeData.wrapMethod('getItemModel', function (model: Model) {
                model.resolveParentPath = resolveParentPath;
                model.getModel = newGetModel;
                return model;
            });

            function resolveParentPath(this: Model, pathArr: readonly string[]): string[] {
                if (pathArr && (pathArr[0] === 'label' || pathArr[1] === 'label')) {
                    const newPathArr = pathArr.slice();
                    if (pathArr[0] === 'label') {
                        newPathArr[0] = 'edgeLabel';
                    }
                    else if (pathArr[1] === 'label') {
                        newPathArr[1] = 'edgeLabel';
                    }
                    return newPathArr;
                }
                return pathArr as string[];
            }
        }
    }

    getGraph(): Graph {
        return this.getData().graph;
    }

    getEdgeData() {
        return this.getGraph().edgeData as SeriesData<GraphSeriesModel, LineDataVisual>;
    }

    getCategoriesData(): SeriesData {
        return this._categoriesData;
    }

    formatTooltip(
        dataIndex: number,
        multipleSeries: boolean,
        dataType: string
    ) {
        if (dataType === 'edge') {
            const nodeData = this.getData();
            const params = this.getDataParams(dataIndex, dataType);
            const edge = nodeData.graph.getEdgeByIndex(dataIndex);
            const sourceName = nodeData.getName(edge.node1.dataIndex);
            const targetName = nodeData.getName(edge.node2.dataIndex);

            const nameArr = [];
            sourceName != null && nameArr.push(sourceName);
            targetName != null && nameArr.push(targetName);

            return createTooltipMarkup('nameValue', {
                name: nameArr.join(' > '),
                value: params.value,
                noValue: params.value == null
            });
        }
        // dataType === 'node' or empty
        const nodeMarkup = defaultSeriesFormatTooltip({
            series: this,
            dataIndex: dataIndex,
            multipleSeries: multipleSeries
        });
        return nodeMarkup;
    }

    _updateCategoriesData() {
        const categories = zrUtil.map(this.option.categories || [], function (category) {
            // Data must has value
            return category.value != null ? category : zrUtil.extend({
                value: 0
            }, category);
        });
        const categoriesData = new SeriesData(['value'], this);
        categoriesData.initData(categories);

        this._categoriesData = categoriesData;

        this._categoriesModels = categoriesData.mapArray(function (idx) {
            return categoriesData.getItemModel(idx);
        });
    }

    setZoom(zoom: number) {
        this.option.zoom = zoom;
    }

    setCenter(center: number[]) {
        this.option.center = center;
    }

    isAnimationEnabled() {
        return super.isAnimationEnabled()
            // Not enable animation when do force layout
            && !(this.get('layout') === 'force' && this.get(['force', 'layoutAnimation']));
    }

    static defaultOption: GraphSeriesOption = {
        // zlevel: 0,
        z: 2,

        coordinateSystem: 'view',

        // Default option for all coordinate systems
        // xAxisIndex: 0,
        // yAxisIndex: 0,
        // polarIndex: 0,
        // geoIndex: 0,

        legendHoverLink: true,

        layout: null,

        // Configuration of circular layout
        circular: {
            rotateLabel: false
        },
        // Configuration of force directed layout
        force: {
            initLayout: null,
            // Node repulsion. Can be an array to represent range.
            repulsion: [0, 50],
            gravity: 0.1,
            // Initial friction
            friction: 0.6,

            // Edge length. Can be an array to represent range.
            edgeLength: 30,

            layoutAnimation: true
        },

        left: 'center',
        top: 'center',
        // right: null,
        // bottom: null,
        // width: '80%',
        // height: '80%',

        symbol: 'circle',
        symbolSize: 10,

        edgeSymbol: ['none', 'none'],
        edgeSymbolSize: 10,
        edgeLabel: {
            position: 'middle',
            distance: 5
        },

        draggable: false,

        roam: false,

        // Default on center of graph
        center: null,

        zoom: 1,
        // Symbol size scale ratio in roam
        nodeScaleRatio: 0.6,

        // cursor: null,

        // categories: [],

        // data: []
        // Or
        // nodes: []
        //
        // links: []
        // Or
        // edges: []

        label: {
            show: false,
            formatter: '{b}'
        },

        itemStyle: {},

        lineStyle: {
            color: '#aaa',
            width: 1,
            opacity: 0.5
        },
        emphasis: {
            scale: true,
            label: {
                show: true
            }
        },

        select: {
            itemStyle: {
                borderColor: '#212121'
            }
        }
    };
}

export default GraphSeriesModel;
