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

import { LayoutPropsContext } from '@asb/context'
import { UserMenu, UserMenuProps } from '@components/UserMenu'
import { WellTreeSelector, WellTreeSelectorProps } from '@components/selectors/WellTreeSelector'
import { isURLAvailable, withPermissions } from '@utils'

import SuspenseFallback from './SuspenseFallback'

import Logo from '@images/Logo'

import '@styles/layout.less'

const { Content, Sider } = Layout

export type LayoutPortalProps = Omit<LayoutProps, 'children'> & {
    title?: ReactNode
    sheet?: boolean
    showSelector?: boolean
    selectorProps?: WellTreeSelectorProps
    sider?: boolean | JSX.Element
    siderProps?: SiderProps & { userMenuProps?: UserMenuProps }
    isAdmin?: boolean
    fallback?: JSX.Element
    breadcrumb?: boolean | JSX.Element
    topRightBlock?: JSX.Element
}

const defaultProps: LayoutPortalProps = {
    title: 'Единая цифровая платформа',
    sider: true,
    sheet: true,
}

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

const _LayoutPortal = memo(() => {
    const [menuCollapsed, setMenuCollapsed] = useState<boolean>(true)
    const [wellsTreeOpen, setWellsTreeOpen] = useState<boolean>(false)
    const [userMenuOpen, setUserMenuOpen] = useState<boolean>(false)
    const [currentWell, setCurrentWell] = useState<string>('')
    const [props, setProps] = useState<LayoutPortalProps>(defaultProps)

    const { isAdmin, title, sheet, showSelector, selectorProps, sider, siderProps, fallback, breadcrumb, topRightBlock, ...other } = useMemo(() => props, [props])

    const setLayoutProps = useCallback((props: LayoutPortalProps) => setProps({ ...defaultProps, ...props}), [])

    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} collapsedWidth={50} collapsed={menuCollapsed} trigger={null} collapsible className={`menu-sider ${siderProps?.className || ''}`}>
                    <div className={'sider-content'}>
                        <button className={'sider-toogle'} onClick={() => setMenuCollapsed((prev) => !prev)}>
                            <Logo onlyIcon={menuCollapsed} />
                        </button>
                        <div className={'scrollable hide-slider'}>
                            {sider}
                        </div>
                        <Menu
                            mode={'inline'}
                            items={menuItems}
                            theme={'dark'}
                            selectable={false}
                        />
                        <UserMenu
                            open={userMenuOpen}
                            onClose={() => setUserMenuOpen(false)}
                            isAdmin={isAdmin}
                            {...siderProps?.userMenuProps}
                        />
                    </div>
                </Sider>
            )}
            {!isAdmin && (
                <WellTreeSelector
                    open={wellsTreeOpen}
                    onClose={() => setWellsTreeOpen(false)}
                    {...selectorProps}
                    onChange={(well) => setCurrentWell(well ?? 'Выберите месторождение')}
                />
            )}
            <Layout className={'page-content'}>
                <Content {...other} className={`${sheet ? 'site-layout-background sheet' : ''} ${other.className ?? ''}`}>
                    {(breadcrumb || topRightBlock) && (
                        <div className={'breadcrumb-block'}>
                            {breadcrumb && (
                                <Breadcrumb>
                                    <Breadcrumb.Item href={'/'}>
                                        <HomeOutlined />
                                    </Breadcrumb.Item>
                                    {!isAdmin && (
                                        <Breadcrumb.Item>
                                            <a style={{ userSelect: 'none' }} onClick={() => setWellsTreeOpen((prev) => !prev)}>{currentWell}</a>
                                        </Breadcrumb.Item>
                                    )}
                                    {breadcrumb}
                                </Breadcrumb>
                            )}
                            {topRightBlock}
                        </div>
                    )}
                    <LayoutPropsContext.Provider value={setLayoutProps}>
                        <Suspense fallback={fallback ?? <SuspenseFallback style={{ minHeight: '100%' }} />}>
                            <Outlet />
                        </Suspense>
                    </LayoutPropsContext.Provider>
                </Content>
            </Layout>
        </Layout>
    )
})

export const LayoutPortal = withPermissions(_LayoutPortal, ['Deposit.get'])

export default LayoutPortal
