/*
* 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 {parsePercent} from '../util/number';
import {isDimensionStacked} from '../data/helper/dataStackHelper';
import type BarSeriesModel from '../chart/bar/BarSeries';
import type Polar from '../coord/polar/Polar';
import AngleAxis from '../coord/polar/AngleAxis';
import RadiusAxis from '../coord/polar/RadiusAxis';
import GlobalModel from '../model/Global';
import ExtensionAPI from '../core/ExtensionAPI';
import { Dictionary } from '../util/types';

type PolarAxis = AngleAxis | RadiusAxis;

interface StackInfo {
    width: number
    maxWidth: number
}
interface LayoutColumnInfo {
    autoWidthCount: number
    bandWidth: number
    remainedWidth: number
    categoryGap: string | number
    gap: string | number
    stacks: Dictionary<StackInfo>
}

interface BarWidthAndOffset {
    width: number
    offset: number
}

function getSeriesStackId(seriesModel: BarSeriesModel) {
    return seriesModel.get('stack')
        || '__ec_stack_' + seriesModel.seriesIndex;
}

function getAxisKey(polar: Polar, axis: PolarAxis) {
    return axis.dim + polar.model.componentIndex;
}

function barLayoutPolar(seriesType: string, ecModel: GlobalModel, api: ExtensionAPI) {

    const lastStackCoords: Dictionary<{p: number, n: number}[]> = {};

    const barWidthAndOffset = calRadialBar(
        zrUtil.filter(
            ecModel.getSeriesByType(seriesType) as BarSeriesModel[],
            function (seriesModel) {
                return !ecModel.isSeriesFiltered(seriesModel)
                    && seriesModel.coordinateSystem
                    && seriesModel.coordinateSystem.type === 'polar';
            }
        )
    );

    ecModel.eachSeriesByType(seriesType, function (seriesModel: BarSeriesModel) {

        // Check series coordinate, do layout for polar only
        if (seriesModel.coordinateSystem.type !== 'polar') {
            return;
        }

        const data = seriesModel.getData();
        const polar = seriesModel.coordinateSystem as Polar;
        const baseAxis = polar.getBaseAxis();
        const axisKey = getAxisKey(polar, baseAxis);

        const stackId = getSeriesStackId(seriesModel);
        const columnLayoutInfo = barWidthAndOffset[axisKey][stackId];
        const columnOffset = columnLayoutInfo.offset;
        const columnWidth = columnLayoutInfo.width;
        const valueAxis = polar.getOtherAxis(baseAxis);

        const cx = seriesModel.coordinateSystem.cx;
        const cy = seriesModel.coordinateSystem.cy;

        const barMinHeight = seriesModel.get('barMinHeight') || 0;
        const barMinAngle = seriesModel.get('barMinAngle') || 0;

        lastStackCoords[stackId] = lastStackCoords[stackId] || [];

        const valueDim = data.mapDimension(valueAxis.dim);
        const baseDim = data.mapDimension(baseAxis.dim);
        const stacked = isDimensionStacked(data, valueDim /* , baseDim */);
        const clampLayout = baseAxis.dim !== 'radius'
            || !seriesModel.get('roundCap', true);

        const valueAxisStart = valueAxis.dataToCoord(0);
        for (let idx = 0, len = data.count(); idx < len; idx++) {
            const value = data.get(valueDim, idx) as number;
            const baseValue = data.get(baseDim, idx) as number;

            const sign = value >= 0 ? 'p' : 'n' as 'p' | 'n';
            let baseCoord = valueAxisStart;

            // Because of the barMinHeight, we can not use the value in
            // stackResultDimension directly.
            // Only ordinal axis can be stacked.
            if (stacked) {

                if (!lastStackCoords[stackId][baseValue]) {
                    lastStackCoords[stackId][baseValue] = {
                        p: valueAxisStart, // Positive stack
                        n: valueAxisStart  // Negative stack
                    };
                }
                // Should also consider #4243
                baseCoord = lastStackCoords[stackId][baseValue][sign];
            }

            let r0;
            let r;
            let startAngle;
            let endAngle;

            // radial sector
            if (valueAxis.dim === 'radius') {
                let radiusSpan = valueAxis.dataToCoord(value) - valueAxisStart;
                const angle = baseAxis.dataToCoord(baseValue);

                if (Math.abs(radiusSpan) < barMinHeight) {
                    radiusSpan = (radiusSpan < 0 ? -1 : 1) * barMinHeight;
                }

                r0 = baseCoord;
                r = baseCoord + radiusSpan;
                startAngle = angle - columnOffset;
                endAngle = startAngle - columnWidth;

                stacked && (lastStackCoords[stackId][baseValue][sign] = r);
            }
            // tangential sector
            else {
                let angleSpan = valueAxis.dataToCoord(value, clampLayout) - valueAxisStart;
                const radius = baseAxis.dataToCoord(baseValue);

                if (Math.abs(angleSpan) < barMinAngle) {
                    angleSpan = (angleSpan < 0 ? -1 : 1) * barMinAngle;
                }

                r0 = radius + columnOffset;
                r = r0 + columnWidth;
                startAngle = baseCoord;
                endAngle = baseCoord + angleSpan;

                // if the previous stack is at the end of the ring,
                // add a round to differentiate it from origin
                // let extent = angleAxis.getExtent();
                // let stackCoord = angle;
                // if (stackCoord === extent[0] && value > 0) {
                //     stackCoord = extent[1];
                // }
                // else if (stackCoord === extent[1] && value < 0) {
                //     stackCoord = extent[0];
                // }
                stacked && (lastStackCoords[stackId][baseValue][sign] = endAngle);
            }

            data.setItemLayout(idx, {
                cx: cx,
                cy: cy,
                r0: r0,
                r: r,
                // Consider that positive angle is anti-clockwise,
                // while positive radian of sector is clockwise
                startAngle: -startAngle * Math.PI / 180,
                endAngle: -endAngle * Math.PI / 180,

                /**
                 * Keep the same logic with bar in catesion: use end value to
                 * control direction. Notice that if clockwise is true (by
                 * default), the sector will always draw clockwisely, no matter
                 * whether endAngle is greater or less than startAngle.
                 */
                clockwise: startAngle >= endAngle
            });

        }

    });

}

