import React from 'react'
import styled from 'styled-components';
import PropTypes from 'prop-types';
import {transitionTime} from '../constants'
import {TopItem,BottomItem,MainClickItem,MainHoverItem,Item} from '../items'


const Styles = styled.div`${({bottomDrawerWidth,topDrawerWidth,visibleDrawer,barBackground,navBarWidth})=>`
	display : flex;
	width: 100vw;
	height : 100%;
	table{
		height : 100%;
		border-collapse : collapse;
		tr, td{
		    padding: 0px;
		}
	}
	.dummy{
		min-width : ${navBarWidth}px;
		position : relative;
		min-height : 100%;
		z-index : 100;
		.nav-bar{
			z-index : 1;
			top : 0px;
			left : 0px;
			position : absolute;
			background : ${barBackground};
			min-height : 100%;
			transition: width ${transitionTime/1000}s ease; 
		}
		.top-drawer{
			z-index : 2;
			position : absolute;
			width : 0px;
			left : ${-1*topDrawerWidth}px;
			top : 0px;
			min-height : 100%;
			transition: left ${transitionTime/1000}s ease;
		}
		.bottom-drawer{
			z-index : -1;
			position : absolute;
			left : ${navBarWidth-bottomDrawerWidth}px;
			width : 0px;
			top : 0px;
			min-height : 100%;
			transition: left ${transitionTime/1000}s ease;
		}
		.overlay{
			z-index : -2;
			top : 0px;
			display : none;
			position : absolute;
			background : rgba(0, 0, 0, 0.3);
			min-height : 100%;
			min-width: 100vw;
			transition : opacity ${transitionTime/1000}s ease;
		}
	}
`}`


/* !!! TODO - Current transitions are brittle !!! */

class NavBar extends React.Component{
	constructor(){
		super()
		this.state = {
			visibleDrawer : null // TOP, BOTTOM, MAIN, null
		}
		this.nullFn = ()=>null
		this.renderTopDrawer = this.nullFn
		this.renderBottomDrawer = this.nullFn
		this.shouldChildrenRender = true
	}

	changeDrawer = (visibleDrawer, index) => {
		if(visibleDrawer=='TOP'){
			this.overlay.style.display = 'block'
			this.overlay.style.opacity = '0'
			requestAnimationFrame(()=>{
				this.overlay.style.opacity = '1'
			})
			this.topDrawer.style.width = this.props.topDrawerWidth+'px'
			this.hotTopIndex = index
		}
		if(visibleDrawer=='BOTTOM'){
			this.overlay.style.display = 'block'
			this.overlay.style.opacity = '0'
			requestAnimationFrame(()=>{
				this.overlay.style.opacity = '1'
			})
			this.bottomDrawer.style.width = this.props.bottomDrawerWidth+'px'
			this.hotBottomIndex = index
		}
		if(visibleDrawer==null){
			this.hotTopIndex = undefined
			this.hotBottomIndex = undefined
		}
		if(visibleDrawer=='MAIN'){

		}
		this.setState({ visibleDrawer })
	}



	navBarRef = el => {
		if(el) {
			this.navBar = el
			this.navBarWidth=el.clientWidth
		}
	}

	topDrawerRef= el => {
		if(el) {
			this.topDrawer=el
		}
	}

	bottomDrawerRef = el => {
		if(el) {
			this.bottomDrawer=el
		}
	}

	overlayRef = el => {
		if(el) {
			this.overlay=el
		}
	}

	onOverlayClick = ev => {
		this.setState({ visibleDrawer : null })
		ev.stopPropagation()
		ev.preventDefault()
	}

