/*
* 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 {
    Dictionary, TooltipRenderMode, ColorString,
    TooltipOrderMode, DimensionType
} from '../../util/types';
import {
    TooltipMarkerType, getTooltipMarker, encodeHTML,
    makeValueReadable, convertToColorString
} from '../../util/format';
import { isString, each, hasOwn, isArray, map, assert, extend } from 'zrender/src/core/util';
import { SortOrderComparator } from '../../data/helper/dataValueHelper';
import SeriesModel from '../../model/Series';
import { getRandomIdBase } from '../../util/number';
import Model from '../../model/Model';
import { TooltipOption } from './TooltipModel';

type RichTextStyle = {
    fontSize: number | string,
    fill: string,
    fontWeight?: number | string
};

type TextStyle = string | RichTextStyle;

const TOOLTIP_LINE_HEIGHT_CSS = 'line-height:1';

// TODO: more textStyle option
function getTooltipTextStyle(
    textStyle: TooltipOption['textStyle'],
    renderMode: TooltipRenderMode
): {
    nameStyle: TextStyle
    valueStyle: TextStyle
} {
    const nameFontColor = textStyle.color || '#6e7079';
    const nameFontSize = textStyle.fontSize || 12;
    const nameFontWeight = textStyle.fontWeight || '400';
    const valueFontColor = textStyle.color || '#464646';
    const valueFontSize = textStyle.fontSize || 14;
    const valueFontWeight = textStyle.fontWeight || '900';

    if (renderMode === 'html') {
        // `textStyle` is probably from user input, should be encoded to reduce security risk.
        return {
            // eslint-disable-next-line max-len
            nameStyle: `font-size:${encodeHTML(nameFontSize + '')}px;color:${encodeHTML(nameFontColor)};font-weight:${encodeHTML(nameFontWeight + '')}`,
            // eslint-disable-next-line max-len
            valueStyle: `font-size:${encodeHTML(valueFontSize + '')}px;color:${encodeHTML(valueFontColor)};font-weight:${encodeHTML(valueFontWeight + '')}`
        };
    }
    else {
        return {
            nameStyle: {
                fontSize: nameFontSize,
                fill: nameFontColor,
                fontWeight: nameFontWeight
            },
            valueStyle: {
                fontSize: valueFontSize,
                fill: valueFontColor,
                fontWeight: valueFontWeight
            }
        };
    }
}

// 0: no gap in this block.
// 1: has max gap in level 1 in this block.
// ...
type GapLevel = number;
// See `TooltipMarkupLayoutIntent['innerGapLevel']`.
// (value from UI design)
const HTML_GAPS: { [key in GapLevel]: number } = [0, 10, 20, 30];
const RICH_TEXT_GAPS: { [key in GapLevel]: string } = ['', '\n', '\n\n', '\n\n\n'];

/**
 * This is an abstract layer to insulate the upper usage of tooltip content
 * from the different backends according to different `renderMode` ('html' or 'richText').
 * With the help of the abstract layer, it does not need to consider how to create and
 * assemble html or richText snippets when making tooltip content.
 *
 * @usage
 *
 * ```ts
 * class XxxSeriesModel {
 *     formatTooltip(
 *         dataIndex: number,
 *         multipleSeries: boolean,
 *         dataType: string
 *     ) {
 *         ...
 *         return createTooltipMarkup('section', {
 *             header: header,
 *             blocks: [
 *                 createTooltipMarkup('nameValue', {
 *                     name: name,
 *                     value: value,
 *                     noValue: value == null
 *                 })
 *             ]
 *         });
 *     }
 * }
 * ```
 */
export type TooltipMarkupBlockFragment =
    TooltipMarkupSection
    | TooltipMarkupNameValueBlock;

interface TooltipMarkupBlock {
    // Use to make comparison when `sortBlocks: true`.
    sortParam?: unknown;
    __gapLevelBetweenSubBlocks?: number;
}

