import { colors } from '@based/ui'
import { styled } from 'inlines'
import type React from 'react'
import { useCallback, useEffect, useRef, useState } from 'react'
import { useTypedRoute } from '../router'

export const Layout = ({
  header,
  sidebar,
  content,
}: Based.UI.Playground.Layout) => {
  const minSidebarWidth = 312
  const maxSidebarWidth = 468
  const dividerRef = useRef<HTMLDivElement>(null)
  const headerContainerRef = useRef<HTMLDivElement>(null)
  const [sidebarWidth, setSidebarWidth] = useState<number>(minSidebarWidth)
  const [isResizing, setIsResizing] = useState<boolean>(false)
  const [headerHeight, setHeaderHeight] = useState<number>(0)
  const { params } = useTypedRoute()
  const { view } = params
  const isFullscreen = view === 'fullscreen'

  const handleMouseMove = useCallback(
    (e: MouseEvent) => {
      if (!isResizing) return

      let newWidth = e.clientX

      if (newWidth < minSidebarWidth) newWidth = minSidebarWidth
      if (newWidth > maxSidebarWidth) newWidth = maxSidebarWidth

      setSidebarWidth(newWidth)
    },
    [isResizing],
  )

  const handleMouseUp = useCallback(() => {
    if (isResizing) {
      setIsResizing(false)
    }
  }, [isResizing])

  useEffect(() => {
    if (isResizing) {
      document.addEventListener('mousemove', handleMouseMove)
      document.addEventListener('mouseup', handleMouseUp)
      document.body.style.cursor = 'col-resize'
      document.body.style.userSelect = 'none'
    } else {
      document.removeEventListener('mousemove', handleMouseMove)
      document.removeEventListener('mouseup', handleMouseUp)
      document.body.style.cursor = 'default'
      document.body.style.userSelect = 'auto'
    }

    return () => {
      document.removeEventListener('mousemove', handleMouseMove)
      document.removeEventListener('mouseup', handleMouseUp)
      document.body.style.cursor = 'default'
      document.body.style.userSelect = 'auto'
    }
  }, [isResizing, handleMouseMove, handleMouseUp])

  useEffect(() => {
    if (headerContainerRef.current) {
      const height = headerContainerRef.current.offsetHeight

      setHeaderHeight(height)
    }
  }, [])

  const handleMouseDown = (e: React.MouseEvent<HTMLDivElement>) => {
    e.preventDefault()
    setIsResizing(true)
  }

  return (
    <div
      style={{
        display: 'grid',
        gridTemplateRows: 'auto 1fr',
        gridTemplateColumns: `${sidebar ? sidebarWidth : 0}px 0px 1fr`,
        height: '100vh',
        overflow: 'hidden',
      }}
    >
      {header && !isFullscreen && (
        <header
          ref={headerContainerRef}
          style={{
            position: 'absolute',
            zIndex: 2,
            width: '100%',
            gridColumn: '1 / -1',
          }}
        >
          {header}
        </header>
      )}

      {sidebar && !isFullscreen && (
        <>
          <styled.div
            ref={dividerRef}
            onMouseDown={handleMouseDown}
            role="separator"
            aria-orientation="vertical"
            tabIndex={0}
            style={{
              gridRow: '2',
              gridColumn: '2',
              cursor: 'col-resize',
              backgroundColor: 'transparent',
              borderLeft: '1px solid',
              borderLeftColor: 'transparent',
              width: '5px',
              userSelect: 'none',
              transition: 'border-left-color 0.2s ease',
              outline: 'none',
              zIndex: 1,
              '&:hover': {
                borderLeftColor: isResizing
                  ? colors.neutral100
                  : colors.neutral60,
              },
            }}
          />
          <aside
            style={{
              gridRow: '2',
              gridColumn: '1',
              minHeight: 0,
              overflow: 'auto',
              transition: 'width 0.2s ease',
              paddingTop: isFullscreen ? 0 : headerHeight,
            }}
          >
            {sidebar}
          </aside>
        </>
      )}

      {content && (
        <main
          style={{
            gridRow: '2',
            gridColumn: '3',
            minHeight: 0,
            maxHeight: '100svh',
            overflow: isFullscreen ? undefined : 'auto',
            display: 'flex',
            flexDirection: 'column',
            paddingTop: isFullscreen ? 0 : headerHeight,
          }}
        >
          {content}
        </main>
      )}
    </div>
  )
}
