/*
* 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.
*/

/* global document */

import * as echarts from '../../../core/echarts';
import * as zrUtil from 'zrender/src/core/util';
import GlobalModel from '../../../model/Global';
import SeriesModel from '../../../model/Series';
import { ToolboxFeature, ToolboxFeatureOption } from '../featureManager';
import { ColorString, ECUnitOption, SeriesOption, Payload, Dictionary } from '../../../util/types';
import ExtensionAPI from '../../../core/ExtensionAPI';
import { addEventListener } from 'zrender/src/core/event';
import Axis from '../../../coord/Axis';
import Cartesian2D from '../../../coord/cartesian/Cartesian2D';
import { warn } from '../../../util/log';

/* global document */

const BLOCK_SPLITER = new Array(60).join('-');
const ITEM_SPLITER = '\t';

type DataItem = {
    name: string
    value: number[] | number
};

type DataList = (DataItem | number | number[])[];

interface ChangeDataViewPayload extends Payload {
    newOption: {
        series: SeriesOption[]
    }
}

interface SeriesGroupMeta {
    axisDim: string
    axisIndex: number
}

interface SeriesGroup {
    series: SeriesModel[]
    categoryAxis: Axis
    valueAxis: Axis
}

/**
 * Group series into two types
 *  1. on category axis, like line, bar
 *  2. others, like scatter, pie
 */
function groupSeries(ecModel: GlobalModel) {
    const seriesGroupByCategoryAxis: Dictionary<SeriesGroup> = {};
    const otherSeries: SeriesModel[] = [];
    const meta: SeriesGroupMeta[] = [];
    ecModel.eachRawSeries(function (seriesModel) {
        const coordSys = seriesModel.coordinateSystem;

        if (coordSys && (coordSys.type === 'cartesian2d' || coordSys.type === 'polar')) {
            // TODO: TYPE Consider polar? Include polar may increase unecessary bundle size.
            const baseAxis = (coordSys as Cartesian2D).getBaseAxis();
            if (baseAxis.type === 'category') {
                const key = baseAxis.dim + '_' + baseAxis.index;
                if (!seriesGroupByCategoryAxis[key]) {
                    seriesGroupByCategoryAxis[key] = {
                        categoryAxis: baseAxis,
                        valueAxis: coordSys.getOtherAxis(baseAxis),
                        series: []
                    };
                    meta.push({
                        axisDim: baseAxis.dim,
                        axisIndex: baseAxis.index
                    });
                }
                seriesGroupByCategoryAxis[key].series.push(seriesModel);
            }
            else {
                otherSeries.push(seriesModel);
            }
        }
        else {
            otherSeries.push(seriesModel);
        }
    });

    return {
        seriesGroupByCategoryAxis: seriesGroupByCategoryAxis,
        other: otherSeries,
        meta: meta
    };
}

/**
 * Assemble content of series on cateogory axis
 * @inner
 */
function assembleSeriesWithCategoryAxis(groups: Dictionary<SeriesGroup>): string {
    const tables: string[] = [];
    zrUtil.each(groups, function (group, key) {
        const categoryAxis = group.categoryAxis;
        const valueAxis = group.valueAxis;
        const valueAxisDim = valueAxis.dim;

        const headers = [' '].concat(zrUtil.map(group.series, function (series) {
            return series.name;
        }));
        // @ts-ignore TODO Polar
        const columns = [categoryAxis.model.getCategories()];
        zrUtil.each(group.series, function (series) {
            const rawData = series.getRawData();
            columns.push(series.getRawData().mapArray(rawData.mapDimension(valueAxisDim), function (val) {
                return val;
            }));
        });
        // Assemble table content
        const lines = [headers.join(ITEM_SPLITER)];
        for (let i = 0; i < columns[0].length; i++) {
            const items = [];
            for (let j = 0; j < columns.length; j++) {
                items.push(columns[j][i]);
            }
            lines.push(items.join(ITEM_SPLITER));
        }
        tables.push(lines.join('\n'));
    });
    return tables.join('\n\n' + BLOCK_SPLITER + '\n\n');
}

