import React from "react"
import classnames from "classnames"
import * as antd from "antd"
import progressBar from "nprogress"

import Sidebar from "./sidebar"
import Header from "./header"
import Drawer from "./drawer"
import Sidedrawer from "./sidedrawer"
import BottomBar from "./bottomBar"

const LayoutRenders = {
	mobile: (props) => {
		return <antd.Layout className={classnames("app_layout", ["mobile"])} style={{ height: "100%" }}>
			<antd.Layout className="content_layout">
				<antd.Layout.Content className={classnames("layout_page", ...props.layoutPageModesClassnames ?? [])}>
					<div className={classnames("fade-transverse-active", { "fade-transverse-leave": props.isOnTransition })}>
						{React.cloneElement(props.children, props)}
					</div>
				</antd.Layout.Content>
			</antd.Layout>
			<BottomBar user={props.user} />
			<Drawer />
		</antd.Layout>
	},
	default: (props) => {
		return <antd.Layout className="app_layout" style={{ height: "100%" }}>
			<Drawer />
			<Sidebar user={props.user} />
			<Sidedrawer />
			<antd.Layout className="content_layout">
				<Header />
				<antd.Layout.Content className={classnames("layout_page", ...props.layoutPageModesClassnames ?? [])}>
					<div className={classnames("fade-transverse-active", { "fade-transverse-leave": props.isOnTransition })}>
						{React.cloneElement(props.children, props)}
					</div>
				</antd.Layout.Content>
			</antd.Layout>
		</antd.Layout>
	}
}

export default class Layout extends React.Component {
	progressBar = progressBar.configure({ parent: "html", showSpinner: false })

	state = {
		layoutType: "default",
		isOnTransition: false,
		compactMode: false,
		renderLock: true,
		renderError: null,
	}

	setLayout = (layout) => {
		if (typeof LayoutRenders[layout] === "function") {
			return this.setState({
				layoutType: layout,
			})
		}

		return console.error("Layout type not found")
	}

	componentDidMount() {
		window.app.eventBus.on("app.initialization.start", () => {
			this.setState({
				renderLock: true,
			})
		})
		window.app.eventBus.on("app.initialization.finish", () => {
			this.setState({
				renderLock: false,
			})
		})

		window.app.eventBus.on("toogleCompactMode", (to) => {
			this.setState({
				compactMode: to ?? !this.state.compactMode,
			})
		})

		if (window.app.settings.get("forceMobileMode") || window.app.isAppCapacitor() || Math.min(window.screen.width, window.screen.height) < 768 || navigator.userAgent.indexOf("Mobi") > -1) {
			window.isMobile = true
			this.setLayout("mobile")
		} else {
			window.isMobile = false
		}

		window.app.eventBus.on("forceMobileMode", (to) => {
			if (to) {
				window.isMobile = true
				this.setLayout("mobile")
			} else {
				window.isMobile = false
				this.setLayout("default")
			}
		})
	}

	onTransitionStart = () => {
		progressBar.start()

		this.setState({ isOnTransition: true })
	}

	onTransitionFinish = () => {
		progressBar.done()

		this.setState({ isOnTransition: false })
	}

	componentDidCatch(info, stack) {
		this.setState({ renderError: { info, stack } })
	}

	render() {
		if (this.state.renderLock) {
			if (this.props.staticRenders?.Initialization) {
				return React.createElement(this.props.staticRenders.Initialization)
			}

			return null
		}

		if (this.state.renderError) {
			if (this.props.staticRenders?.RenderError) {
				return React.createElement(this.props.staticRenders?.RenderError, { error: this.state.renderError })
			}

			return JSON.stringify(this.state.renderError)
		}

		const layoutComponentProps = {
			...this.props.bindProps,
			...this.state,
			children: this.props.children,
			layoutPageModesClassnames: [{
				["noMargin"]: this.state.compactMode,
			}],
			onTransitionStart: this.onTransitionStart,
			onTransitionFinish: this.onTransitionFinish,
		}

		if (LayoutRenders[this.state.layoutType]) {
			return LayoutRenders[this.state.layoutType](layoutComponentProps)
		}

		return LayoutRenders.default(layoutComponentProps)
	}
}