/*
* 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 * as zrColor from 'zrender/src/tool/color';
import {linearMap} from '../util/number';
import { AllPropTypes, Dictionary } from 'zrender/src/core/types';
import {
    ColorString,
    BuiltinVisualProperty,
    VisualOptionPiecewise,
    VisualOptionCategory,
    VisualOptionLinear,
    VisualOptionUnit,
    ParsedValue
} from '../util/types';

const each = zrUtil.each;
const isObject = zrUtil.isObject;

const CATEGORY_DEFAULT_VISUAL_INDEX = -1;

// Type of raw value
type RawValue = ParsedValue;
// Type of mapping visual value
type VisualValue = AllPropTypes<VisualOptionUnit>;
// Type of value after normalized. 0 - 1
type NormalizedValue = number;

type MappingMethod = 'linear' | 'piecewise' | 'category' | 'fixed';

// May include liftZ. wich is not provided to developers.

interface Normalizer {
    (this: VisualMapping, value?: RawValue): NormalizedValue
}
interface ColorMapper {
    (this: VisualMapping, value: RawValue | NormalizedValue, isNormalized?: boolean, out?: number[])
        : ColorString | number[]
}
interface DoMap {
    (this: VisualMapping, normalzied?: NormalizedValue, value?: RawValue): VisualValue
}
interface VisualValueGetter {
    (key: string): VisualValue
}
interface VisualValueSetter {
    (key: string, value: VisualValue): void
}
interface VisualHandler {
    applyVisual(
        this: VisualMapping,
        value: RawValue,
        getter: VisualValueGetter,
        setter: VisualValueSetter
    ): void

    _normalizedToVisual: {
        linear(this: VisualMapping, normalized: NormalizedValue): VisualValue
        category(this: VisualMapping, normalized: NormalizedValue): VisualValue
        piecewise(this: VisualMapping, normalzied: NormalizedValue, value: RawValue): VisualValue
        fixed(this: VisualMapping): VisualValue
    }
    /**
     * Get color mapping for the outside usage.
     * Currently only used in `color` visual.
     *
     * The last parameter out is cached color array.
     */
    getColorMapper?: (this: VisualMapping) => ColorMapper
}

interface VisualMappingPiece {
    index?: number

    value?: number | string
    interval?: [number, number]
    close?: [0 | 1, 0 | 1]

    text?: string

    visual?: VisualOptionPiecewise
}

export interface VisualMappingOption {
    type?: BuiltinVisualProperty

    mappingMethod?: MappingMethod

    /**
     * required when mappingMethod is 'linear'
     */
    dataExtent?: [number, number]
    /**
     *  required when mappingMethod is 'piecewise'.
     *  Visual for only each piece can be specified
     * [
     *   {value: someValue},
     *   {interval: [min1, max1], visual: {...}},
     *   {interval: [min2, max2]}
     *  ],.
     */
    pieceList?: VisualMappingPiece[]
    /**
     * required when mappingMethod is 'category'. If no option.categories, categories is set as [0, 1, 2, ...].
     */
    categories?: (string | number)[]
    /**
     * Whether loop mapping when mappingMethod is 'category'.
     * @default false
     */
    loop?: boolean
    /**
     * Visual data
     * when mappingMethod is 'category', visual data can be array or object
     * (like: {cate1: '#222', none: '#fff'})
     * or primary types (which represents default category visual), otherwise visual
     * can be array or primary (which will be normalized to array).
     */
    visual?: VisualValue[] | Dictionary<VisualValue> | VisualValue
}

interface VisualMappingInnerPiece extends VisualMappingPiece {
    originIndex: number
}
interface VisualMappingInnerOption extends VisualMappingOption {
    hasSpecialVisual: boolean
    pieceList: VisualMappingInnerPiece[]
    /**
     * Map to get category index
     */
    categoryMap: Dictionary<number>
    /**
     * Cached parsed rgba array from string to avoid parse every time.
     */
    parsedVisual: number[][]

    // Have converted primary value to array.
    visual?: VisualValue[] | Dictionary<VisualValue>
}

class VisualMapping<VisualOption
    extends VisualOptionPiecewise | VisualOptionCategory | VisualOptionUnit | VisualOptionLinear = {}