/**
 * Assemble content of other series
 */
function assembleOtherSeries(series: SeriesModel[]) {
    return zrUtil.map(series, function (series) {
        const data = series.getRawData();
        const lines = [series.name];
        const vals: string[] = [];
        data.each(data.dimensions, function () {
            const argLen = arguments.length;
            const dataIndex = arguments[argLen - 1];
            const name = data.getName(dataIndex);
            for (let i = 0; i < argLen - 1; i++) {
                vals[i] = arguments[i];
            }
            lines.push((name ? (name + ITEM_SPLITER) : '') + vals.join(ITEM_SPLITER));
        });
        return lines.join('\n');
    }).join('\n\n' + BLOCK_SPLITER + '\n\n');
}

function getContentFromModel(ecModel: GlobalModel) {

    const result = groupSeries(ecModel);

    return {
        value: zrUtil.filter([
                assembleSeriesWithCategoryAxis(result.seriesGroupByCategoryAxis),
                assembleOtherSeries(result.other)
            ], function (str) {
                return !!str.replace(/[\n\t\s]/g, '');
            }).join('\n\n' + BLOCK_SPLITER + '\n\n'),

        meta: result.meta
    };
}


function trim(str: string) {
    return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}
/**
 * If a block is tsv format
 */
function isTSVFormat(block: string): boolean {
    // Simple method to find out if a block is tsv format
    const firstLine = block.slice(0, block.indexOf('\n'));
    if (firstLine.indexOf(ITEM_SPLITER) >= 0) {
        return true;
    }
}

const itemSplitRegex = new RegExp('[' + ITEM_SPLITER + ']+', 'g');
/**
 * @param {string} tsv
 * @return {Object}
 */
function parseTSVContents(tsv: string) {
    const tsvLines = tsv.split(/\n+/g);
    const headers = trim(tsvLines.shift()).split(itemSplitRegex);

    const categories: string[] = [];
    const series: {name: string, data: string[]}[] = zrUtil.map(headers, function (header) {
        return {
            name: header,
            data: []
        };
    });
    for (let i = 0; i < tsvLines.length; i++) {
        const items = trim(tsvLines[i]).split(itemSplitRegex);
        categories.push(items.shift());
        for (let j = 0; j < items.length; j++) {
            series[j] && (series[j].data[i] = items[j]);
        }
    }
    return {
        series: series,
        categories: categories
    };
}

function parseListContents(str: string) {
    const lines = str.split(/\n+/g);
    const seriesName = trim(lines.shift());

    const data: DataList = [];
    for (let i = 0; i < lines.length; i++) {
        // if line is empty, ignore it.
        // there is a case that a user forgot to delete `\n`.
        const line = trim(lines[i]);
        if (!line) {
            continue;
        }
        let items = line.split(itemSplitRegex);

        let name = '';
        let value: number[];
        let hasName = false;
        if (isNaN(items[0] as unknown as number)) { // First item is name
            hasName = true;
            name = items[0];
            items = items.slice(1);
            data[i] = {
                name: name,
                value: []
            };
            value = (data[i] as DataItem).value as number[];
        }
        else {
            value = data[i] = [];
        }
        for (let j = 0; j < items.length; j++) {
            value.push(+items[j]);
        }
        if (value.length === 1) {
            hasName ? ((data[i] as DataItem).value = value[0]) : (data[i] = value[0]);
        }
    }

    return {
        name: seriesName,
        data: data
    };
}

function parseContents(str: string, blockMetaList: SeriesGroupMeta[]) {
    const blocks = str.split(new RegExp('\n*' + BLOCK_SPLITER + '\n*', 'g'));
    const newOption: ECUnitOption = {
        series: []
    };
    zrUtil.each(blocks, function (block, idx) {
        if (isTSVFormat(block)) {
            const result = parseTSVContents(block);
            const blockMeta = blockMetaList[idx];
            const axisKey = blockMeta.axisDim + 'Axis';

            if (blockMeta) {
                newOption[axisKey] = newOption[axisKey] || [];
                (newOption[axisKey] as any)[blockMeta.axisIndex] = {
                    data: result.categories
                };
                newOption.series = (newOption.series as SeriesOption[]).concat(result.series);
            }
        }
        else {
            const result = parseListContents(block);
            (newOption.series as SeriesOption[]).push(result);
        }
    });
    return newOption;
}