/**
 * Calculate bar width and offset for radial bar charts
 */
function calRadialBar(barSeries: BarSeriesModel[]) {
    // Columns info on each category axis. Key is polar name
    const columnsMap: Dictionary<LayoutColumnInfo> = {};

    zrUtil.each(barSeries, function (seriesModel, idx) {
        const data = seriesModel.getData();
        const polar = seriesModel.coordinateSystem as Polar;

        const baseAxis = polar.getBaseAxis();
        const axisKey = getAxisKey(polar, baseAxis);

        const axisExtent = baseAxis.getExtent();
        const bandWidth = baseAxis.type === 'category'
            ? baseAxis.getBandWidth()
            : (Math.abs(axisExtent[1] - axisExtent[0]) / data.count());

        const columnsOnAxis = columnsMap[axisKey] || {
            bandWidth: bandWidth,
            remainedWidth: bandWidth,
            autoWidthCount: 0,
            categoryGap: '20%',
            gap: '30%',
            stacks: {}
        };
        const stacks = columnsOnAxis.stacks;
        columnsMap[axisKey] = columnsOnAxis;

        const stackId = getSeriesStackId(seriesModel);

        if (!stacks[stackId]) {
            columnsOnAxis.autoWidthCount++;
        }
        stacks[stackId] = stacks[stackId] || {
            width: 0,
            maxWidth: 0
        };

        let barWidth = parsePercent(
            seriesModel.get('barWidth'),
            bandWidth
        );
        const barMaxWidth = parsePercent(
            seriesModel.get('barMaxWidth'),
            bandWidth
        );
        const barGap = seriesModel.get('barGap');
        const barCategoryGap = seriesModel.get('barCategoryGap');

        if (barWidth && !stacks[stackId].width) {
            barWidth = Math.min(columnsOnAxis.remainedWidth, barWidth);
            stacks[stackId].width = barWidth;
            columnsOnAxis.remainedWidth -= barWidth;
        }

        barMaxWidth && (stacks[stackId].maxWidth = barMaxWidth);
        (barGap != null) && (columnsOnAxis.gap = barGap);
        (barCategoryGap != null) && (columnsOnAxis.categoryGap = barCategoryGap);
    });


    const result: Dictionary<Dictionary<BarWidthAndOffset>> = {};

    zrUtil.each(columnsMap, function (columnsOnAxis, coordSysName) {

        result[coordSysName] = {};

        const stacks = columnsOnAxis.stacks;
        const bandWidth = columnsOnAxis.bandWidth;
        const categoryGap = parsePercent(columnsOnAxis.categoryGap, bandWidth);
        const barGapPercent = parsePercent(columnsOnAxis.gap, 1);

        let remainedWidth = columnsOnAxis.remainedWidth;
        let autoWidthCount = columnsOnAxis.autoWidthCount;
        let autoWidth = (remainedWidth - categoryGap)
            / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
        autoWidth = Math.max(autoWidth, 0);

        // Find if any auto calculated bar exceeded maxBarWidth
        zrUtil.each(stacks, function (column, stack) {
            let maxWidth = column.maxWidth;
            if (maxWidth && maxWidth < autoWidth) {
                maxWidth = Math.min(maxWidth, remainedWidth);
                if (column.width) {
                    maxWidth = Math.min(maxWidth, column.width);
                }
                remainedWidth -= maxWidth;
                column.width = maxWidth;
                autoWidthCount--;
            }
        });

        // Recalculate width again
        autoWidth = (remainedWidth - categoryGap)
            / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
        autoWidth = Math.max(autoWidth, 0);

        let widthSum = 0;
        let lastColumn: StackInfo;
        zrUtil.each(stacks, function (column, idx) {
            if (!column.width) {
                column.width = autoWidth;
            }
            lastColumn = column;
            widthSum += column.width * (1 + barGapPercent);
        });
        if (lastColumn) {
            widthSum -= lastColumn.width * barGapPercent;
        }

        let offset = -widthSum / 2;
        zrUtil.each(stacks, function (column, stackId) {
            result[coordSysName][stackId] = result[coordSysName][stackId] || {
                offset: offset,
                width: column.width
            } as BarWidthAndOffset;

            offset += column.width * (1 + barGapPercent);
        });
    });

    return result;
}

export default barLayoutPolar;