	render(){
		if(this.hotTopIndex!=undefined){
			this.renderTopDrawer = this.props.items[this.hotTopIndex].props.renderDrawer
		}
		if(this.hotBottomIndex!=undefined){
			this.renderBottomDrawer = this.props.items[this.hotBottomIndex].props.renderDrawer
		}
		var i = 0
		
		return (
		<Styles
			topDrawerWidth={this.props.topDrawerWidth||0}
			bottomDrawerWidth={this.props.bottomDrawerWidth||0} 
			visibleDrawer={this.state.visibleDrawer} 
			navBarWidth={this.navBarWidth||0} 
			barBackground={this.props.barBackground}
		>
			<table>
				<tbody>
					<tr>
						<td>
							<div className='dummy'>
								<div className='nav-bar' key='nav-bar' ref={this.navBarRef} onMouseLeave={
								()=>{
									if(this.state.visibleDrawer=='MAIN' && this.props.closeMainOnMouseLeave) this.changeDrawer(null)
								}
								}>
								{
									this.props.items.map( child => (
										React.cloneElement(child,
										  {
										  	visibleDrawer : this.state.visibleDrawer,
										  	changeDrawer : this.changeDrawer,
										  	index : i++
										  }
										)
									))
								}
								</div>
								<div key='top-drawer' ref={this.topDrawerRef}
									className='top-drawer'>
									{this.renderTopDrawer(()=>this.changeDrawer(null))}
								</div>
								<div key='bottom-drawer' ref={this.bottomDrawerRef}
									className='bottom-drawer'>
									{this.renderBottomDrawer(()=>this.changeDrawer(null))}
								</div>
								<div ref={this.overlayRef} key='overlay' onClick={this.onOverlayClick} className='overlay'></div>
							</div>
						</td>
						<td style={{width : `calc(100vw - ${this.navBarWidth||0}px)`}}>
							{this.props.children}
						</td>
					</tr>
				</tbody>
			</table>
		</Styles>
		)
	}

	componentDidUpdate(){
		
		//hack - why is requestAnimationFrame not updating styles
		if(this.state.visibleDrawer=='BOTTOM') {
			// requestAnimationFrame(()=>{
				setTimeout(()=>{
					this.bottomDrawer.style.height = this.navBar.style.height = this.overlay.style.height = this.bottomDrawer.scrollHeight+'px'
				},500)
			
			// })			
		}
		if(this.state.visibleDrawer=='TOP'){
			requestAnimationFrame(()=>{
			this.navBar.style.height = this.overlay.style.height = this.topDrawer.scrollHeight+'px'
			})
		}
		
		if(this.shouldChildrenRender && this.navBarWidth){
			this.shouldChildrenRender = false
		}
		if(this.state.visibleDrawer=='MAIN'){
			
		}
		if(this.state.visibleDrawer=='TOP'){
			requestAnimationFrame(()=>{
				this.topDrawer.style.left = '0px'
			})
		}
		if(this.state.visibleDrawer=='BOTTOM'){
			requestAnimationFrame(()=>{
				this.bottomDrawer.style.left = this.navBarWidth+'px'
			})
		}
		if(this.state.visibleDrawer==null){
			if(this.renderBottomDrawer!=this.nullFn){
				this.renderBottomDrawer = this.nullFn
				this.bottomDrawer.style.left = -1*this.props.bottomDrawerWidth+this.navBarWidth+'px'
				this.overlay.style.opacity = '0'
				setTimeout(()=>{
					this.overlay.style.display = 'none'
					this.bottomDrawer.style.width = '0px'
				},transitionTime)
			}
			if(this.renderTopDrawer!=this.nullFn){
				this.renderTopDrawer = this.nullFn
				this.topDrawer.style.left = -1*this.props.topDrawerWidth+'px'
				this.overlay.style.opacity = '0'
				setTimeout(()=>{
					this.overlay.style.display = 'none'
					this.topDrawer.style.width = '0px'
				},transitionTime)
			}
		}
	}
}


NavBar.TopItem = TopItem
NavBar.BottomItem = BottomItem
NavBar.MainClickItem = MainClickItem
NavBar.MainHoverItem = MainHoverItem
NavBar.Item = Item

NavBar.propTypes = {
  bottomDrawerWidth : PropTypes.number,
  topDrawerWidth : PropTypes.number,
  barBackground : PropTypes.string,
  closeMainOnMouseLeave : PropTypes.bool,
  items : PropTypes.array.isRequired
}

export default NavBar