'use strict';
import './styles/main.scss';
import React, {Component} from 'react';
import {Provider, Store, Emitter} from 'sbx-react-core';

import IconTab from './close.svg?jsx';
import IconClose from './close.svg?jsx';

import Dropdown from 'sbx-react-dropdown';
import News from 'sbx-react-news';

import classNames from 'classnames';

import Lang from 'components/Language';

//Containers
import TradeChart       from 'containers/TradeChart';
import History          from 'containers/Orders/HistoryOrders';
import OpenOrders       from 'containers/Orders/OpenOrders';
import PendingOrders    from 'containers/Orders/PendingOrders';
import Market           from 'containers/Market';


const GIRD_COMPONENTS = {
    TradeChart: <TradeChart/>,
    OpenOrders: <OpenOrders/>,
    PendingOrders: <PendingOrders/>,
    History: <History/>,
    Market: <Market/>,
    News: <News/>
    };

export default class Main extends Component {

    state = {
        history: true,
        style: {},
    };

    constructor(props) {
        super(props);
        let grid = {
            _version: "0.0.4",
            blockSizes: [
                {
                    width: '26%',
                    height: `100%`
                },
                {
                    height: `72%`
                },
            ],
            closed: [
                {
                    name: 'News',
                    title: <Lang>NEWS</Lang>
                },
                {
                    name: 'Heatmap',
                    title: <Lang>HEATMAP</Lang>
                }
            ],
            list: [
                {
                    active: 'Market',
                    tabs: [
                        {
                            name: 'Market',
                            title: <Lang>MARKET</Lang>,
                        }
                    ]
                },
                {
                    active: 'TradeChart',
                    tabs: [
                        {
                            name: 'TradeChart',
                            title: <Lang>CHART</Lang>,
                        }
                    ]
                },
                {
                    active: 'OpenOrders',
                    tabs: [
                        {
                            name: 'OpenOrders',
                            title: <Lang>POSITION</Lang>,
                        },
                        {
                            name: 'History',
                            title: <Lang>TRADING_HISTORY</Lang>,
                        },
                        {
                            name: 'PendingOrders',
                            title: <Lang>PENDING_ORDERS</Lang>,
                        }
                    ]
                }
            ]
        };

        let savedGrid ; //localStorage.getItem('MAIN_GRID');
        if (savedGrid) {
            savedGrid = JSON.parse(savedGrid);
            if (grid._version === savedGrid._version) {
                grid = Object.assign(grid, savedGrid);
            } else {
                localStorage.removeItem('MAIN_GRID');
            }
        }

        this.state.grid = grid;
    }

    __update = () => {
        this.forceUpdate();
    };

    componentWillMount() {
        window.addEventListener('resize', this.__update)
    }

    componentDidUpdate(prevProps, prevState, snapshot) {
        localStorage.setItem('MAIN_GRID', JSON.stringify(this.state.grid))
    }

    componentWillUnmount() {
        window.removeEventListener('resize', this.__update)
    }

    resizeView = (callBack, e) => {
        let gridSizes = this.gridElement.getBoundingClientRect();
        let targetSizes = e.target.getBoundingClientRect();
        let blockSizes = e.target.parentElement.getBoundingClientRect();
        let shiftX = e.clientX - targetSizes.left;
        let shiftY = e.clientY - targetSizes.top;
        document.body.style.pointerEvents = 'none';
        moveAt(e.pageX, e.pageY);

        function moveAt(pageX, pageY) {
            let height = (pageY - gridSizes.top) / gridSizes.height;
            let width = (pageX  - gridSizes.left - blockSizes.left) / gridSizes.width;


            if(width <= 0.25){
                width = 0.25
            }
            if(height <= 0.2){
                height = 0.2
            }
            if(height >= 0.8){
                height = 0.8
            }

            callBack({
                height: height * 100,
                width: width * 100,
            }, e);
        }


        function onMouseMove(event) {
            moveAt(event.pageX, event.pageY);
        }

        function clear(event) {
            document.body.style.pointerEvents = 'unset';
            document.removeEventListener('mousemove', onMouseMove);
            document.removeEventListener('mouseup', clear);
        }

        document.addEventListener('mousemove', onMouseMove);
        document.addEventListener('mouseup', clear);
    };

