/*
* 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, CommonTooltipOption, OptionDataValue
} 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: Record<GapLevel, number> = [0, 10, 20, 30];
const RICH_TEXT_GAPS: Record<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;
}

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;

    valueFormatter?: CommonTooltipOption<unknown>['valueFormatter']
}

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;

    valueFormatter?: CommonTooltipOption<unknown>['valueFormatter']
}

/**
 * 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 {
    (
        ctx: TooltipMarkupBuildContext,
        fragment: TooltipMarkupBlockFragment,
        topMarginForOuterGap: number,
        toolTipTextStyle: TooltipOption['textStyle']
    ): MarkupText;
}

function isSectionFragment(frag: TooltipMarkupBlockFragment): frag is TooltipMarkupSection {
    return frag.type === 'section';
}

function getBuilder(frag: TooltipMarkupBlockFragment): TooltipMarkupFragmentBuilder {
    return isSectionFragment(frag) ? buildSection : buildNameValue;
}

function getBlockGapLevel(frag: TooltipMarkupBlockFragment) {
    if (isSectionFragment(frag)) {
        let gapLevel = 0;
        const subBlockLen = frag.blocks.length;
        const hasInnerGap = subBlockLen > 1 || (subBlockLen > 0 && !frag.noHeader);
        each(frag.blocks, function (subBlock) {
            const subGapLevel = getBlockGapLevel(subBlock);
            // 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 >= gapLevel) {
                gapLevel = subGapLevel + (
                    +(
                        hasInnerGap && (
                            // 0 always can not be readable gap level.
                            !subGapLevel
                            // If no header, always keep the sub gap level. Otherwise
                            // look weird in case `multipleSeries`.
                            || (isSectionFragment(subBlock) && !subBlock.noHeader)
                        )
                    )
                );
            }
        });
        return gapLevel;
    }
    return 0;
}

function buildSection(
    ctx: TooltipMarkupBuildContext,
    fragment: TooltipMarkupSection,
    topMarginForOuterGap: number,
    toolTipTextStyle: TooltipOption['textStyle']
) {
    const noHeader = fragment.noHeader;

    const gaps = getGap(getBlockGapLevel(fragment));

    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();
        }
    }

    each(subBlocks, function (subBlock, idx) {
        const valueFormatter = fragment.valueFormatter;
        const subMarkupText = getBuilder(subBlock)(
            // Inherit valueFormatter
            valueFormatter ? extend(extend({}, ctx), { valueFormatter }) : ctx,
            subBlock,
            idx > 0 ? gaps.html : 0,
            toolTipTextStyle
        );
        subMarkupText != null && subMarkupTextList.push(subMarkupText);
    });

    const subMarkupText = ctx.renderMode === 'richText'
        ? subMarkupTextList.join(gaps.richText)
        : wrapBlockHTML(
            subMarkupTextList.join(''),
            noHeader ? topMarginForOuterGap : gaps.html
        );

    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
        );
    }
}

function buildNameValue(
    ctx: TooltipMarkupBuildContext,
    fragment: TooltipMarkupNameValueBlock,
    topMarginForOuterGap: number,
    toolTipTextStyle: TooltipOption['textStyle']
) {
    const renderMode = ctx.renderMode;
    const noName = fragment.noName;
    const noValue = fragment.noValue;
    const noMarker = !fragment.markerType;
    const name = fragment.name;
    const useUTC = ctx.useUTC;
    const valueFormatter = fragment.valueFormatter || ctx.valueFormatter || ((value) => {
        value = isArray(value) ? value : [value];
        return map(value as unknown[], (val, idx) => makeValueReadable(
            val, isArray(valueTypeOption) ? valueTypeOption[idx] : valueTypeOption, 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 ? [] : valueFormatter(fragment.value as OptionDataValue);
    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
        );
}

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

    valueFormatter: CommonTooltipOption<unknown>['valueFormatter']
}

/**
 * @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);
    const ctx: TooltipMarkupBuildContext = {
        useUTC: useUTC,
        renderMode: renderMode,
        orderMode: orderMode,
        markupStyleCreator: markupStyleCreator,
        valueFormatter: fragment.valueFormatter
    };
    return builder(ctx, fragment, 0, toolTipTextStyle);
}


function getGap(gapLevel: number): {
    html: number;
    richText: string
} {
    return {
        html: HTML_GAPS[gapLevel],
        richText: RICH_TEXT_GAPS[gapLevel]
    };
}

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 | 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}` : '';
    valueList = isArray(valueList) ? valueList : [valueList];
    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,
    values: string | 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(
        isArray(values) ? values.join('  ') : values,
        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}}`;
    }
}