> {

    option: VisualMappingInnerOption;

    type: BuiltinVisualProperty;

    mappingMethod: MappingMethod;

    applyVisual: VisualHandler['applyVisual'];

    getColorMapper: VisualHandler['getColorMapper'];

    _normalizeData: Normalizer;

    _normalizedToVisual: DoMap;

    constructor(option: VisualMappingOption) {
        const mappingMethod = option.mappingMethod;
        const visualType = option.type;

        const thisOption: VisualMappingInnerOption = this.option = zrUtil.clone(option) as VisualMappingInnerOption;

        this.type = visualType;
        this.mappingMethod = mappingMethod;

        this._normalizeData = normalizers[mappingMethod];
        const visualHandler = VisualMapping.visualHandlers[visualType];

        this.applyVisual = visualHandler.applyVisual;

        this.getColorMapper = visualHandler.getColorMapper;

        this._normalizedToVisual = visualHandler._normalizedToVisual[mappingMethod];

        if (mappingMethod === 'piecewise') {
            normalizeVisualRange(thisOption);
            preprocessForPiecewise(thisOption);
        }
        else if (mappingMethod === 'category') {
            thisOption.categories
                ? preprocessForSpecifiedCategory(thisOption)
                // categories is ordinal when thisOption.categories not specified,
                // which need no more preprocess except normalize visual.
                : normalizeVisualRange(thisOption, true);
        }
        else { // mappingMethod === 'linear' or 'fixed'
            zrUtil.assert(mappingMethod !== 'linear' || thisOption.dataExtent);
            normalizeVisualRange(thisOption);
        }
    }

    mapValueToVisual(value: RawValue): VisualValue {
        const normalized = this._normalizeData(value);
        return this._normalizedToVisual(normalized, value);
    }

    getNormalizer() {
        return zrUtil.bind(this._normalizeData, this);
    }

    static visualHandlers: {[key in BuiltinVisualProperty]: VisualHandler} = {
        color: {
            applyVisual: makeApplyVisual('color'),
            getColorMapper: function () {
                const thisOption = this.option;

                return zrUtil.bind(
                    thisOption.mappingMethod === 'category'
                        ? function (
                            this: VisualMapping,
                            value: NormalizedValue | RawValue,
                            isNormalized?: boolean
                        ): ColorString {
                            !isNormalized && (value = this._normalizeData(value));
                            return doMapCategory.call(this, value) as ColorString;
                        }
                        : function (
                            this: VisualMapping,
                            value: NormalizedValue | RawValue,
                            isNormalized?: boolean,
                            out?: number[]
                        ): number[] | string {
                            // If output rgb array
                            // which will be much faster and useful in pixel manipulation
                            const returnRGBArray = !!out;
                            !isNormalized && (value = this._normalizeData(value));
                            out = zrColor.fastLerp(value as NormalizedValue, thisOption.parsedVisual, out);
                            return returnRGBArray ? out : zrColor.stringify(out, 'rgba');
                        },
                    this
                );
            },

            _normalizedToVisual: {
                linear: function (normalized) {
                    return zrColor.stringify(
                        zrColor.fastLerp(normalized, this.option.parsedVisual),
                        'rgba'
                    );
                },
                category: doMapCategory,
                piecewise: function (normalized, value) {
                    let result = getSpecifiedVisual.call(this, value);
                    if (result == null) {
                        result = zrColor.stringify(
                            zrColor.fastLerp(normalized, this.option.parsedVisual),
                            'rgba'
                        );
                    }
                    return result;
                },
                fixed: doMapFixed
            }
        },

        colorHue: makePartialColorVisualHandler(function (color: ColorString, value: number) {
            return zrColor.modifyHSL(color, value);
        }),

        colorSaturation: makePartialColorVisualHandler(function (color: ColorString, value: number) {
            return zrColor.modifyHSL(color, null, value);
        }),

        colorLightness: makePartialColorVisualHandler(function (color: ColorString, value: number) {
            return zrColor.modifyHSL(color, null, null, value);
        }),

        colorAlpha: makePartialColorVisualHandler(function (color: ColorString, value: number) {
            return zrColor.modifyAlpha(color, value);
        }),

        decal: {
            applyVisual: makeApplyVisual('decal'),
            _normalizedToVisual: {
                linear: null,
                category: doMapCategory,
                piecewise: null,
                fixed: null
            }
        },

        opacity: {
            applyVisual: makeApplyVisual('opacity'),
            _normalizedToVisual: createNormalizedToNumericVisual([0, 1])
        },

        liftZ: {
            applyVisual: makeApplyVisual('liftZ'),
            _normalizedToVisual: {
                linear: doMapFixed,
                category: doMapFixed,
                piecewise: doMapFixed,
                fixed: doMapFixed
            }
        },

        symbol: {
            applyVisual: function (value, getter, setter) {
                const symbolCfg = this.mapValueToVisual(value);
                setter('symbol', symbolCfg as string);
            },
            _normalizedToVisual: {
                linear: doMapToArray,
                category: doMapCategory,
                piecewise: function (normalized, value) {
                    let result = getSpecifiedVisual.call(this, value);
                    if (result == null) {
                        result = doMapToArray.call(this, normalized);
                    }
                    return result;
                },
                fixed: doMapFixed
            }
        },

        symbolSize: {
            applyVisual: makeApplyVisual('symbolSize'),
            _normalizedToVisual: createNormalizedToNumericVisual([0, 1])
        }
    };


    /**
     * List available visual types.
     *
     * @public
     * @return {Array.<string>}
     */
    static listVisualTypes() {
        return zrUtil.keys(VisualMapping.visualHandlers);
    }

    // /**
    //  * @public
    //  */
    // static addVisualHandler(name, handler) {
    //     visualHandlers[name] = handler;
    // }

    /**
     * @public
     */
    static isValidType(visualType: string): boolean {
        return VisualMapping.visualHandlers.hasOwnProperty(visualType);
    }

    /**
     * Convinent method.
     * Visual can be Object or Array or primary type.
     */
    static eachVisual<Ctx, T>(
        visual: T | T[] | Dictionary<T>,
        callback: (visual: T, key?: string | number) => void,
        context?: Ctx
    ) {
        if (zrUtil.isObject(visual)) {
            zrUtil.each(visual as Dictionary<T>, callback, context);
        }
        else {
            callback.call(context, visual);
        }
    }

    static mapVisual<Ctx, T>(visual: T, callback: (visual: T, key?: string | number) => T, context?: Ctx): T
    static mapVisual<Ctx, T>(visual: T[], callback: (visual: T, key?: string | number) => T[], context?: Ctx): T[]
    static mapVisual<Ctx, T>(
        visual: Dictionary<T>,
        callback: (visual: T, key?: string | number) => Dictionary<T>,
        context?: Ctx
    ): Dictionary<T>
    static mapVisual<Ctx, T>(
        visual: T | T[] | Dictionary<T>,
        callback: (visual: T, key?: string | number) => T | T[] | Dictionary<T>,
        context?: Ctx
    ) {
        let isPrimary: boolean;
        let newVisual: T | T[] | Dictionary<T> = zrUtil.isArray(visual)
            ? []
            : zrUtil.isObject(visual)
            ? {}
            : (isPrimary = true, null);

        VisualMapping.eachVisual(visual, function (v, key) {
            const newVal = callback.call(context, v, key);
            isPrimary ? (newVisual = newVal) : ((newVisual as Dictionary<T>)[key as string] = newVal as T);
        });
        return newVisual;
    }

    /**
     * Retrieve visual properties from given object.
     */
    static retrieveVisuals(obj: Dictionary<any>): VisualOptionPiecewise {
        const ret: VisualOptionPiecewise = {};
        let hasVisual: boolean;

        obj && each(VisualMapping.visualHandlers, function (h, visualType: BuiltinVisualProperty) {
            if (obj.hasOwnProperty(visualType)) {
                (ret as any)[visualType] = obj[visualType];
                hasVisual = true;
            }
        });

        return hasVisual ? ret : null;
    }

    /**
     * Give order to visual types, considering colorSaturation, colorAlpha depends on color.
     *
     * @public
     * @param {(Object|Array)} visualTypes If Object, like: {color: ..., colorSaturation: ...}
     *                                     IF Array, like: ['color', 'symbol', 'colorSaturation']
     * @return {Array.<string>} Sorted visual types.
     */
    static prepareVisualTypes(
        visualTypes: {[key in BuiltinVisualProperty]?: any} | BuiltinVisualProperty[]
    ) {
        if (zrUtil.isArray(visualTypes)) {
            visualTypes = visualTypes.slice();
        }
        else if (isObject(visualTypes)) {
            const types: BuiltinVisualProperty[] = [];
            each(visualTypes, function (item: unknown, type: BuiltinVisualProperty) {
                types.push(type);
            });
            visualTypes = types;
        }
        else {
            return [];
        }

        visualTypes.sort(function (type1: BuiltinVisualProperty, type2: BuiltinVisualProperty) {
            // color should be front of colorSaturation, colorAlpha, ...
            // symbol and symbolSize do not matter.
            return (type2 === 'color' && type1 !== 'color' && type1.indexOf('color') === 0)
                ? 1 : -1;
        });

        return visualTypes;
    }

    /**
     * 'color', 'colorSaturation', 'colorAlpha', ... are depends on 'color'.
     * Other visuals are only depends on themself.
     */
    static dependsOn(visualType1: BuiltinVisualProperty, visualType2: BuiltinVisualProperty) {
        return visualType2 === 'color'
            ? !!(visualType1 && visualType1.indexOf(visualType2) === 0)
            : visualType1 === visualType2;
    }

    /**
     * @param value
     * @param pieceList [{value: ..., interval: [min, max]}, ...]
     *                         Always from small to big.
     * @param findClosestWhenOutside Default to be false
     * @return index
     */
    static findPieceIndex(value: number, pieceList: VisualMappingPiece[], findClosestWhenOutside?: boolean): number {
        let possibleI: number;
        let abs = Infinity;

        // value has the higher priority.
        for (let i = 0, len = pieceList.length; i < len; i++) {
            const pieceValue = pieceList[i].value;
            if (pieceValue != null) {
                if (pieceValue === value
                    // FIXME
                    // It is supposed to compare value according to value type of dimension,
                    // but currently value type can exactly be string or number.
                    // Compromise for numeric-like string (like '12'), especially
                    // in the case that visualMap.categories is ['22', '33'].
                    || (typeof pieceValue === 'string' && pieceValue === value + '')
                ) {
                    return i;
                }
                findClosestWhenOutside && updatePossible(pieceValue as number, i);
            }
        }

        for (let i = 0, len = pieceList.length; i < len; i++) {
            const piece = pieceList[i];
            const interval = piece.interval;
            const close = piece.close;

            if (interval) {
                if (interval[0] === -Infinity) {
                    if (littleThan(close[1], value, interval[1])) {
                        return i;
                    }
                }
                else if (interval[1] === Infinity) {
                    if (littleThan(close[0], interval[0], value)) {
                        return i;
                    }
                }
                else if (
                    littleThan(close[0], interval[0], value)
                    && littleThan(close[1], value, interval[1])
                ) {
                    return i;
                }
                findClosestWhenOutside && updatePossible(interval[0], i);
                findClosestWhenOutside && updatePossible(interval[1], i);
            }
        }

        if (findClosestWhenOutside) {
            return value === Infinity
                ? pieceList.length - 1
                : value === -Infinity
                ? 0
                : possibleI;
        }

        function updatePossible(val: number, index: number) {
            const newAbs = Math.abs(val - value);
            if (newAbs < abs) {
                abs = newAbs;
                possibleI = index;
            }
        }

    }
}