export interface TooltipMarkupSection extends TooltipMarkupBlock {
    type: 'section';
    header?: unknown;
    // If `noHeader` is `true`, do not display header.
    // Otherwise, always display it even if it is
    // null/undefined/NaN/''... (displayed as '-').
    noHeader?: boolean;
    blocks?: TooltipMarkupBlockFragment[];
    // Enable to sort blocks when making final html or richText.
    sortBlocks?: boolean;
}

export interface TooltipMarkupNameValueBlock extends TooltipMarkupBlock {
    type: 'nameValue';
    // If `!markerType`, tooltip marker is not used.
    markerType?: TooltipMarkerType;
    markerColor?: ColorString;
    name?: string;
    // Also support value is `[121, 555, 94.2]`.
    value?: unknown | unknown[];
    // If not specified, treat value as normal string or numeric.
    // If needs to display formatted time, set as 'time'.
    // If needs to display original string with numeric guessing, set as 'ordinal'.
    // If both `value` and `valueType` are array, each valueType[i] cooresponds to value[i].
    valueType?: DimensionType | DimensionType[];
    // If `noName` or `noValue` is `true`, do not display name or value.
    // Otherwise, always display them even if they are
    // null/undefined/NaN/''... (displayed as '-').
    noName?: boolean;
    noValue?: boolean;
}

/**
 * Create tooltip markup by this function, we can get TS type check.
 */
// eslint-disable-next-line max-len
export function createTooltipMarkup(type: 'section', option: Omit<TooltipMarkupSection, 'type'>): TooltipMarkupSection;
// eslint-disable-next-line max-len
export function createTooltipMarkup(type: 'nameValue', option: Omit<TooltipMarkupNameValueBlock, 'type'>): TooltipMarkupNameValueBlock;
// eslint-disable-next-line max-len
export function createTooltipMarkup(type: TooltipMarkupBlockFragment['type'], option: Omit<TooltipMarkupBlockFragment, 'type'>): TooltipMarkupBlockFragment {
    (option as TooltipMarkupBlockFragment).type = type;
    return option as TooltipMarkupBlockFragment;
}


// Can be null/undefined, which means generate nothing markup text.
type MarkupText = string;
interface TooltipMarkupFragmentBuilder {
    planLayout(
        fragment: TooltipMarkupBlockFragment
    ): void;
    build(
        ctx: TooltipMarkupBuildContext,
        fragment: TooltipMarkupBlockFragment,
        topMarginForOuterGap: number,
        toolTipTextStyle: TooltipOption['textStyle']
    ): MarkupText;
}

function getBuilder(fragment: TooltipMarkupBlockFragment): TooltipMarkupFragmentBuilder {
    return hasOwn(builderMap, fragment.type) && builderMap[fragment.type];
}

