/*
* 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 graphic from '../../util/graphic';
import { setStatesStylesFromModel, toggleHoverEmphasis } from '../../util/states';
import * as zrUtil from 'zrender/src/core/util';
import * as symbolUtil from '../../util/symbol';
import ChartView from '../../view/Chart';
import RadarSeriesModel, { RadarSeriesDataItemOption } from './RadarSeries';
import ExtensionAPI from '../../core/ExtensionAPI';
import SeriesData from '../../data/SeriesData';
import { ColorString } from '../../util/types';
import GlobalModel from '../../model/Global';
import { VectorArray } from 'zrender/src/core/vector';
import { setLabelStyle, getLabelStatesModels } from '../../label/labelStyle';
import ZRImage from 'zrender/src/graphic/Image';
import { saveOldStyle } from '../../animation/basicTransition';

type RadarSymbol = ReturnType<typeof symbolUtil.createSymbol> & {
    __dimIdx: number
};

class RadarView extends ChartView {
    static type = 'radar';
    type = RadarView.type;

    private _data: SeriesData<RadarSeriesModel>;

    render(seriesModel: RadarSeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
        const polar = seriesModel.coordinateSystem;
        const group = this.group;

        const data = seriesModel.getData();
        const oldData = this._data;

        function createSymbol(data: SeriesData<RadarSeriesModel>, idx: number) {
            const symbolType = data.getItemVisual(idx, 'symbol') as string || 'circle';
            if (symbolType === 'none') {
                return;
            }
            const symbolSize = symbolUtil.normalizeSymbolSize(
                data.getItemVisual(idx, 'symbolSize')
            );
            const symbolPath = symbolUtil.createSymbol(
                symbolType, -1, -1, 2, 2
            );
            const symbolRotate = data.getItemVisual(idx, 'symbolRotate') || 0;
            symbolPath.attr({
                style: {
                    strokeNoScale: true
                },
                z2: 100,
                scaleX: symbolSize[0] / 2,
                scaleY: symbolSize[1] / 2,
                rotation: symbolRotate * Math.PI / 180 || 0
            });
            return symbolPath as RadarSymbol;
        }

        function updateSymbols(
            oldPoints: VectorArray[],
            newPoints: VectorArray[],
            symbolGroup: graphic.Group,
            data: SeriesData<RadarSeriesModel>,
            idx: number,
            isInit?: boolean
        ) {
            // Simply rerender all
            symbolGroup.removeAll();
            for (let i = 0; i < newPoints.length - 1; i++) {
                const symbolPath = createSymbol(data, idx);
                if (symbolPath) {
                    symbolPath.__dimIdx = i;
                    if (oldPoints[i]) {
                        symbolPath.setPosition(oldPoints[i]);
                        graphic[isInit ? 'initProps' : 'updateProps'](
                            symbolPath, {
                                x: newPoints[i][0],
                                y: newPoints[i][1]
                            }, seriesModel, idx
                        );
                    }
                    else {
                        symbolPath.setPosition(newPoints[i]);
                    }
                    symbolGroup.add(symbolPath);
                }
            }
        }

        function getInitialPoints(points: number[][]) {
            return zrUtil.map(points, function (pt) {
                return [polar.cx, polar.cy];
            });
        }
        data.diff(oldData)
            .add(function (idx) {
                const points = data.getItemLayout(idx);
                if (!points) {
                    return;
                }
                const polygon = new graphic.Polygon();
                const polyline = new graphic.Polyline();
                const target = {
                    shape: {
                        points: points
                    }
                };

                polygon.shape.points = getInitialPoints(points);
                polyline.shape.points = getInitialPoints(points);
                graphic.initProps(polygon, target, seriesModel, idx);
                graphic.initProps(polyline, target, seriesModel, idx);

                const itemGroup = new graphic.Group();
                const symbolGroup = new graphic.Group();
                itemGroup.add(polyline);
                itemGroup.add(polygon);
                itemGroup.add(symbolGroup);

                updateSymbols(
                    polyline.shape.points, points, symbolGroup, data, idx, true
                );

                data.setItemGraphicEl(idx, itemGroup);
            })
            .update(function (newIdx, oldIdx) {
                const itemGroup = oldData.getItemGraphicEl(oldIdx) as graphic.Group;

                const polyline = itemGroup.childAt(0) as graphic.Polyline;
                const polygon = itemGroup.childAt(1) as graphic.Polygon;
                const symbolGroup = itemGroup.childAt(2) as graphic.Group;
                const target = {
                    shape: {
                        points: data.getItemLayout(newIdx)
                    }
                };

                if (!target.shape.points) {
                    return;
                }
                updateSymbols(
                    polyline.shape.points,
                    target.shape.points,
                    symbolGroup,
                    data,
                    newIdx,
                    false
                );

                saveOldStyle(polygon);
                saveOldStyle(polyline);

                graphic.updateProps(polyline, target, seriesModel);
                graphic.updateProps(polygon, target, seriesModel);

                data.setItemGraphicEl(newIdx, itemGroup);
            })
            .remove(function (idx) {
                group.remove(oldData.getItemGraphicEl(idx));
            })
            .execute();

        data.eachItemGraphicEl(function (itemGroup: graphic.Group, idx) {
            const itemModel = data.getItemModel<RadarSeriesDataItemOption>(idx);
            const polyline = itemGroup.childAt(0) as graphic.Polyline;
            const polygon = itemGroup.childAt(1) as graphic.Polygon;
            const symbolGroup = itemGroup.childAt(2) as graphic.Group;
            // Radar uses the visual encoded from itemStyle.
            const itemStyle = data.getItemVisual(idx, 'style');
            const color = itemStyle.fill;

            group.add(itemGroup);

            polyline.useStyle(
                zrUtil.defaults(
                    itemModel.getModel('lineStyle').getLineStyle(),
                    {
                        fill: 'none',
                        stroke: color
                    }
                )
            );

            setStatesStylesFromModel(polyline, itemModel, 'lineStyle');
            setStatesStylesFromModel(polygon, itemModel, 'areaStyle');

            const areaStyleModel = itemModel.getModel('areaStyle');
            const polygonIgnore = areaStyleModel.isEmpty() && areaStyleModel.parentModel.isEmpty();

            polygon.ignore = polygonIgnore;

            zrUtil.each(['emphasis', 'select', 'blur'] as const, function (stateName) {
                const stateModel = itemModel.getModel([stateName, 'areaStyle']);
                const stateIgnore = stateModel.isEmpty() && stateModel.parentModel.isEmpty();
                // Won't be ignore if normal state is not ignore.
                polygon.ensureState(stateName).ignore = stateIgnore && polygonIgnore;
            });

            polygon.useStyle(
                zrUtil.defaults(
                    areaStyleModel.getAreaStyle(),
                    {
                        fill: color,
                        opacity: 0.7,
                        decal: itemStyle.decal
                    }
                )
            );
            const emphasisModel = itemModel.getModel('emphasis');
            const itemHoverStyle = emphasisModel.getModel('itemStyle').getItemStyle();
            symbolGroup.eachChild(function (symbolPath: RadarSymbol) {
                if (symbolPath instanceof ZRImage) {
                    const pathStyle = symbolPath.style;
                    symbolPath.useStyle(zrUtil.extend({
                        // TODO other properties like x, y ?
                        image: pathStyle.image,
                        x: pathStyle.x, y: pathStyle.y,
                        width: pathStyle.width, height: pathStyle.height
                    }, itemStyle));
                }
                else {
                    symbolPath.useStyle(itemStyle);
                    symbolPath.setColor(color);
                    symbolPath.style.strokeNoScale = true;
                }

                const pathEmphasisState = symbolPath.ensureState('emphasis');
                pathEmphasisState.style = zrUtil.clone(itemHoverStyle);
                let defaultText = data.getStore().get(data.getDimensionIndex(symbolPath.__dimIdx), idx);
                (defaultText == null || isNaN(defaultText as number)) && (defaultText = '');

                setLabelStyle(
                    symbolPath, getLabelStatesModels(itemModel),
                    {
                        labelFetcher: data.hostModel,
                        labelDataIndex: idx,
                        labelDimIndex: symbolPath.__dimIdx,
                        defaultText: defaultText as string,
                        inheritColor: color as ColorString,
                        defaultOpacity: itemStyle.opacity
                    }
                );
            });

            toggleHoverEmphasis(
                itemGroup, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled')
            );
        });

        this._data = data;
    }

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

export default RadarView;
