/*
* 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 createSeriesDataSimply from '../helper/createSeriesDataSimply';
import {defaultEmphasis} from '../../util/model';
import {makeSeriesEncodeForNameBased} from '../../data/helper/sourceHelper';
import LegendVisualProvider from '../../visual/LegendVisualProvider';
import SeriesModel from '../../model/Series';
import {
    SeriesOption,
    BoxLayoutOptionMixin,
    HorizontalAlign,
    LabelOption,
    LabelLineOption,
    ItemStyleOption,
    OptionDataValueNumeric,
    StatesOptionMixin,
    OptionDataItemObject,
    LayoutOrient,
    VerticalAlign,
    SeriesLabelOption,
    SeriesEncodeOptionMixin,
    DefaultStatesMixinEmphasis,
    CallbackDataParams
} from '../../util/types';
import GlobalModel from '../../model/Global';
import SeriesData from '../../data/SeriesData';

type FunnelLabelOption = Omit<SeriesLabelOption, 'position'> & {
    position?: LabelOption['position']
        | 'outer' | 'inner' | 'center' | 'rightTop' | 'rightBottom' | 'leftTop' | 'leftBottom'
};

interface FunnelStatesMixin {
    emphasis?: DefaultStatesMixinEmphasis
}

export interface FunnelCallbackDataParams extends CallbackDataParams {
    percent: number
}
export interface FunnelStateOption<TCbParams = never> {
    itemStyle?: ItemStyleOption<TCbParams>
    label?: FunnelLabelOption
    labelLine?: LabelLineOption
}

export interface FunnelDataItemOption
    extends FunnelStateOption, StatesOptionMixin<FunnelStateOption, FunnelStatesMixin>,
    OptionDataItemObject<OptionDataValueNumeric> {

    itemStyle?: ItemStyleOption & {
        width?: number | string
        height?: number | string
    }
}

export interface FunnelSeriesOption
    extends SeriesOption<FunnelStateOption<FunnelCallbackDataParams>, FunnelStatesMixin>,
    FunnelStateOption<FunnelCallbackDataParams>,
    BoxLayoutOptionMixin, SeriesEncodeOptionMixin {
    type?: 'funnel'

    min?: number
    max?: number

    /**
     * Absolute number or percent string
     */
    minSize?: number | string
    maxSize?: number | string

    sort?: 'ascending' | 'descending' | 'none'

    orient?: LayoutOrient

    gap?: number

    funnelAlign?: HorizontalAlign | VerticalAlign

    data?: (OptionDataValueNumeric | OptionDataValueNumeric[] | FunnelDataItemOption)[]
}

class FunnelSeriesModel extends SeriesModel<FunnelSeriesOption> {
    static type = 'series.funnel' as const;
    type = FunnelSeriesModel.type;

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

        // Enable legend selection for each data item
        // Use a function instead of direct access because data reference may changed
        this.legendVisualProvider = new LegendVisualProvider(
            zrUtil.bind(this.getData, this), zrUtil.bind(this.getRawData, this)
        );
        // Extend labelLine emphasis
        this._defaultLabelLine(option);
    }

    getInitialData(this: FunnelSeriesModel, option: FunnelSeriesOption, ecModel: GlobalModel): SeriesData {
        return createSeriesDataSimply(this, {
            coordDimensions: ['value'],
            encodeDefaulter: zrUtil.curry(makeSeriesEncodeForNameBased, this)
        });
    }

    _defaultLabelLine(option: FunnelSeriesOption) {
        // Extend labelLine emphasis
        defaultEmphasis(option, 'labelLine', ['show']);

        const labelLineNormalOpt = option.labelLine;
        const labelLineEmphasisOpt = option.emphasis.labelLine;
        // Not show label line if `label.normal.show = false`
        labelLineNormalOpt.show = labelLineNormalOpt.show
            && option.label.show;
        labelLineEmphasisOpt.show = labelLineEmphasisOpt.show
            && option.emphasis.label.show;
    }

    // Overwrite
    getDataParams(dataIndex: number): FunnelCallbackDataParams {
        const data = this.getData();
        const params = super.getDataParams(dataIndex) as FunnelCallbackDataParams;
        const valueDim = data.mapDimension('value');
        const sum = data.getSum(valueDim);
        // Percent is 0 if sum is 0
        params.percent = !sum ? 0 : +(data.get(valueDim, dataIndex) as number / sum * 100).toFixed(2);

        params.$vars.push('percent');
        return params;
    }

    static defaultOption: FunnelSeriesOption = {
        // zlevel: 0,                  // 一级层叠
        z: 2,                       // 二级层叠
        legendHoverLink: true,
        colorBy: 'data',
        left: 80,
        top: 60,
        right: 80,
        bottom: 60,
        // width: {totalWidth} - left - right,
        // height: {totalHeight} - top - bottom,

        // 默认取数据最小最大值
        // min: 0,
        // max: 100,
        minSize: '0%',
        maxSize: '100%',
        sort: 'descending', // 'ascending', 'descending'
        orient: 'vertical',
        gap: 0,
        funnelAlign: 'center',
        label: {
            show: true,
            position: 'outer'
            // formatter: 标签文本格式器，同Tooltip.formatter，不支持异步回调
        },
        labelLine: {
            show: true,
            length: 20,
            lineStyle: {
                // color: 各异,
                width: 1
            }
        },
        itemStyle: {
            // color: 各异,
            borderColor: '#fff',
            borderWidth: 1
        },
        emphasis: {
            label: {
                show: true
            }
        },
        select: {
            itemStyle: {
                borderColor: '#212121'
            }
        }
    };

}

export default FunnelSeriesModel;
