/*
* 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 Model from '../../model/Model';
import {isNameSpecified} from '../../util/model';
import ComponentModel from '../../model/Component';
import {
    ComponentOption,
    BoxLayoutOptionMixin,
    BorderOptionMixin,
    ColorString,
    LabelOption,
    LayoutOrient,
    CommonTooltipOption,
    ItemStyleOption,
    LineStyleOption
} from '../../util/types';
import { Dictionary } from 'zrender/src/core/types';
import GlobalModel from '../../model/Global';
import { ItemStyleProps } from '../../model/mixin/itemStyle';
import { LineStyleProps } from './../../model/mixin/lineStyle';
import {PathStyleProps} from 'zrender/src/graphic/Path';

type LegendDefaultSelectorOptionsProps = {
    type: string;
    title: string;
};
const getDefaultSelectorOptions = function (ecModel: GlobalModel, type: string): LegendDefaultSelectorOptionsProps {
    if (type === 'all') {
        return {
            type: 'all',
            title: ecModel.getLocaleModel().get(['legend', 'selector', 'all'])
        };
    }
    else if (type === 'inverse') {
        return {
            type: 'inverse',
            title: ecModel.getLocaleModel().get(['legend', 'selector', 'inverse'])
        };
    }
};

type SelectorType = 'all' | 'inverse';
export interface LegendSelectorButtonOption {
    type?: SelectorType
    title?: string
}

/**
 * T: the type to be extended
 * ET: extended type for keys of T
 * ST: special type for T to be extended
 */
type ExtendPropertyType<T, ET, ST extends { [key in keyof T]: any }> = {
    [key in keyof T]: key extends keyof ST ? T[key] | ET | ST[key] : T[key] | ET
};

export interface LegendItemStyleOption extends ExtendPropertyType<ItemStyleOption, 'inherit', {
    borderWidth: 'auto'
}> {}

export interface LegendLineStyleOption extends ExtendPropertyType<LineStyleOption, 'inherit', {
    width: 'auto'
}> {
    inactiveColor?: ColorString
    inactiveWidth?: number
}

export interface LegendStyleOption {
    /**
     * Icon of the legend items.
     * @default 'roundRect'
     */
    icon?: string

    /**
     * Color when legend item is not selected
     */
    inactiveColor?: ColorString
    /**
     * Border color when legend item is not selected
     */
    inactiveBorderColor?: ColorString
    /**
     * Border color when legend item is not selected
     */
    inactiveBorderWidth?: number | 'auto'

    /**
     * Legend label formatter
     */
    formatter?: string | ((name: string) => string)

    itemStyle?: LegendItemStyleOption

    lineStyle?: LegendLineStyleOption

    textStyle?: LabelOption

    symbolRotate?: number | 'inherit'

    /**
     * @deprecated
     */
    symbolKeepAspect?: boolean
}

interface DataItem extends LegendStyleOption {
    name?: string
    icon?: string
    textStyle?: LabelOption

    // TODO: TYPE tooltip
    tooltip?: unknown
}

export interface LegendTooltipFormatterParams {
    componentType: 'legend'
    legendIndex: number
    name: string
    $vars: ['name']
}

export interface LegendIconParams {
    itemWidth: number
    itemHeight: number
    /**
     * symbolType is from legend.icon, legend.data.icon, or series visual
     */
    icon: string
    iconRotate: number | 'inherit'
    symbolKeepAspect: boolean
    itemStyle: PathStyleProps
    lineStyle: LineStyleProps
}

export interface LegendSymbolStyleOption {
    itemStyle?: ItemStyleProps
    lineStyle?: LineStyleProps
}