const builderMap: { [key in TooltipMarkupBlockFragment['type']]: TooltipMarkupFragmentBuilder } = {

    /**
     * A `section` block is like:
     * ```
     * header
     * subBlock
     * subBlock
     * ...
     * ```
     */
    section: {
        planLayout: function (fragment: TooltipMarkupSection) {
            const subBlockLen = fragment.blocks.length;
            const thisBlockHasInnerGap = subBlockLen > 1 || (subBlockLen > 0 && !fragment.noHeader);

            let thisGapLevelBetweenSubBlocks = 0;
            each(fragment.blocks, function (subBlock) {
                getBuilder(subBlock).planLayout(subBlock);
                const subGapLevel = subBlock.__gapLevelBetweenSubBlocks;

                // If the some of the sub-blocks have some gaps (like 10px) inside, this block
                // should use a larger gap (like 20px) to distinguish those sub-blocks.
                if (subGapLevel >= thisGapLevelBetweenSubBlocks) {
                    thisGapLevelBetweenSubBlocks = subGapLevel + (
                        (
                            thisBlockHasInnerGap && (
                                // 0 always can not be readable gap level.
                                !subGapLevel
                                // If no header, always keep the sub gap level. Otherwise
                                // look weird in case `multipleSeries`.
                                || (subBlock.type === 'section' && !subBlock.noHeader)
                            )
                        ) ? 1 : 0
                    );
                }
            });
            fragment.__gapLevelBetweenSubBlocks = thisGapLevelBetweenSubBlocks;
        },

        build(
            ctx,
            fragment: TooltipMarkupSection,
            topMarginForOuterGap,
            toolTipTextStyle
        ): string {
            const noHeader = fragment.noHeader;
            const gaps = getGap(fragment);

            const subMarkupText = buildSubBlocks(
                ctx,
                fragment,
                noHeader ? topMarginForOuterGap : gaps.html,
                toolTipTextStyle
            );

            if (noHeader) {
                return subMarkupText;
            }

            const displayableHeader = makeValueReadable(fragment.header, 'ordinal', ctx.useUTC);
            const {nameStyle} = getTooltipTextStyle(toolTipTextStyle, ctx.renderMode);
            if (ctx.renderMode === 'richText') {
                return wrapInlineNameRichText(ctx, displayableHeader, nameStyle as RichTextStyle) + gaps.richText
                    + subMarkupText;
            }
            else {
                return wrapBlockHTML(
                    `<div style="${nameStyle};${TOOLTIP_LINE_HEIGHT_CSS};">`
                        + encodeHTML(displayableHeader)
                        + '</div>'
                        + subMarkupText,
                    topMarginForOuterGap
                );
            }
        }
    },

    /**
     * A `nameValue` block is like:
     * ```
     * marker  name  value
     * ```
     */
    nameValue: {
        planLayout: function (fragment: TooltipMarkupNameValueBlock) {
            fragment.__gapLevelBetweenSubBlocks = 0;
        },

        build(ctx, fragment: TooltipMarkupNameValueBlock, topMarginForOuterGap, toolTipTextStyle) {
            const renderMode = ctx.renderMode;
            const noName = fragment.noName;
            const noValue = fragment.noValue;
            const noMarker = !fragment.markerType;
            const name = fragment.name;
            const value = fragment.value;
            const useUTC = ctx.useUTC;

            if (noName && noValue) {
                return;
            }

            const markerStr = noMarker
                ? ''
                : ctx.markupStyleCreator.makeTooltipMarker(
                    fragment.markerType,
                    fragment.markerColor || '#333',
                    renderMode
                );
            const readableName = noName
                ? ''
                : makeValueReadable(name, 'ordinal', useUTC);
            const valueTypeOption = fragment.valueType;
            const readableValueList = noValue
                ? []
                : (isArray(value)
                    ? map(value, (val, idx) => makeValueReadable(
                        val, isArray(valueTypeOption) ? valueTypeOption[idx] : valueTypeOption, useUTC
                    ))
                    : [makeValueReadable(
                        value, isArray(valueTypeOption) ? valueTypeOption[0] : valueTypeOption, useUTC
                    )]
                );
            const valueAlignRight = !noMarker || !noName;
            // It little weird if only value next to marker but far from marker.
            const valueCloseToMarker = !noMarker && noName;

            const {nameStyle, valueStyle} = getTooltipTextStyle(toolTipTextStyle, renderMode);

            return renderMode === 'richText'
                ? (
                    (noMarker ? '' : markerStr)
                    + (noName ? '' : wrapInlineNameRichText(ctx, readableName, nameStyle as RichTextStyle))
                    // Value has commas inside, so use ' ' as delimiter for multiple values.
                    + (noValue ? '' : wrapInlineValueRichText(
                        ctx, readableValueList, valueAlignRight, valueCloseToMarker, valueStyle as RichTextStyle
                    ))
                )
                : wrapBlockHTML(
                    (noMarker ? '' : markerStr)
                    + (noName ? '' : wrapInlineNameHTML(readableName, !noMarker, nameStyle as string))
                    + (noValue ? '' : wrapInlineValueHTML(
                        readableValueList, valueAlignRight, valueCloseToMarker, valueStyle as string
                    )),
                    topMarginForOuterGap
                );
        }
    }
};