export interface ToolboxDataViewFeatureOption extends ToolboxFeatureOption {
    readOnly?: boolean

    optionToContent?: (option: ECUnitOption) => string | HTMLElement
    contentToOption?: (viewMain: HTMLDivElement, oldOption: ECUnitOption) => ECUnitOption

    icon?: string
    title?: string
    lang?: string[]

    backgroundColor?: ColorString

    textColor?: ColorString
    textareaColor?: ColorString
    textareaBorderColor?: ColorString

    buttonColor?: ColorString
    buttonTextColor?: ColorString
}

class DataView extends ToolboxFeature<ToolboxDataViewFeatureOption> {

    private _dom: HTMLDivElement;

    onclick(ecModel: GlobalModel, api: ExtensionAPI) {
        // FIXME: better way?
        setTimeout(() => {
            api.dispatchAction({
                type: 'hideTip'
            });
        });

        const container = api.getDom();
        const model = this.model;
        if (this._dom) {
            container.removeChild(this._dom);
        }
        const root = document.createElement('div');
        // use padding to avoid 5px whitespace
        root.style.cssText = 'position:absolute;top:0;bottom:0;left:0;right:0;padding:5px';
        root.style.backgroundColor = model.get('backgroundColor') || '#fff';

        // Create elements
        const header = document.createElement('h4');
        const lang = model.get('lang') || [];
        header.innerHTML = lang[0] || model.get('title');
        header.style.cssText = 'margin:10px 20px';
        header.style.color = model.get('textColor');

        const viewMain = document.createElement('div');
        const textarea = document.createElement('textarea');
        viewMain.style.cssText = 'overflow:auto';

        const optionToContent = model.get('optionToContent');
        const contentToOption = model.get('contentToOption');
        const result = getContentFromModel(ecModel);
        if (zrUtil.isFunction(optionToContent)) {
            const htmlOrDom = optionToContent(api.getOption());
            if (zrUtil.isString(htmlOrDom)) {
                viewMain.innerHTML = htmlOrDom;
            }
            else if (zrUtil.isDom(htmlOrDom)) {
                viewMain.appendChild(htmlOrDom);
            }
        }
        else {
            // Use default textarea
            textarea.readOnly = model.get('readOnly');
            const style = textarea.style;
            // eslint-disable-next-line max-len
            style.cssText = 'display:block;width:100%;height:100%;font-family:monospace;font-size:14px;line-height:1.6rem;resize:none;box-sizing:border-box;outline:none';
            style.color = model.get('textColor');
            style.borderColor = model.get('textareaBorderColor');
            style.backgroundColor = model.get('textareaColor');
            textarea.value = result.value;
            viewMain.appendChild(textarea);
        }

        const blockMetaList = result.meta;

        const buttonContainer = document.createElement('div');
        buttonContainer.style.cssText = 'position:absolute;bottom:5px;left:0;right:0';

        // eslint-disable-next-line max-len
        let buttonStyle = 'float:right;margin-right:20px;border:none;cursor:pointer;padding:2px 5px;font-size:12px;border-radius:3px';
        const closeButton = document.createElement('div');
        const refreshButton = document.createElement('div');

        buttonStyle += ';background-color:' + model.get('buttonColor');
        buttonStyle += ';color:' + model.get('buttonTextColor');

        const self = this;

        function close() {
            container.removeChild(root);
            self._dom = null;
        }
        addEventListener(closeButton, 'click', close);

        addEventListener(refreshButton, 'click', function () {
            if ((contentToOption == null && optionToContent != null)
                || (contentToOption != null && optionToContent == null)) {
                if (__DEV__) {
                    // eslint-disable-next-line
                    warn('It seems you have just provided one of `contentToOption` and `optionToContent` functions but missed the other one. Data change is ignored.')
                }
                close();
                return;
            }

            let newOption;
            try {
                if (zrUtil.isFunction(contentToOption)) {
                    newOption = contentToOption(viewMain, api.getOption());
                }
                else {
                    newOption = parseContents(textarea.value, blockMetaList);
                }
            }
            catch (e) {
                close();
                throw new Error('Data view format error ' + e);
            }
            if (newOption) {
                api.dispatchAction({
                    type: 'changeDataView',
                    newOption: newOption
                });
            }

            close();
        });

        closeButton.innerHTML = lang[1];
        refreshButton.innerHTML = lang[2];
        refreshButton.style.cssText =
        closeButton.style.cssText = buttonStyle;

        !model.get('readOnly') && buttonContainer.appendChild(refreshButton);
        buttonContainer.appendChild(closeButton);

        root.appendChild(header);
        root.appendChild(viewMain);
        root.appendChild(buttonContainer);

        viewMain.style.height = (container.clientHeight - 80) + 'px';

        container.appendChild(root);
        this._dom = root;
    }