    render() {
        let {grid} = this.state;

        return <main className="main">
            <div ref={e => {
                    this.gridElement = e;
                    if (e) {
                        let blocks = e.children;
                        for (let i = 0; i < blocks.length; i++) {
                            let prevBlock = blocks[i - 1];
                            if (i > 0) {
                                blocks[i].style.left = blocks[0].style.width;
                                blocks[i].style.width = 100 - parseFloat(blocks[0].style.width) + '%';
                                if(i === 2){
                                    blocks[i].style.top =prevBlock.style.height;
                                    blocks[i].style.height = 100 - parseFloat(prevBlock.style.height) + '%';
                                }
                            } else {
                                blocks[i].style.left = 0;
                            }
                        }
                    }
                }}
                className="main__grid"
            >
                {grid.list.map(({active, tabs}, tabsIndex) => {
                    let activeTab = tabs.find(i => i.name === active) || tabs[0];
                    let isEmpty = tabs.length === 0;
                    return <div
                        key={`block_${tabsIndex}`}
                        ref={e => this[`block_${tabsIndex}`] = e}
                        style={{
                            ...grid.blockSizes[tabsIndex] || {}
                        }}
                        className={classNames({
                            'mainBlock': true,
                        })}
                    >
                        <div className="mainBlock__tabs">
                            {!isEmpty && tabs.map((tab, index) => {
                                let isActive = tab.name === activeTab.name;
                                return <div
                                    key={index}
                                    className={classNames({
                                        mainBlock__tabsItem: true,
                                        mainBlock__tabsItem_active: isActive,
                                    })}
                                    onClick={e => {
                                        Emitter.emit('sound','tab');
                                        grid.list[tabsIndex].active = tab.name;
                                        this.setState({grid});
                                    }}
                                    draggable={true}
                                    onDragStart={e => {
                                        this.dragData = {tab, index, tabsIndex};
                                    }}
                                    onDragOver={e => {
                                        e.stopPropagation();
                                        e.preventDefault();
                                    }}
                                    onDragEnter={e => {
                                        if (this.dragData.tab.name !== tab.name)
                                            e.currentTarget.classList.add('mainBlock__tabsItem_drag');
                                    }}
                                    onDragLeave={e => {
                                        e.currentTarget.classList.remove('mainBlock__tabsItem_drag')
                                    }}
                                    onDrop={e => {
                                        if (this.dragData.tab.name !== tab.name) {
                                            e.currentTarget.classList.remove('mainBlock__tabsItem_drag');
                                            let data = this.dragData;
                                            grid.list[data.tabsIndex].tabs.splice(data.index, 1);
                                            grid.list[tabsIndex].active = data.tab.name;
                                            grid.list[tabsIndex].tabs.splice(index - 1, 0, data.tab);
                                            this.setState({grid});
                                        }
                                    }}
                                >
                                    {tab.title}
                                    {isActive && <React.Fragment>
                                        <IconClose
                                            className="mainBlock__tabsItemIcon"
                                            onClick={e => {
                                                Emitter.emit('sound','tab');
                                                grid.closed.push(tab);
                                                grid.list[tabsIndex].tabs.splice(index, 1);
                                                if (index)
                                                    grid.list[tabsIndex].active = grid.list[tabsIndex].tabs[index - 1].name;
                                                this.setState({grid});
                                            }}
                                        />
                                    </React.Fragment>}
                                </div>
                            })}
                            {grid.closed.length !== 0 && <Dropdown
                                position="bottom_left"
                                ref={e => this['dropdown_' + tabsIndex] = e}
                                data={<ul className="mainBlock__tabsClosedList list-box">
                                    {grid.closed.map((closedItem, index) => {
                                        return <li
                                            key={index + '_closed'}
                                            onClick={e => {
                                                grid.closed.splice(index, 1);
                                                grid.list[tabsIndex].tabs.push(closedItem);
                                                grid.list[tabsIndex].active = closedItem.name;
                                                this['dropdown_' + tabsIndex].hide();
                                                this.setState({grid})
                                            }}
                                        >
                                            <a>{closedItem.title}</a>
                                        </li>
                                    })}
                                </ul>}
                            >
                                <div
                                    className="mainBlock__tabsItem mainBlock__tabsItem_add"
                                    onDragOver={e => {
                                        e.stopPropagation();
                                        e.preventDefault();
                                    }}
                                    onDragEnter={e => {
                                        e.currentTarget.classList.add('mainBlock__tabsItem_drag');
                                    }}
                                    onDragLeave={e => {
                                        e.currentTarget.classList.remove('mainBlock__tabsItem_drag')
                                    }}
                                    onDrop={e => {
                                        e.currentTarget.classList.remove('mainBlock__tabsItem_drag');
                                        let data = this.dragData;
                                        grid.list[data.tabsIndex].tabs.splice(data.index, 1);
                                        grid.list[tabsIndex].active = data.tab.name;
                                        grid.list[tabsIndex].tabs.splice(tabs.length, 0, data.tab);
                                        this.setState({grid});
                                    }}
                                >
                                    +
                                </div>
                            </Dropdown>}
                        </div>
                        <div className="mainBlock__content">
                            {isEmpty ? <div className="mainBlock__tabsEmpty">
                                <h3><Lang>CONTAINER_EMPTY</Lang></h3>
                                {/*<h3>This container is empty</h3>*/}
                                <p> <Lang>CONTAINER_EMPTY_DESC</Lang></p>
                                {/*<p>Please add a module by pressing '+' button or change the layout by pressing the*/}
                                    {/*button in the upper part of the platform.</p>*/}
                            </div> : GIRD_COMPONENTS[activeTab.name]}
                        </div>
                        {tabsIndex === 0 && <div
                            className="mainBlock__split mainBlock__split_v mainBlock__split_right"
                            onMouseDown={this.resizeView.bind(this, ({width}) => {
                                grid.blockSizes[tabsIndex].width = width + '%';
                                this.setState({grid});
                            })}
                        />}

                        {tabsIndex === 1 && <div
                            className="mainBlock__split mainBlock__split_h mainBlock__split_bottom"
                            onMouseDown={this.resizeView.bind(this, ({height}) => {
                                grid.blockSizes[tabsIndex].height = height + '%';
                                this.setState({grid});
                            })}
                        />}
                    </div>
                })}
            </div>
        </main>;
    }
}