function buildSubBlocks(
    ctx: TooltipMarkupBuildContext,
    fragment: TooltipMarkupSection,
    topMarginForOuterGap: number,
    tooltipTextStyle: TooltipOption['textStyle']
): MarkupText {
    const subMarkupTextList: string[] = [];
    let subBlocks = fragment.blocks || [];
    assert(!subBlocks || isArray(subBlocks));
    subBlocks = subBlocks || [];

    const orderMode = ctx.orderMode;
    if (fragment.sortBlocks && orderMode) {
        subBlocks = subBlocks.slice();
        const orderMap = { valueAsc: 'asc', valueDesc: 'desc' } as const;
        if (hasOwn(orderMap, orderMode)) {
            const comparator = new SortOrderComparator(orderMap[orderMode as 'valueAsc' | 'valueDesc'], null);
            subBlocks.sort((a, b) => comparator.evaluate(a.sortParam, b.sortParam));
        }
        // FIXME 'seriesDesc' necessary?
        else if (orderMode === 'seriesDesc') {
            subBlocks.reverse();
        }
    }

    const gaps = getGap(fragment);
    each(subBlocks, function (subBlock, idx) {
        const subMarkupText = getBuilder(subBlock).build(
            ctx,
            subBlock,
            idx > 0 ? gaps.html : 0,
            tooltipTextStyle
        );
        subMarkupText != null && subMarkupTextList.push(subMarkupText);
    });

    if (!subMarkupTextList.length) {
        return;
    }

    return ctx.renderMode === 'richText'
        ? subMarkupTextList.join(gaps.richText)
        : wrapBlockHTML(
            subMarkupTextList.join(''),
            topMarginForOuterGap
        );
}

interface TooltipMarkupBuildContext {
    useUTC: boolean;
    renderMode: TooltipRenderMode;
    orderMode: TooltipOrderMode;
    markupStyleCreator: TooltipMarkupStyleCreator;
}

/**
 * @return markupText. null/undefined means no content.
 */
export function buildTooltipMarkup(
    fragment: TooltipMarkupBlockFragment,
    markupStyleCreator: TooltipMarkupStyleCreator,
    renderMode: TooltipRenderMode,
    orderMode: TooltipOrderMode,
    useUTC: boolean,
    toolTipTextStyle: TooltipOption['textStyle']
): MarkupText {
    if (!fragment) {
        return;
    }

    const builder = getBuilder(fragment);
    builder.planLayout(fragment);
    const ctx: TooltipMarkupBuildContext = {
        useUTC: useUTC,
        renderMode: renderMode,
        orderMode: orderMode,
        markupStyleCreator: markupStyleCreator
    };
    return builder.build(ctx, fragment, 0, toolTipTextStyle);
}


function getGap(fragment: TooltipMarkupBlock): {
    html: number;
    richText: string
} {
    const gapLevelBetweenSubBlocks = fragment.__gapLevelBetweenSubBlocks;
    return {
        html: HTML_GAPS[gapLevelBetweenSubBlocks],
        richText: RICH_TEXT_GAPS[gapLevelBetweenSubBlocks]
    };
}

function wrapBlockHTML(
    encodedContent: string,
    topGap: number
): string {
    const clearfix = '<div style="clear:both"></div>';
    const marginCSS = `margin: ${topGap}px 0 0`;
    return `<div style="${marginCSS};${TOOLTIP_LINE_HEIGHT_CSS};">`
        + encodedContent + clearfix
        + '</div>';
}

function wrapInlineNameHTML(
    name: string,
    leftHasMarker: boolean,
    style: string
): string {
    const marginCss = leftHasMarker ? 'margin-left:2px' : '';
    return `<span style="${style};${marginCss}">`
        + encodeHTML(name)
        + '</span>';
}