    remove(ecModel: GlobalModel, api: ExtensionAPI) {
        this._dom && api.getDom().removeChild(this._dom);
    }

    dispose(ecModel: GlobalModel, api: ExtensionAPI) {
        this.remove(ecModel, api);
    }

    static getDefaultOption(ecModel: GlobalModel) {
        const defaultOption: ToolboxDataViewFeatureOption = {
            show: true,
            readOnly: false,
            optionToContent: null,
            contentToOption: null,

            // eslint-disable-next-line
            icon: 'M17.5,17.3H33 M17.5,17.3H33 M45.4,29.5h-28 M11.5,2v56H51V14.8L38.4,2H11.5z M38.4,2.2v12.7H51 M45.4,41.7h-28',
            title: ecModel.getLocaleModel().get(['toolbox', 'dataView', 'title']),
            lang: ecModel.getLocaleModel().get(['toolbox', 'dataView', 'lang']),
            backgroundColor: '#fff',
            textColor: '#000',
            textareaColor: '#fff',
            textareaBorderColor: '#333',
            buttonColor: '#c23531',
            buttonTextColor: '#fff'
        };

        return defaultOption;
    }
}

/**
 * @inner
 */
function tryMergeDataOption(newData: DataList, originalData: DataList) {
    return zrUtil.map(newData, function (newVal, idx) {
        const original = originalData && originalData[idx];
        if (zrUtil.isObject(original) && !zrUtil.isArray(original)) {
            const newValIsObject = zrUtil.isObject(newVal) && !zrUtil.isArray(newVal);
            if (!newValIsObject) {
                newVal = {
                    value: newVal
                } as DataItem;
            }
            // original data has name but new data has no name
            const shouldDeleteName = original.name != null && (newVal as DataItem).name == null;
            // Original data has option
            newVal = zrUtil.defaults((newVal as DataItem), original);
            shouldDeleteName && (delete (newVal as DataItem).name);
            return newVal;
        }
        else {
            return newVal;
        }
    });
}


// TODO: SELF REGISTERED.
echarts.registerAction({
    type: 'changeDataView',
    event: 'dataViewChanged',
    update: 'prepareAndUpdate'
}, function (payload: ChangeDataViewPayload, ecModel: GlobalModel) {
    const newSeriesOptList: SeriesOption[] = [];
    zrUtil.each(payload.newOption.series, function (seriesOpt) {
        const seriesModel = ecModel.getSeriesByName(seriesOpt.name)[0];
        if (!seriesModel) {
            // New created series
            // Geuss the series type
            newSeriesOptList.push(zrUtil.extend({
                // Default is scatter
                type: 'scatter'
            }, seriesOpt));
        }
        else {
            const originalData = seriesModel.get('data');
            newSeriesOptList.push({
                name: seriesOpt.name,
                data: tryMergeDataOption(seriesOpt.data as DataList, originalData as DataList)
            });
        }
    });

    ecModel.mergeOption(zrUtil.defaults({
        series: newSeriesOptList
    }, payload.newOption));
});

export default DataView;