export interface LegendOption extends ComponentOption, LegendStyleOption,
    BoxLayoutOptionMixin, BorderOptionMixin
{

    mainType?: 'legend'

    show?: boolean

    orient?: LayoutOrient

    align?: 'auto' | 'left' | 'right'

    backgroundColor?: ColorString
    /**
     * Border radius of background rect
     * @default 0
     */
    borderRadius?: number | number[]

    /**
     * Padding between legend item and border.
     * Support to be a single number or an array.
     * @default 5
     */
    padding?: number | number[]
    /**
     * Gap between each legend item.
     * @default 10
     */
    itemGap?: number
    /**
     * Width of legend symbol
     */
    itemWidth?: number
    /**
     * Height of legend symbol
     */
    itemHeight?: number

    selectedMode?: boolean | 'single' | 'multiple'
    /**
     * selected map of each item. Default to be selected if item is not in the map
     */
    selected?: Dictionary<boolean>

    /**
     * Buttons for all select or inverse select.
     * @example
     *  selector: [{type: 'all or inverse', title: xxx}]
     *  selector: true
     *  selector: ['all', 'inverse']
     */
    selector?: (LegendSelectorButtonOption | SelectorType)[] | boolean

    selectorLabel?: LabelOption

    emphasis?: {
        selectorLabel?: LabelOption
    }

    /**
     * Position of selector buttons.
     */
    selectorPosition?: 'auto' | 'start' | 'end'
    /**
     * Gap between each selector button
     */
    selectorItemGap?: number
    /**
     * Gap between selector buttons group and legend main items.
     */
    selectorButtonGap?: number

    data?: (string | DataItem)[]

    /**
     * Tooltip option
     */
    tooltip?: CommonTooltipOption<LegendTooltipFormatterParams>

}

class LegendModel<Ops extends LegendOption = LegendOption> extends ComponentModel<Ops> {
    static type = 'legend.plain';
    type = LegendModel.type;

    static readonly dependencies = ['series'];

    readonly layoutMode = {
        type: 'box',
        // legend.width/height are maxWidth/maxHeight actually,
        // whereas real width/height is calculated by its content.
        // (Setting {left: 10, right: 10} does not make sense).
        // So consider the case:
        // `setOption({legend: {left: 10});`
        // then `setOption({legend: {right: 10});`
        // The previous `left` should be cleared by setting `ignoreSize`.
        ignoreSize: true
    } as const;


    private _data: Model<DataItem>[];
    private _availableNames: string[];

    init(option: Ops, parentModel: Model, ecModel: GlobalModel) {
        this.mergeDefaultAndTheme(option, ecModel);

        option.selected = option.selected || {};
        this._updateSelector(option);
    }

    mergeOption(option: Ops, ecModel: GlobalModel) {
        super.mergeOption(option, ecModel);
        this._updateSelector(option);
    }

    _updateSelector(option: Ops) {
        let selector = option.selector;
        const {ecModel} = this;
        if (selector === true) {
            selector = option.selector = ['all', 'inverse'];
        }
        if (zrUtil.isArray(selector)) {
            zrUtil.each(selector, function (item, index) {
                zrUtil.isString(item) && (item = {type: item});
                (selector as LegendSelectorButtonOption[])[index] = zrUtil.merge(
                    item, getDefaultSelectorOptions(ecModel, item.type)
                );
            });
        }
    }

    optionUpdated() {
        this._updateData(this.ecModel);

        const legendData = this._data;

        // If selectedMode is single, try to select one
        if (legendData[0] && this.get('selectedMode') === 'single') {
            let hasSelected = false;
            // If has any selected in option.selected
            for (let i = 0; i < legendData.length; i++) {
                const name = legendData[i].get('name');
                if (this.isSelected(name)) {
                    // Force to unselect others
                    this.select(name);
                    hasSelected = true;
                    break;
                }
            }
            // Try select the first if selectedMode is single
            !hasSelected && this.select(legendData[0].get('name'));
        }
    }

    _updateData(ecModel: GlobalModel) {
        let potentialData: string[] = [];
        let availableNames: string[] = [];

        ecModel.eachRawSeries(function (seriesModel) {
            const seriesName = seriesModel.name;
            availableNames.push(seriesName);
            let isPotential;

            if (seriesModel.legendVisualProvider) {
                const provider = seriesModel.legendVisualProvider;
                const names = provider.getAllNames();

                if (!ecModel.isSeriesFiltered(seriesModel)) {
                    availableNames = availableNames.concat(names);
                }

                if (names.length) {
                    potentialData = potentialData.concat(names);
                }
                else {
                    isPotential = true;
                }
            }
            else {
                isPotential = true;
            }

            if (isPotential && isNameSpecified(seriesModel)) {
                potentialData.push(seriesModel.name);
            }
        });

        /**
         * @type {Array.<string>}
         * @private
         */
        this._availableNames = availableNames;

        // If legend.data is not specified in option, use availableNames as data,
        // which is convenient for user preparing option.
        const rawData = this.get('data') || potentialData;

        const legendNameMap = zrUtil.createHashMap();
        const legendData = zrUtil.map(rawData, function (dataItem) {
            // Can be string or number
            if (zrUtil.isString(dataItem) || zrUtil.isNumber(dataItem)) {
                dataItem = {
                    name: dataItem as string
                };
            }
            if (legendNameMap.get(dataItem.name)) {
                // remove legend name duplicate
                return null;
            }
            legendNameMap.set(dataItem.name, true);
            return new Model(dataItem, this, this.ecModel);
        }, this);

        /**
         * @type {Array.<module:echarts/model/Model>}
         * @private
         */
        this._data = zrUtil.filter(legendData, item => !!item);
    }

