import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import { killWorkerScript } from "../src/Netscript/killWorkerScript";
import { RunningScript } from "../src/Script/RunningScript";

import { createElement } from "./uiHelpers/createElement";
import { removeElementById } from "./uiHelpers/removeElementById";

let gameContainer: HTMLElement;

(function() {
    function getGameContainer(): void {
        const container = document.getElementById("entire-game-container");
        if (container == null) {
            throw new Error(`Failed to find game container DOM element`)
        }

        gameContainer = container;
        document.removeEventListener("DOMContentLoaded", getGameContainer);
    }

    document.addEventListener("DOMContentLoaded", getGameContainer);
})();

interface IProps {
    script: RunningScript;
    container: HTMLElement;
    id: string;
}

function ScriptLogPopup(props: IProps): React.ReactElement {
    const setRerender = useState(false)[1];

    function rerender(): void {
        setRerender(old => !old);
    }

    useEffect(() => {
        const id = setInterval(rerender, 1000);
        return () => clearInterval(id);
    }, []);


    function close(): void {
        const content = document.getElementById(props.id);
        if (content == null) return;
        ReactDOM.unmountComponentAtNode(content);
        removeElementById(props.id);
    }

    useEffect(() => {
        function closeHandler(event: KeyboardEvent) {
            if(event.keyCode === 27) {
                close();
            }
        }

        document.addEventListener('keydown', closeHandler);

        return () => {
            document.removeEventListener('keydown', closeHandler);
        }
    }, []);

    function kill(): void {
        killWorkerScript(props.script, props.script.server, true);
        close();
    }

    function drag(event: React.MouseEvent<HTMLElement, MouseEvent>): void {
        event.preventDefault();
        let x = event.clientX;
        let y = event.clientY;
        let left = props.container.offsetLeft+props.container.clientWidth/2;
        let top = props.container.offsetTop+props.container.clientWidth/5;
        function mouseMove(event: MouseEvent): void {
            left+=event.clientX-x;
            top+=event.clientY-y;
            props.container.style.left=left+'px';
            props.container.style.top=top+'px';
            // reset right and bottom to avoid the window stretching
            props.container.style.right='';
            props.container.style.bottom='';
            x=event.clientX;
            y=event.clientY;
        }
        function mouseUp(): void {
            document.removeEventListener('mouseup', mouseUp)
            document.removeEventListener('mousemove', mouseMove)
        }
        document.addEventListener('mouseup', mouseUp)
        document.addEventListener('mousemove', mouseMove)
    }

    return (<>
        <div className="log-box-header" onMouseDown={drag}>
            <p>{props.script.filename} {props.script.args.map((x: any): string => `${x}`).join(' ')}</p>
            <div>
                <button className="log-box-button" onClick={kill}>Kill Script</button>
                <button className="log-box-button" onClick={close}>Close</button>
            </div>
        </div>
        <div className="log-box-log-container">
            <p>{props.script.logs.map((line: string, i: number): JSX.Element => <span key={i} style={{whiteSpace: "pre-line"}}>{line}<br /></span>)}</p>
        </div>
    </>);
}

export function logBoxCreate(script: RunningScript): void {
    const id = script.server+"-"+script.filename+script.args.map((x: any): string => `${x}`).join('-');
    if(document.getElementById(id) !== null) return;
    const container = createElement("div", {
        class: "log-box-container",
        id: id,
    });
    gameContainer.appendChild(container);
    ReactDOM.render(<ScriptLogPopup script={script} id={id} container={container} />, container);
}