function wrapInlineValueHTML(
    valueList: string[],
    alignRight: boolean,
    valueCloseToMarker: boolean,
    style: string
): string {
    // Do not too close to marker, considering there are multiple values separated by spaces.
    const paddingStr = valueCloseToMarker ? '10px' : '20px';
    const alignCSS = alignRight ? `float:right;margin-left:${paddingStr}` : '';
    return (
        `<span style="${alignCSS};${style}">`
        // Value has commas inside, so use '  ' as delimiter for multiple values.
        + map(valueList, value => encodeHTML(value)).join('&nbsp;&nbsp;')
        + '</span>'
    );
}

function wrapInlineNameRichText(ctx: TooltipMarkupBuildContext, name: string, style: RichTextStyle): string {
    return ctx.markupStyleCreator.wrapRichTextStyle(name, style as Dictionary<unknown>);
}

function wrapInlineValueRichText(
    ctx: TooltipMarkupBuildContext,
    valueList: string[],
    alignRight: boolean,
    valueCloseToMarker: boolean,
    style: RichTextStyle
): string {
    const styles: Dictionary<unknown>[] = [style];
    const paddingLeft = valueCloseToMarker ? 10 : 20;
    alignRight && styles.push({ padding: [0, 0, 0, paddingLeft], align: 'right' });
    // Value has commas inside, so use '  ' as delimiter for multiple values.
    return ctx.markupStyleCreator.wrapRichTextStyle(valueList.join('  '), styles);
}


export function retrieveVisualColorForTooltipMarker(
    series: SeriesModel,
    dataIndex: number
): ColorString {
    const style = series.getData().getItemVisual(dataIndex, 'style');
    const color = style[series.visualDrawType];
    return convertToColorString(color);
}

export function getPaddingFromTooltipModel(
    model: Model<TooltipOption>,
    renderMode: TooltipRenderMode
): number | number[] {
    const padding = model.get('padding');
    return padding != null
        ? padding
        // We give slightly different to look pretty.
        : renderMode === 'richText'
        ? [8, 10]
        : 10;
}

/**
 * The major feature is generate styles for `renderMode: 'richText'`.
 * But it also serves `renderMode: 'html'` to provide
 * "renderMode-independent" API.
 */
export class TooltipMarkupStyleCreator {
    readonly richTextStyles: Dictionary<Dictionary<unknown>> = {};

    // Notice that "generate a style name" usuall happens repeatly when mouse moving and
    // displaying a tooltip. So we put the `_nextStyleNameId` as a member of each creator
    // rather than static shared by all creators (which will cause it increase to fast).
    private _nextStyleNameId: number = getRandomIdBase();

    private _generateStyleName() {
        return '__EC_aUTo_' + this._nextStyleNameId++;
    }

    makeTooltipMarker(
        markerType: TooltipMarkerType,
        colorStr: ColorString,
        renderMode: TooltipRenderMode
    ): string {
        const markerId = renderMode === 'richText'
            ? this._generateStyleName()
            : null;
        const marker = getTooltipMarker({
            color: colorStr,
            type: markerType,
            renderMode,
            markerId: markerId
        });
        if (isString(marker)) {
            return marker;
        }
        else {
            if (__DEV__) {
                assert(markerId);
            }
            this.richTextStyles[markerId] = marker.style;
            return marker.content;
        }
    }

    /**
     * @usage
     * ```ts
     * const styledText = markupStyleCreator.wrapRichTextStyle([
     *     // The styles will be auto merged.
     *     {
     *         fontSize: 12,
     *         color: 'blue'
     *     },
     *     {
     *         padding: 20
     *     }
     * ]);
     * ```
     */
    wrapRichTextStyle(text: string, styles: Dictionary<unknown> | Dictionary<unknown>[]): string {
        const finalStl = {};
        if (isArray(styles)) {
            each(styles, stl => extend(finalStl, stl));
        }
        else {
            extend(finalStl, styles);
        }
        const styleName = this._generateStyleName();
        this.richTextStyles[styleName] = finalStl;
        return `{${styleName}|${text}}`;
    }
}