function preprocessForPiecewise(thisOption: VisualMappingInnerOption) {
    const pieceList = thisOption.pieceList;
    thisOption.hasSpecialVisual = false;

    zrUtil.each(pieceList, function (piece, index) {
        piece.originIndex = index;
        // piece.visual is "result visual value" but not
        // a visual range, so it does not need to be normalized.
        if (piece.visual != null) {
            thisOption.hasSpecialVisual = true;
        }
    });
}

function preprocessForSpecifiedCategory(thisOption: VisualMappingInnerOption) {
    // Hash categories.
    const categories = thisOption.categories;
    const categoryMap: VisualMappingInnerOption['categoryMap'] = thisOption.categoryMap = {};

    let visual = thisOption.visual;
    each(categories, function (cate, index) {
        categoryMap[cate] = index;
    });

    // Process visual map input.
    if (!zrUtil.isArray(visual)) {
        const visualArr: VisualValue[] = [];

        if (zrUtil.isObject(visual)) {
            each(visual, function (v, cate) {
                const index = categoryMap[cate];
                visualArr[index != null ? index : CATEGORY_DEFAULT_VISUAL_INDEX] = v;
            });
        }
        else { // Is primary type, represents default visual.
            visualArr[CATEGORY_DEFAULT_VISUAL_INDEX] = visual;
        }

        visual = setVisualToOption(thisOption, visualArr);
    }

    // Remove categories that has no visual,
    // then we can mapping them to CATEGORY_DEFAULT_VISUAL_INDEX.
    for (let i = categories.length - 1; i >= 0; i--) {
        if (visual[i] == null) {
            delete categoryMap[categories[i]];
            categories.pop();
        }
    }
}

