import { NodeInfoOverlay } from "./components/nodeinfo";

import React from "react";
import screenfull from "screenfull";
import { GraphRenderer } from "./renderer";
import * as Helpers from "./helpers";
import Graph from "./graph";
import { loadGraphJson } from "../datasets";
import PropTypes, { InferType } from "prop-types";

class Display extends React.Component<
    InferType<typeof Display.propTypes>,
    InferType<typeof Display.stateTypes>
> {
    props: InferType<typeof Display.propTypes>;
    state: InferType<typeof Display.stateTypes>;

    infoOverlay: NodeInfoOverlay;
    sceneNode: HTMLElement;
    fullscreenRef: React.RefObject<HTMLDivElement>;

    static propTypes = {
        spaceId: PropTypes.string.isRequired,
    };

    static stateTypes = {
        graph: Graph,
        width: PropTypes.number,
        height: PropTypes.number,
    };

    constructor(props: InferType<typeof Display.propTypes>) {
        super(props);
        this.fullscreenRef = React.createRef();
        this.state = {
            graph: null,
            width: 0,
            height: 0,
        };
    }

    componentDidMount() {
        this.setState({
            width: Helpers.getWidth(),
            height: Helpers.getHeight(),
        });

        const fetchGraph = async () => {
            const graphData = await loadGraphJson(this.props.spaceId);
            const graph = new Graph(graphData.nodes, graphData.links);
            this.setState({ graph: graph });
        };
        fetchGraph();

        // this.infoOverlay = new NodeInfoOverlay(this.graph);
    }

    /**
     * Callback which is called when the underlying graph has finished loading
     * its content
     */
    loadGraphComponents() {
        // this.infoOverlay.create();
        // this.sceneNode = document.getElementById("kg-display");
        /*
         * This call is necessary since the graph can only load after the
         * component has mounted (the graph requires a fixed <div> element),
         * but some components rely on the graph being loaded.
         * The fix is to exclude all components from rendering until the graph
         * finished loading.
         * TODO: Once all components have been transformed to react components
         *  this call could be substituted by changing the object state (which
         *  causes a re-render)
         */
        // this.forceUpdate();
        // filterOverlay.filterChangedCallback = (cls) =>
        //     infoOverlay.bottomMenu.toggleTabVisibility(cls);
        // createFullScreenButton();
    }

    toggleFullscreen() {
        if (screenfull.isEnabled) {
            if (!screenfull.isFullscreen) {
                this.setState({
                    width: screen.width,
                    height: screen.height,
                });
            } else {
                this.setState({
                    width: Helpers.getWidth(),
                    height: Helpers.getHeight(),
                });
            }

            screenfull.toggle(this.fullscreenRef.current);
        } else {
            console.log("No fullscreen mode available :(");
        }
    }

    render() {
        return (
            <div
                id="kg-display"
                style={{ position: "relative" }}
                ref={this.fullscreenRef}
            >
                <div
                    className={"fullscreen-button no-select"}
                    title={"Vollbild"}
                    onClick={this.toggleFullscreen.bind(this)}
                >
                    <p>&#10530;</p>
                </div>
                {/*{this.graph && (*/}
                {/*    <FilterOverlay graph={this.graph} type={"node"} />*/}
                {/*)}*/}
                <div id="3d-graph">
                    {this.state.graph && (
                        <GraphRenderer
                            graph={this.state.graph}
                            width={this.state.width}
                            height={this.state.height}
                        />
                    )}
                </div>
            </div>
        );
    }
}

export default Display;