import type { IconName } from '@blueprintjs/core'
import { Button, Collapse, Divider, Icon } from '@blueprintjs/core'
import { css, cx } from '@emotion/css'
import InjectLogo from '@inject/shared/svg/inject-logo.svg?react'
import { useLocalStorageState } from 'ahooks'
import { Fragment, type FC, type ReactNode } from 'react'

const container = css`
  display: flex;
  height: 100%;
  width: 100%;
`

const sidebar = css`
  overflow-y: auto;
  & .bp5-divider:last-child {
    display: none;
  }
`

const sectionName = css`
  margin: 0 0 0.25rem 0.5rem;
`

const titleWrapper = css`
  margin: 0 0 0.25rem 0.5rem;
  display: flex;
  justify-content: space-between;
  align-items: end;
  gap: 0.25rem;
`

const sidebarTitle = css`
  margin: 0;
  padding-top: 0.25rem;
`

const hoverable = css`
  &:hover {
    cursor: pointer;
  }
`

export interface Section {
  name?: string
  node: ReactNode
  id: string
  icon?: IconName
}

interface SidebarProps {
  position?: 'left' | 'right'
  hideNames?: boolean
  sections: Section[]
  stickySections?: Section[]
  showLogo?: boolean
  onClickLogo?: () => void
  title?: string
  className?: string
  onClose?: () => void
}

const SectionCat: FC<{
  section: Section
  hideNames?: boolean
}> = ({ section, hideNames }) => {
  const [hidden, setHidden] = useLocalStorageState(`{HideBar}:${section.id}`, {
    defaultValue: true,
    listenStorageChange: true,
  })

  return (
    <>
      {!hideNames && (
        <div
          className={css`
            &:hover {
              cursor: pointer;
            }
            display: flex;
            align-items: center;
          `}
          onClick={() => setHidden(prev => !prev)}
        >
          {section.icon && <Icon icon={section.icon} />}
          {section.name && <h3 className={sectionName}>{section.name}</h3>}
          <Icon
            style={{ marginLeft: 'auto' }}
            icon={hidden ? 'chevron-up' : 'chevron-down'}
          />
        </div>
      )}
      <Collapse isOpen={hidden || hideNames} keepChildrenMounted>
        {section.node}
      </Collapse>
      <Divider />
    </>
  )
}

const Sidebar: FC<SidebarProps> = ({
  position,
  sections,
  showLogo,
  stickySections,
  hideNames,
  title,
  onClickLogo,
  className,
  onClose,
}) => (
  <div className={cx(container, ...(className ? [className] : []))}>
    {position === 'right' && <Divider />}
    {/* {position === 'left' && <NoBorderDivider />} */}

    <div
      style={{
        height: '100%',
        width: '100%',
        display: 'flex',
        flexDirection: 'column',
      }}
    >
      {(title || showLogo || stickySections) && (
        <div>
          {title && (
            <div>
              <div className={titleWrapper}>
                <h2 className={sidebarTitle}>{title}</h2>
                {onClose && (
                  <Button icon='small-cross' minimal onClick={onClose} />
                )}
              </div>
              <Divider />
            </div>
          )}

          {showLogo && (
            <>
              <InjectLogo
                style={{
                  width: '5rem',
                  height: 'auto',
                  padding: '0.25rem 0.5rem',
                  display: 'block',
                  margin: 'auto',
                }}
                className={cx({
                  [hoverable]: !!onClickLogo,
                })}
                onClick={onClickLogo}
              />

              <Divider />
            </>
          )}
          {stickySections &&
            stickySections.map(section => (
              <Fragment key={section.id}>
                {!hideNames && section.name && (
                  <h3 className={sectionName}>{section.name}</h3>
                )}
                {section.node}
                <Divider />
              </Fragment>
            ))}
        </div>
      )}

      <div className={sidebar}>
        {sections.map(section => (
          <SectionCat
            key={section.id}
            hideNames={hideNames}
            section={section}
          />
        ))}
      </div>
    </div>

    {position === 'left' && <Divider />}
    {/* {position === 'right' && <NoBorderDivider />} */}
  </div>
)

export default Sidebar