function normalizeVisualRange(thisOption: VisualMappingInnerOption, isCategory?: boolean) {
    const visual = thisOption.visual;
    const visualArr: VisualValue[] = [];

    if (zrUtil.isObject(visual)) {
        each(visual, function (v) {
            visualArr.push(v);
        });
    }
    else if (visual != null) {
        visualArr.push(visual);
    }

    const doNotNeedPair = {color: 1, symbol: 1};

    if (!isCategory
        && visualArr.length === 1
        && !doNotNeedPair.hasOwnProperty(thisOption.type)
    ) {
        // Do not care visualArr.length === 0, which is illegal.
        visualArr[1] = visualArr[0];
    }

    setVisualToOption(thisOption, visualArr);
}

function makePartialColorVisualHandler(
    applyValue: (prop: VisualValue, value: NormalizedValue) => VisualValue
): VisualHandler {
    return {
        applyVisual: function (value, getter, setter) {
            // Only used in HSL
            const colorChannel = this.mapValueToVisual(value);
            // Must not be array value
            setter('color', applyValue(getter('color'), colorChannel as number));
        },
        _normalizedToVisual: createNormalizedToNumericVisual([0, 1])
    };
}

function doMapToArray(this: VisualMapping<VisualOptionLinear>, normalized: NormalizedValue): VisualValue {
    const visual = this.option.visual as VisualValue[];
    return visual[
        Math.round(linearMap(normalized, [0, 1], [0, visual.length - 1], true))
    ] || {} as any;    // TODO {}?
}

