import { Button, Layout, LayoutProps, Menu, SiderProps } from 'antd'
import { HTMLProps, Key, memo, ReactNode, useEffect, useMemo, useState } from 'react'
import { ItemType } from 'antd/lib/menu/hooks/useItems'
import { Link } from 'react-router-dom'
import {
    ApartmentOutlined,
    CodeOutlined,
    HomeOutlined,
    MenuFoldOutlined,
    MenuUnfoldOutlined,
    UserOutlined,
} from '@ant-design/icons'

import PageHeader from '@components/PageHeader'
import { UserMenu, UserMenuProps } from '@components/UserMenu'
import { WellTreeSelector, WellTreeSelectorProps } from '@components/selectors/WellTreeSelector'
import { isURLAvailable, wrapPrivateComponent } from '@utils'

import '@styles/layout.less'

const { Content, Sider } = Layout

export type LayoutPortalProps = HTMLProps<HTMLDivElement> & {
    title?: ReactNode
    noSheet?: boolean
    showSelector?: boolean
    selectorProps?: WellTreeSelectorProps
    sider?: boolean | JSX.Element
    siderProps?: SiderProps & { userMenuProps?: UserMenuProps }
    isAdmin?: boolean
}

const makeItem = (title: string, key: Key, icon: JSX.Element, label?: ReactNode, onClick?: () => void) => ({ icon, key, title, label: label ?? title, onClick })

const _LayoutPortal = memo<LayoutPortalProps>(({ isAdmin, title, noSheet, showSelector, selectorProps, sider, siderProps, ...props }) => {
    const [menuCollapsed, setMenuCollapsed] = useState<boolean>(true)
    const [wellsTreeOpen, setWellsTreeOpen] = useState<boolean>(false)
    const [userMenuOpen, setUserMenuOpen] = useState<boolean>(false)
    const [currentWell, setCurrentWell] = useState<string>('')

    useEffect(() => {
        if (typeof showSelector === 'boolean')
            setWellsTreeOpen(showSelector)
    }, [showSelector])

    const menuItems = useMemo(() => [
        !isAdmin && makeItem(currentWell, 'well', <ApartmentOutlined/>, null, () => setWellsTreeOpen((prev) => !prev)),
        isAdmin && makeItem('Вернуться на сайт', 'go_back', <HomeOutlined />, <Link to={'/'}>Домой</Link>),
        !isAdmin && isURLAvailable('/admin') && makeItem('Панель администратора', 'admin_panel', <CodeOutlined />, <Link to={'/admin'}>Панель администратора</Link>),
        makeItem('Профиль', 'profile', <UserOutlined/>, null, () => setUserMenuOpen((prev) => !prev)),
    ].filter(Boolean) as ItemType[], [isAdmin, currentWell])

    return (
        <Layout className={`page-layout ${isAdmin ? 'page-layout-admin' : ''}`}>
            {(sider || siderProps) && (
                <Sider {...siderProps} collapsed={menuCollapsed} trigger={null} collapsible className={`menu-sider ${siderProps?.className || ''}`}>
                    <div className={'sider-content'}>
                        <button className={'sider-toogle'} onClick={() => setMenuCollapsed((prev) => !prev)}>
                            {menuCollapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
                        </button>
                        <div className={'scrollable hide-slider'}>
                            {sider}
                        </div>
                        <Menu
                            mode={'inline'}
                            items={menuItems}
                            inlineCollapsed
                            theme={'dark'}
                            selectable={false}
                        />
                        <UserMenu
                            open={userMenuOpen}
                            onClose={() => setUserMenuOpen(false)}
                            isAdmin={isAdmin}
                            {...siderProps?.userMenuProps}
                        />
                    </div>
                </Sider>
            )}
            <Layout className={'page-content'}>
                <PageHeader title={title}>
                    {isAdmin ? (
                        <Button size={'large'}>
                            <Link to={'/'}>Вернуться на сайт</Link>
                        </Button>
                    ) : (
                        <>
                            <WellTreeSelector
                                open={wellsTreeOpen}
                                onClose={() => setWellsTreeOpen(false)}
                                {...selectorProps}
                                onChange={(well) => setCurrentWell(well ?? 'Выберите месторождение')}
                            />
                            <Button onClick={() => setWellsTreeOpen((prev) => !prev)}>{currentWell}</Button>
                        </>
                    )}
                </PageHeader>
                <Content>
                    <div {...props} className={`${noSheet ? '' : 'site-layout-background sheet'} ${props.className}`} />
                </Content>
            </Layout>
        </Layout>
    )
})

export const LayoutPortal = wrapPrivateComponent(_LayoutPortal, {
    requirements: ['Deposit.get'],
})

export default LayoutPortal
