import * as React from 'react';
import { Stack, Modal, IconButton, IDragOptions, ContextualMenu } from '@fluentui/react';
import ReactEcharts from 'echarts-for-react';
import IntermediateVal from '../public-child/IntermediateVal';
import { TRIALS } from '../../static/datamodel';
import { TableRecord, Intermedia, TooltipForIntermediate } from '../../static/interface';
import { contentStyles, iconButtonStyles } from '../buttons/ModalTheme';
import '../../static/style/compare.scss';

const dragOptions: IDragOptions = {
    moveMenuItemText: 'Move',
    closeMenuItemText: 'Close',
    menu: ContextualMenu
};

// the modal of trial compare
interface CompareProps {
    compareStacks: Array<TableRecord>;
    cancelFunc: () => void;
}

class Compare extends React.Component<CompareProps, {}> {
    public _isCompareMount!: boolean;
    constructor(props: CompareProps) {
        super(props);
    }

    intermediate = (): React.ReactNode => {
        const { compareStacks } = this.props;
        const trialIntermediate: Array<Intermedia> = [];
        const idsList: string[] = [];
        compareStacks.forEach(element => {
            const trial = TRIALS.getTrial(element.id);
            trialIntermediate.push({
                name: element.id,
                data: trial.description.intermediate,
                type: 'line',
                hyperPara: trial.description.parameters
            });
            idsList.push(element.id);
        });
        // find max intermediate number
        trialIntermediate.sort((a, b) => {
            return b.data.length - a.data.length;
        });
        const legend: string[] = [];
        // max length
        const length = trialIntermediate[0] !== undefined ? trialIntermediate[0].data.length : 0;
        const xAxis: number[] = [];
        trialIntermediate.forEach(element => {
            legend.push(element.name);
        });
        for (let i = 1; i <= length; i++) {
            xAxis.push(i);
        }
        const option = {
            tooltip: {
                trigger: 'item',
                enterable: true,
                position: function(point: number[], data: TooltipForIntermediate): number[] {
                    if (data.dataIndex < length / 2) {
                        return [point[0], 80];
                    } else {
                        return [point[0] - 300, 80];
                    }
                },
                formatter: function(data: TooltipForIntermediate): React.ReactNode {
                    const trialId = data.seriesName;
                    let obj = {};
                    const temp = trialIntermediate.find(key => key.name === trialId);
                    if (temp !== undefined) {
                        obj = temp.hyperPara;
                    }
                    return (
                        '<div class="tooldetailAccuracy">' +
                        '<div>Trial ID: ' +
                        trialId +
                        '</div>' +
                        '<div>Intermediate: ' +
                        data.data +
                        '</div>' +
                        '<div>Parameters: ' +
                        '<pre>' +
                        JSON.stringify(obj, null, 4) +
                        '</pre>' +
                        '</div>' +
                        '</div>'
                    );
                }
            },
            grid: {
                left: '5%',
                top: 40,
                containLabel: true
            },
            legend: {
                type: 'scroll',
                right: 40,
                left: idsList.length > 6 ? 80 : null,
                data: idsList
            },
            xAxis: {
                type: 'category',
                // name: '# Intermediate',
                boundaryGap: false,
                data: xAxis
            },
            yAxis: {
                type: 'value',
                name: 'Metric',
                scale: true
            },
            series: trialIntermediate
        };
        return (
            <ReactEcharts
                option={option}
                style={{ width: '100%', height: 418, margin: '0 auto' }}
                notMerge={true} // update now
            />
        );
    };

    // render table column ---
    initColumn = (): React.ReactNode => {
        const idList: string[] = [];
        const sequenceIdList: number[] = [];
        const durationList: number[] = [];

        const compareStacks = this.props.compareStacks.map(tableRecord => TRIALS.getTrial(tableRecord.id));

        const parameterList: Array<object> = [];
        let parameterKeys: string[] = [];
        if (compareStacks.length !== 0) {
            parameterKeys = Object.keys(compareStacks[0].description.parameters);
        }
        compareStacks.forEach(temp => {
            idList.push(temp.id);
            sequenceIdList.push(temp.sequenceId);
            durationList.push(temp.duration);
            parameterList.push(temp.description.parameters);
        });
        let isComplexSearchSpace;
        if (parameterList.length > 0) {
            isComplexSearchSpace = typeof parameterList[0][parameterKeys[0]] === 'object' ? true : false;
        }
        const width = this.getWebUIWidth();
        let scrollClass;
        if (width > 1200) {
            scrollClass = idList.length > 3 ? 'flex' : '';
        } else if (width < 700) {
            scrollClass = idList.length > 1 ? 'flex' : '';
        } else {
            scrollClass = idList.length > 2 ? 'flex' : '';
        }
        return (
            <table className={`compare-modal-table ${scrollClass}`}>
                <tbody>
                    <tr>
                        <td className='column'>Id</td>
                        {Object.keys(idList).map(key => (
                            <td className='value idList' key={key}>
                                {idList[key]}
                            </td>
                        ))}
                    </tr>
                    <tr>
                        <td className='column'>Trial No.</td>
                        {Object.keys(sequenceIdList).map(key => (
                            <td className='value idList' key={key}>
                                {sequenceIdList[key]}
                            </td>
                        ))}
                    </tr>
                    <tr>
                        <td className='column'>Default metric</td>
                        {Object.keys(compareStacks).map(index => (
                            <td className='value' key={index}>
                                <IntermediateVal trialId={compareStacks[index].id} />
                            </td>
                        ))}
                    </tr>
                    <tr>
                        <td className='column'>duration</td>
                        {Object.keys(durationList).map(index => (
                            <td className='value' key={index}>
                                {durationList[index]}
                            </td>
                        ))}
                    </tr>
                    {isComplexSearchSpace
                        ? null
                        : Object.keys(parameterKeys).map(index => (
                              <tr key={index}>
                                  <td className='column' key={index}>
                                      {parameterKeys[index]}
                                  </td>
                                  {Object.keys(parameterList).map(key => (
                                      <td key={key} className='value'>
                                          {parameterList[key][parameterKeys[index]]}
                                      </td>
                                  ))}
                              </tr>
                          ))}
                </tbody>
            </table>
        );
    };

    getWebUIWidth = (): number => {
        return window.innerWidth;
    };

    componentDidMount(): void {
        this._isCompareMount = true;
    }

    componentWillUnmount(): void {
        this._isCompareMount = false;
    }

    render(): React.ReactNode {
        const { cancelFunc } = this.props;

        return (
            <Modal
                isOpen={true}
                containerClassName={contentStyles.container}
                className='compare-modal'
                allowTouchBodyScroll={true}
                dragOptions={dragOptions}
            >
                <div>
                    <div className={contentStyles.header}>
                        <span>Compare trials</span>
                        <IconButton
                            styles={iconButtonStyles}
                            iconProps={{ iconName: 'Cancel' }}
                            ariaLabel='Close popup modal'
                            onClick={cancelFunc}
                        />
                    </div>
                    <Stack className='compare-modal-intermediate'>
                        {this.intermediate()}
                        <Stack className='compare-yAxis'># Intermediate result</Stack>
                    </Stack>
                    <Stack>{this.initColumn()}</Stack>
                </div>
            </Modal>
        );
    }
}

export default Compare;