function makeApplyVisual(visualType: string): VisualHandler['applyVisual'] {
    return function (value, getter, setter) {
        setter(visualType, this.mapValueToVisual(value));
    };
}

function doMapCategory(this: VisualMapping<VisualOptionCategory>, normalized: NormalizedValue): VisualValue {
    const visual = this.option.visual as Dictionary<any>;
    return visual[
        (this.option.loop && normalized !== CATEGORY_DEFAULT_VISUAL_INDEX)
            ? normalized % visual.length
            : normalized
    ];
}

function doMapFixed(this: VisualMapping): VisualValue {
    // visual will be convert to array.
    return (this.option.visual as VisualValue[])[0];
}

/**
 * Create mapped to numeric visual
 */
function createNormalizedToNumericVisual(sourceExtent: [number, number]): VisualHandler['_normalizedToVisual'] {
    return {
        linear: function (normalized) {
            return linearMap(normalized, sourceExtent, this.option.visual as [number, number], true);
        },
        category: doMapCategory,
        piecewise: function (normalized, value) {
            let result = getSpecifiedVisual.call(this, value);
            if (result == null) {
                result = linearMap(normalized, sourceExtent, this.option.visual as [number, number], true);
            }
            return result;
        },
        fixed: doMapFixed
    };
}

function getSpecifiedVisual(this: VisualMapping, value: number) {
    const thisOption = this.option;
    const pieceList = thisOption.pieceList;
    if (thisOption.hasSpecialVisual) {
        const pieceIndex = VisualMapping.findPieceIndex(value, pieceList);
        const piece = pieceList[pieceIndex];
        if (piece && piece.visual) {
            return piece.visual[this.type];
        }
    }
}

function setVisualToOption(thisOption: VisualMappingInnerOption, visualArr: VisualValue[]) {
    thisOption.visual = visualArr;
    if (thisOption.type === 'color') {
        thisOption.parsedVisual = zrUtil.map(visualArr, function (item: string) {
            return zrColor.parse(item);
        });
    }
    return visualArr;
}


/**
 * Normalizers by mapping methods.
 */
const normalizers: { [key in MappingMethod]: Normalizer } = {
    linear: function (value: RawValue): NormalizedValue {
        return linearMap(value as number, this.option.dataExtent, [0, 1], true);
    },

    piecewise: function (value: RawValue): NormalizedValue {
        const pieceList = this.option.pieceList;
        const pieceIndex = VisualMapping.findPieceIndex(value as number, pieceList, true);
        if (pieceIndex != null) {
            return linearMap(pieceIndex, [0, pieceList.length - 1], [0, 1], true);
        }
    },

    category: function (value: RawValue): NormalizedValue {
        const index: number = this.option.categories
            ? this.option.categoryMap[value]
            : value as number; // ordinal value
        return index == null ? CATEGORY_DEFAULT_VISUAL_INDEX : index;
    },

    fixed: zrUtil.noop as Normalizer
};


function littleThan(close: boolean | 0 | 1, a: number, b: number): boolean {
    return close ? a <= b : a < b;
}

export default VisualMapping;
