import React from "react"
import * as antd from "antd"
import classnames from "classnames"
import { ActionSheet } from "antd-mobile"
import { Motion, spring } from "react-motion"

import { Icons, createIconRender } from "components/Icons"

import { WithPlayerContext, Context } from "contexts/WithPlayerContext"

import { QuickNavMenuItems, QuickNavMenu } from "components/Layout/quickNav"

import PlayerView from "pages/@mobile-views/player"
import CreatorView from "pages/@mobile-views/creator"

import "./index.less"

const tourSteps = [
    {
        title: "Open quick nav",
        description: "Xd",
        ref: React.createRef(),
    },
    {
        title: "Account button",
        description: "Xd",
        ref: React.createRef(),
    }
]

const openPlayerView = () => {
    app.DrawerController.open("player", PlayerView)
}
const openCreator = () => {
    app.DrawerController.open("creator", CreatorView, {
        props: {
            bodyStyle: {
                minHeight: "unset",
                height: "50vh"
            }
        }
    })
}

const PlayerButton = (props) => {
    React.useEffect(() => {
        openPlayerView()
    }, [])

    return <div
        className={classnames(
            "player_btn",
            {
                "bounce": props.playback === "playing"
            }
        )}
        style={{
            "--average-color": props.colorAnalysis?.rgba,
            "--color": props.colorAnalysis?.isDark ? "var(--text-color-white)" : "var(--text-color-black)",
        }}
        onClick={openPlayerView}
    >
        {
            props.playback === "playing" ? <Icons.MdMusicNote /> : <Icons.MdPause />
        }
    </div>
}

const AccountButton = React.forwardRef((props, ref) => {
    const user = app.userData
    const ActionSheetRef = React.useRef()

    const handleClick = () => {
        if (!user) {
            return app.navigation.goAuth()
        }

        return app.navigation.goToAccount()
    }

    const handleHold = () => {
        ActionSheetRef.current = ActionSheet.show({
            actions: [
                {
                    key: "settings",
                    text: <><Icons.Settings /> <span>Settings</span></>,
                    onClick: () => {
                        app.navigation.goToSettings()
                        ActionSheetRef.current.close()
                    }
                },
                {
                    key: "account",
                    text: <><Icons.User /> <span>Account</span></>,
                    onClick: () => {
                        app.navigation.goToAccount()
                        ActionSheetRef.current.close()
                    }
                },
                {
                    key: "logout",
                    text: <><Icons.MdOutlineLogout /> <span>Logout</span></>,
                    danger: true,
                    onClick: () => {
                        app.eventBus.emit("app.logout_request")
                        ActionSheetRef.current.close()
                    }
                }
            ]
        })
    }

    return <div
        key="account"
        id="account"
        className="item"
        ref={ref}
        onClick={handleClick}
        onContextMenu={handleHold}
        context-menu="ignore"
    >
        <div className="icon">
            {
                user ? <antd.Avatar shape="square" src={app.userData.avatar} /> : createIconRender("Login")
            }
        </div>
    </div>
})

export default (props) => {
    return <WithPlayerContext>
        <BottomBar
            {...props}
        />
    </WithPlayerContext>
}

export class BottomBar extends React.Component {
    static contextType = Context

    state = {
        visible: false,
        quickNavVisible: false,
        render: null,
        tourOpen: false,
    }

    busEvents = {
        "runtime.crash": () => {
            this.toggleVisibility(false)
        }
    }

    refs = {
        homeBtn: React.createRef(),
        accountBtn: React.createRef(),
    }

    componentDidMount = () => {
        this.interface = app.layout.bottom_bar = {
            toggleVisible: this.toggleVisibility,
            isVisible: () => this.state.visible,
            render: (fragment) => {
                this.setState({ render: fragment })
            },
            clear: () => {
                this.setState({ render: null })
            },
            toggleTour: () => {
                this.setState({ tourOpen: !this.state.tourOpen })
            },
        }

        setTimeout(() => {
            this.setState({ visible: true })
        }, 10)

        // Register bus events
        Object.keys(this.busEvents).forEach((key) => {
            app.eventBus.on(key, this.busEvents[key])
        })
    }

    componentWillUnmount = () => {
        delete window.app.layout.bottom_bar

        // Unregister bus events
        Object.keys(this.busEvents).forEach((key) => {
            app.eventBus.off(key, this.busEvents[key])
        })
    }

    toggleVisibility = (to) => {
        if (typeof to === "undefined") {
            to = !this.state.visible
        }

        this.setState({ visible: to })
    }

