import React from "react";
import {
    createStyles,
    CssBaseline,
    Divider,
    Drawer,
    Fab,
    IconButton,
    Theme,
    Tooltip, withStyles
} from "@material-ui/core";
import clsx from "clsx";
import {Map} from "./Map";
import MenuIcon from "@material-ui/icons/Menu";
import ChevronLeftIcon from "@material-ui/icons/ChevronLeft";
import {OGC3DContainerLayer} from "./layers/OGC3DContainerLayer";
import {STALayer} from "./layers/STALayer";

const SIDEBAR_WIDTH = 300;

const styles = (theme: Theme) => createStyles({
    root: {
        display: "flex",
        width: "100%"
    },
    menuButton: {
        position: "absolute",
        "z-index": 1000,
        left: 30,
        top: 14,
        backgroundColor: "ghostwhite"
    },
    hide: {
        display: "none",
    },
    drawer: {
        width: SIDEBAR_WIDTH,
        flexShrink: 0
    },
    drawerPaper: {
        width: SIDEBAR_WIDTH,
        backgroundColor: "#f6f6f6"
    },
    drawerHeader: {
        display: "flex",
        alignItems: "center",
        padding: theme.spacing(0, 1),
        // necessary for content to be below app bar
        justifyContent: "flex-end",
    },
    content: {
        flexGrow: 1,
        backgroundColor: "#defff4",
        transition: theme.transitions.create("margin", {
            easing: theme.transitions.easing.sharp,
            duration: theme.transitions.duration.leavingScreen,
        }),
        marginLeft: -SIDEBAR_WIDTH,
    },
    contentShift: {
        transition: theme.transitions.create("margin", {
            easing: theme.transitions.easing.easeOut,
            duration: theme.transitions.duration.enteringScreen
        }),
        marginLeft: 0
    },
});

type SidebarProps = { classes: any }
type SidebarState = {
    isOpen: boolean;
    map: Map | null
};

class SidebarClass extends React.Component<SidebarProps, SidebarState> {

    constructor(props: SidebarProps) {
        super(props);
        this.state = {
            isOpen: false,
            map: null
        };
    }

    private handleDrawerToggle() {
        this.setState(state => ({isOpen: !state.isOpen}));
    }

    render() {
        return (<div className={this.props.classes.root}>
            <CssBaseline/>
            <Tooltip title="Menu">
                <Fab
                    color="inherit"
                    size={"small"}
                    aria-label="open drawer"
                    onClick={this.handleDrawerToggle.bind(this)}
                    className={clsx(this.props.classes.menuButton, this.state.isOpen && this.props.classes.hide)}
                >
                    <MenuIcon/>
                </Fab>
            </Tooltip>
            <Drawer
                className={this.props.classes.drawer}
                classes={{
                    paper: this.props.classes.drawerPaper,
                }}
                variant={"persistent"}
                anchor={"left"}
                open={this.state.isOpen}
                onClose={this.handleDrawerToggle.bind(this)}
                ModalProps={{
                    keepMounted: true, // Better open performance on mobile.
                }}
            >
                <div className={this.props.classes.drawerHeader}>
                    <IconButton onClick={this.handleDrawerToggle.bind(this)}>
                        <ChevronLeftIcon/>
                    </IconButton>
                </div>
                <Divider/>
                {this.state.map ?
                    [
                        <OGC3DContainerLayer
                            key={"ogc-layer"}
                            onTilesetAdded={this.state.map.showTileset.bind(this.state.map)}
                            onTilesetRemoved={this.state.map.hideTileset.bind(this.state.map)}
                            getVisibleItemsIds={this.state.map.getVisibleItemsIds.bind(this.state.map)}
                            flyToTileset={this.state.map.flyToTileset.bind(this.state.map)}
                        />,
                        <STALayer
                            key={"traffic-layer"}
                            onTrafficLayerAdded={this.state.map.showTrafficLayer.bind(this.state.map)}
                            onTrafficLayerRemoved={this.state.map.hideTrafficLayer.bind(this.state.map)}
                            onColorByStrategyChanged={this.state.map.onColorByStrategyChanged.bind(this.state.map)}
                            onColorByAqiChanged={this.state.map.onColorByAqiChanged.bind(this.state.map)}
                            onPMLayerAdded={this.state.map.showPMLayer.bind(this.state.map)}
                            addLoadingId={this.state.map.addCustomLoadingId.bind(this.state.map)}
                            removeLoadingId={this.state.map.removeLoadingId.bind(this.state.map)}
                            showSnackbar={this.state.map.showSnackbar.bind(this.state.map)}
                        />
                    ]
                    : null}
            </Drawer>
            <main
                className={clsx(this.props.classes.content, {
                    [this.props.classes.contentShift]: this.state.isOpen
                })}>
                <Map ref={map => {
                    if (map && !this.state.map)
                        this.setState({map});
                }}/>
            </main>
        </div>);
    }
}

export const Sidebar
    = withStyles(styles)(SidebarClass);
