class InternalToolResult extends React.Component {
    render() {
        let message = '';
        if (this.props.message) {
            message = (
                <div className="row">
                    <div className="col-sm-12">
                        <p className="it-pre-formatted-text">
                            {this.props.message}
                        </p>
                    </div>
                </div>
            );
        }
        let tableData = '';
        if (!$.isEmptyObject(this.props.data)) {
            tableData = (
                <div className="row">
                    <div className="col-sm-12">
                        {this.renderTableResult()}
                    </div>
                </div>
            );
        }

        return (
            <div>
                {message}
                {tableData}
            </div>
        );
    }

    renderTableResult() {
        let objectHash = this.props.data[0];
        let headerComponents = this.generateHeaders(objectHash);
        let rowComponents = this.generateRows(objectHash);
        return (
            <table className="table table-striped table-condensed table-hover table-responsive table-bordered">
                <thead> {headerComponents} </thead>
                <tbody> {rowComponents} </tbody>
            </table>
        );
    }

    generateHeaders(objectHash) {
        return <tr> {Object.keys(objectHash).map(key => <th key={key}> {key} </th>)} </tr>;
    }

    generateRows(objectHash) {
        let cols = Object.keys(objectHash);
        let data = this.props.data;
        let details = this.props.details;

        let haveEnrichDetails = !$.isEmptyObject(details);

        return data.map(function (item) {
            let cells = cols.map(function (key) {
                if (haveEnrichDetails && details.hasOwnProperty(key)) {
                    return <td>{InternalToolResult.enrichCell(details, key, item)}</td>;
                }

                let value = item[key];
                if (value != null && Array.isArray(value)) {
                    return <td>{value.join(",\u2009")}</td>;
                }
                if (value != null && typeof value === "object") {
                    return <td>{Object.keys(value).sort().map(k => k + "=" + value[k]).join(",\u2009")}</td>;
                }

                return <td>{value !== null ? value.toString() : ""} </td>;
            });
            return <tr key={item.id}> {cells} </tr>;
        });
    }

    static enrichCell(details, key, item) {
        switch (details[key].category) {
            //Простая замена
            case "COMMON_REPLACE":
                return details[key].data[item[key]];

            //Данные о пользователе имя + логин с ссылкой
            case "USER":
                return <span>{JSON.stringify(details[key].data[item[key]])}
                    ({InternalToolResult.getClientsCampaignHref(details[key].data[item[key]].login,
                        details[key].data[item[key]].login)})</span>;

            //Ссылка на страницу кампаний пользователя
            case "CLIENT_CAMPAIGNS_LINK_REPLACE":
                return <span>
                    {InternalToolResult.getClientsCampaignHref(details[key].data[item[key]], item[key])}</span>;

            //Замена на ссылку
            case "LINK_REPLACE":
                return <span>{InternalToolResult.getHref(item[key], details[key].data[item[key]], '_blank')}</span>;

            //Замена ссылки на короткую ссылку
            case "LINK_NAME_REPLACE":
                return <span>{InternalToolResult.getHref(details[key].data[item[key]], item[key], '_blank')}</span>;

            case "HIGHLIGHT":
                return <span style={{color: details[key].data[item[key]]}}>{item[key]}</span>;

            case "JSON_PRETTIFY":
                return <pre><code className="javascript">{JSON.stringify(JSON.parse(item[key]), null, "\t")}</code></pre>;

            case "DIFF":
                return <pre><code className="diff">{item[key]}</code></pre>;

            case "EXPANDER":
                return <ExpanderCell text={item[key]} />;

            case "HTML_PRETTIFY":
                return <HTMLPrettifyCell text={item[key]} />;

            //Без улучшений
            default:
                return item[key];
        }
    }

    static getHref(text, url, target, changeVisited) {
        if (changeVisited) {
            return <a href={url} target={target} onClick={() => InternalToolResult.markVisited(url)}>{text}</a>
        } else {
            return <a href={url} target={target}>{text}</a>
        }
    }

    static markVisited(url) {
        history.replaceState({}, '', url);
        history.replaceState({}, '', window.location.href);
    }

    static getClientsCampaignHref(text, login) {
        return InternalToolResult.getHref(text, '/registered/main.pl?cmd=showCamps&ulogin=' + login, '_blank', true)
    }
}

const MAX_EXPANDER_TEXT_LENGTH = 200;

class ExpanderCell extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            isOpened: false
        };
    }

    toggleSwitcher() {
        this.setState({
            isOpened: !this.state.isOpened
        });
    };

    copyToClipboard() {
        let el = document.createElement('textarea');

        el.value = this.props.text;
        el.setAttribute('readonly', '');
        el.style.position = 'absolute';
        el.style.left = '-9999px';

        document.body.appendChild(el);
        const selected = document.getSelection().rangeCount > 0
            ? document.getSelection().getRangeAt(0)
            : false;
        el.select();

        const copied = document.execCommand('copy');
        document.body.removeChild(el);
        if (selected) {
            document.getSelection().removeAllRanges();
            document.getSelection().addRange(selected);
        }

        return copied
    };

    render() {
        const text = this.props.text || '';
        const needSwitcher = text && text.length > MAX_EXPANDER_TEXT_LENGTH;

        return (
            <div className={'expander-cell'}>
                <span
                    className={[
                        'expander-cell__text',
                        this.state.isOpened || !needSwitcher ?
                            'expander-cell__text_open_yes' :
                            'expander-cell__text_open_no'
                    ].join(' ')}
                >
                    {
                        this.state.isOpened || !needSwitcher ?
                            text :
                            text.slice(0, MAX_EXPANDER_TEXT_LENGTH)
                    }
                </span>
                <div className={'expander-cell__buttons'}>
                    <div
                        className={'expander-cell__copy'}
                        title={'Copy to clipboard'}
                        onClick={this.copyToClipboard.bind(this)}
                    >copy</div>
                    {needSwitcher && <div
                        className={'expander-cell__switcher'}
                        title={'Uncollapse value'}
                        onClick={this.toggleSwitcher.bind(this)}
                    >...</div>}
                </div>
            </div>
        );
    }

}

class HTMLPrettifyCell extends React.Component {
    copyToClipboard() {
        let el = document.createElement('textarea');

        el.value = this.props.text;
        el.setAttribute('readonly', '');
        el.style.position = 'absolute';
        el.style.left = '-9999px';

        document.body.appendChild(el);
        const selected = document.getSelection().rangeCount > 0
            ? document.getSelection().getRangeAt(0)
            : false;
        el.select();

        const copied = document.execCommand('copy');
        document.body.removeChild(el);
        if (selected) {
            document.getSelection().removeAllRanges();
            document.getSelection().addRange(selected);
        }

        return copied
    };

    render() {
        const text = this.props.text || '';

        return (
            <div className={'html-cell'}>
                <pre><code className="html">{text}</code></pre>
                <div className={'html-cell__buttons'}>
                    <div
                        className={'html-cell__copy'}
                        title={'Copy to clipboard'}
                        onClick={this.copyToClipboard.bind(this)}
                    >copy</div>
                </div>
            </div>
        );
    }

}