    handleItemClick = (item) => {
        if (item.dispatchEvent) {
            app.eventBus.emit(item.dispatchEvent)
        } else if (item.location) {
            app.location.push(item.location)
        }
    }

    handleNavTouchStart = (e) => {
        this._navTouchStart = setTimeout(() => {
            this.setState({ quickNavVisible: true })

            if (app.cores.haptics?.vibrate) {
                app.cores.haptics.vibrate(80)
            }

            // remove the timeout
            this._navTouchStart = null
        }, 400)
    }

    handleNavTouchEnd = (event) => {
        if (this._lastHovered) {
            this._lastHovered.classList.remove("hover")
        }

        if (this._navTouchStart) {
            clearTimeout(this._navTouchStart)

            this._navTouchStart = null

            return false
        }

        this.setState({ quickNavVisible: false })

        // get cords of the touch
        const x = event.changedTouches[0].clientX
        const y = event.changedTouches[0].clientY

        // get the element at the touch
        const element = document.elementFromPoint(x, y)

        // get the closest element with the attribute
        const closest = element.closest(".quick-nav_item")

        if (!closest) {
            return false
        }

        const item = QuickNavMenuItems.find((item) => {
            return item.id === closest.getAttribute("quicknav-item")
        })

        if (!item) {
            return false
        }

        if (item.location) {
            app.location.push(item.location)

            if (app.cores.haptics?.vibrate) {
                app.cores.haptics.vibrate([40, 80])
            }
        }
    }

    handleNavTouchMove = (event) => {
        // check if the touch is hovering a quicknav item
        const x = event.changedTouches[0].clientX
        const y = event.changedTouches[0].clientY

        // get the element at the touch
        const element = document.elementFromPoint(x, y)

        // get the closest element with the attribute
        const closest = element.closest("[quicknav-item]")

        if (!closest) {
            if (this._lastHovered) {
                this._lastHovered.classList.remove("hover")
            }

            this._lastHovered = null

            return false
        }

        if (this._lastHovered !== closest) {
            if (this._lastHovered) {
                this._lastHovered.classList.remove("hover")
            }

            this._lastHovered = closest

            closest.classList.add("hover")

            if (app.cores.haptics?.vibrate) {
                app.cores.haptics.vibrate(40)
            }
        }
    }

    toggleTour = (to) => {
        if (typeof to === "undefined") {
            to = !this.state.tourOpen
        }

        this.setState({
            tourOpen: to
        })
    }

    render() {
        if (this.state.render) {
            return <div className="bottomBar">
                {this.state.render}
            </div>
        }

        const heightValue = this.state.visible ? Number(app.cores.style.defaultVar("bottom-bar-height").replace("px", "")) : 0

        return <>
            <QuickNavMenu
                visible={this.state.quickNavVisible}
            />

            <Motion style={{
                y: spring(this.state.visible ? 0 : 300),
                height: spring(heightValue)
            }}>
                {({ y, height }) =>
                    <div className="bottomBar_wrapper">
                        <div
                            className="bottomBar"
                            style={{
                                WebkitTransform: `translateY(${y}px)`,
                                transform: `translateY(${y}px)`,
                                height: `${height}px`,
                            }}
                        >
                            <div className="items">
                                <div
                                    key="creator"
                                    id="creator"
                                    className={classnames("item", "primary")}
                                    onClick={openCreator}
                                >
                                    <div className="icon">
                                        {createIconRender("PlusCircle")}
                                    </div>
                                </div>

                                {
                                    this.context.currentManifest && <div
                                        className="item"
                                    >
                                        <PlayerButton
                                            manifest={this.context.currentManifest}
                                            playback={this.context.playbackStatus}
                                            colorAnalysis={this.context.coverColorAnalysis}
                                        />
                                    </div>
                                }

                                <div
                                    key="navigator"
                                    id="navigator"
                                    className="item"
                                    onClick={() => app.location.push("/")}
                                    onTouchMove={this.handleNavTouchMove}
                                    onTouchStart={this.handleNavTouchStart}
                                    onTouchEnd={this.handleNavTouchEnd}
                                    onTouchCancel={() => {
                                        this.setState({ quickNavVisible: false })
                                    }}
                                >
                                    <div className="icon">
                                        {createIconRender("Home")}
                                    </div>
                                </div>

                                <div
                                    key="searcher"
                                    id="searcher"
                                    className="item"
                                    onClick={app.controls.openSearcher}
                                >
                                    <div className="icon">
                                        {createIconRender("Search")}
                                    </div>
                                </div>

                                <AccountButton/>
                            </div>
                        </div>
                    </div>
                }
            </Motion>
        </>
    }
}