    getData() {
        return this._data;
    }

    select(name: string) {
        const selected = this.option.selected;
        const selectedMode = this.get('selectedMode');
        if (selectedMode === 'single') {
            const data = this._data;
            zrUtil.each(data, function (dataItem) {
                selected[dataItem.get('name')] = false;
            });
        }
        selected[name] = true;
    }

    unSelect(name: string) {
        if (this.get('selectedMode') !== 'single') {
            this.option.selected[name] = false;
        }
    }

    toggleSelected(name: string) {
        const selected = this.option.selected;
        // Default is true
        if (!selected.hasOwnProperty(name)) {
            selected[name] = true;
        }
        this[selected[name] ? 'unSelect' : 'select'](name);
    }

    allSelect() {
        const data = this._data;
        const selected = this.option.selected;
        zrUtil.each(data, function (dataItem) {
            selected[dataItem.get('name', true)] = true;
        });
    }

    inverseSelect() {
        const data = this._data;
        const selected = this.option.selected;
        zrUtil.each(data, function (dataItem) {
            const name = dataItem.get('name', true);
            // Initially, default value is true
            if (!selected.hasOwnProperty(name)) {
                selected[name] = true;
            }
            selected[name] = !selected[name];
        });
    }

    isSelected(name: string) {
        const selected = this.option.selected;
        return !(selected.hasOwnProperty(name) && !selected[name])
            && zrUtil.indexOf(this._availableNames, name) >= 0;
    }

    getOrient(): {index: 0, name: 'horizontal'}
    getOrient(): {index: 1, name: 'vertical'}
    getOrient() {
        return this.get('orient') === 'vertical'
            ? {index: 1, name: 'vertical'}
            : {index: 0, name: 'horizontal'};
    }

    static defaultOption: LegendOption = {
        // zlevel: 0,
        z: 4,
        show: true,

        orient: 'horizontal',

        left: 'center',
        // right: 'center',
        top: 0,
        // bottom: null,

        align: 'auto',

        backgroundColor: 'rgba(0,0,0,0)',
        borderColor: '#ccc',
        borderRadius: 0,
        borderWidth: 0,
        padding: 5,
        itemGap: 10,
        itemWidth: 25,
        itemHeight: 14,
        symbolRotate: 'inherit',
        symbolKeepAspect: true,

        inactiveColor: '#ccc',
        inactiveBorderColor: '#ccc',
        inactiveBorderWidth: 'auto',

        itemStyle: {
            color: 'inherit',
            opacity: 'inherit',
            borderColor: 'inherit',
            borderWidth: 'auto',
            borderCap: 'inherit',
            borderJoin: 'inherit',
            borderDashOffset: 'inherit',
            borderMiterLimit: 'inherit'
        },

        lineStyle: {
            width: 'auto',
            color: 'inherit',
            inactiveColor: '#ccc',
            inactiveWidth: 2,
            opacity: 'inherit',
            type: 'inherit',
            cap: 'inherit',
            join: 'inherit',
            dashOffset: 'inherit',
            miterLimit: 'inherit'
        },

        textStyle: {
            color: '#333'
        },
        selectedMode: true,

        selector: false,

        selectorLabel: {
            show: true,
            borderRadius: 10,
            padding: [3, 5, 3, 5],
            fontSize: 12,
            fontFamily: 'sans-serif',
            color: '#666',
            borderWidth: 1,
            borderColor: '#666'
        },

        emphasis: {
            selectorLabel: {
                show: true,
                color: '#eee',
                backgroundColor: '#666'
            }
        },

        selectorPosition: 'auto',

        selectorItemGap: 7,

        selectorButtonGap: 10,

        tooltip: {
            show: false
        }
    };
}

export default LegendModel;
