import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { NavLink, Outlet, useLocation, useNavigate } from 'react-router-dom'
import {
  AppstoreOutlined, CalendarOutlined, ShoppingCartOutlined,
} from '@ant-design/icons'
import SchedulePanel from './SchedulePanel'
import BillCareLogo from './BillCareLogo'
import AccountPopover from './AccountPopover'
import { careMenuSections, filterMenuSections, resolveSelectedKey, sectionContainsPath, shopMenuSections } from '../menu'
import { fetchMyMenus } from '../api/auth'
import { THEMES } from '../theme'
import { useTheme } from '../themeContext'

const PANEL_MIN = 170
const PANEL_MAX = 420

type Props = {
  shop?: boolean
}

export default function AgentShell({ shop = false }: Props) {
  const navigate = useNavigate()
  const location = useLocation()
  const { theme, changeTheme } = useTheme()
  const [scheduleOpen, setScheduleOpen] = useState(false)
  const userName = localStorage.getItem('userName') || (shop ? '판매점' : '관리자')
  const [allowedMenus, setAllowedMenus] = useState<string[] | null>(() => {
    if (shop) return null
    try {
      const cached = localStorage.getItem('allowedMenus')
      return cached ? (JSON.parse(cached) as string[]) : []
    } catch {
      return []
    }
  })

  const [panelWidth, setPanelWidth] = useState(() => {
    const v = Number(localStorage.getItem('lp.width'))
    return v >= PANEL_MIN && v <= PANEL_MAX ? v : 220
  })
  const [collapsed, setCollapsed] = useState(() => localStorage.getItem('lp.collapsed') === '1')
  const draggingRef = useRef(false)
  const [dragging, setDragging] = useState(false)

  useEffect(() => {
    if (shop) {
      setAllowedMenus(null)
      return
    }
    let cancelled = false
    fetchMyMenus()
      .then((res) => {
        if (cancelled) return
        if (res.staffPermission) localStorage.setItem('staffPermission', res.staffPermission)
        setAllowedMenus(res.menus || [])
        try {
          localStorage.setItem('allowedMenus', JSON.stringify(res.menus || []))
        } catch { /* ignore */ }
      })
      .catch(() => {
        if (cancelled) return
        try {
          const cached = localStorage.getItem('allowedMenus')
          if (cached) setAllowedMenus(JSON.parse(cached) as string[])
          else setAllowedMenus(['home'])
        } catch {
          setAllowedMenus(['home'])
        }
      })
    return () => { cancelled = true }
  }, [shop])

  const allSections = useMemo(() => (shop ? shopMenuSections() : careMenuSections()), [shop])
  const sections = useMemo(
    () => (shop ? allSections : filterMenuSections(allSections, allowedMenus)),
    [shop, allSections, allowedMenus],
  )
  const selectedKey = resolveSelectedKey(location.pathname)

  const [openCards, setOpenCards] = useState<Record<string, boolean>>({})

  useEffect(() => {
    setOpenCards((prev) => {
      const next = { ...prev }
      sections.forEach((sec) => {
        if (next[sec.id] === undefined) {
          next[sec.id] = sectionContainsPath(sec, location.pathname) || sec.items.length <= 1
        }
        if (sectionContainsPath(sec, location.pathname)) next[sec.id] = true
      })
      return next
    })
  }, [location.pathname, sections])

  useEffect(() => {
    localStorage.setItem('lp.width', String(panelWidth))
  }, [panelWidth])
  useEffect(() => {
    localStorage.setItem('lp.collapsed', collapsed ? '1' : '0')
  }, [collapsed])

  const startResize = useCallback((e: React.MouseEvent) => {
    e.preventDefault()
    draggingRef.current = true
    setDragging(true)
    document.body.style.userSelect = 'none'
    document.body.style.cursor = 'col-resize'
  }, [])

  useEffect(() => {
    const onMove = (e: MouseEvent) => {
      if (!draggingRef.current) return
      setPanelWidth(Math.min(PANEL_MAX, Math.max(PANEL_MIN, e.clientX)))
    }
    const onUp = () => {
      if (!draggingRef.current) return
      draggingRef.current = false
      setDragging(false)
      document.body.style.userSelect = ''
      document.body.style.cursor = ''
    }
    window.addEventListener('mousemove', onMove)
    window.addEventListener('mouseup', onUp)
    return () => {
      window.removeEventListener('mousemove', onMove)
      window.removeEventListener('mouseup', onUp)
    }
  }, [])

  const logout = () => {
    localStorage.clear()
    navigate('/login')
  }

  const toggleCard = (id: string) => {
    setOpenCards((prev) => ({ ...prev, [id]: !prev[id] }))
  }

  return (
    <div className="app-shell">
      <header className="topbar">
        <div className={`topbar-brand${collapsed ? ' is-collapsed' : ''}`} style={collapsed ? undefined : { width: panelWidth }}>
          {!collapsed && (
            <div className="brand-inline">
              <BillCareLogo title="BillCare" size="header" />
            </div>
          )}
        </div>
        <div className="topbar-main">
          <div className="topbar-left-tools">
            {shop ? (
              <span className="topbar-user muted">에이전트 데모 / {userName}</span>
            ) : (
              <div className="agent-header-tools">
                <strong>[ BillCare ]</strong>
                <span className="header-divider" />
                <ShoppingCartOutlined />
                <span>문자발송(장바구니)</span>
                <span className="sms-remain">잔여SMS <b>996</b>건</span>
              </div>
            )}
          </div>
          <div className="topbar-right">
            {!shop && (
              <>
                <button
                  type="button"
                  className={`header-icon-btn${location.pathname.includes('/sitemap') ? ' active' : ''}`}
                  aria-label="전체보기"
                  title="전체보기"
                  onClick={() => navigate('/care/main/sitemap')}
                >
                  <AppstoreOutlined />
                </button>
                <AccountPopover onLogout={logout} />
                <button
                  type="button"
                  className={`header-icon-btn${scheduleOpen ? ' active' : ''}`}
                  aria-label="일정표"
                  onClick={() => setScheduleOpen((v) => !v)}
                >
                  <CalendarOutlined />
                </button>
              </>
            )}
            <select
              className="theme-select"
              value={theme}
              onChange={(e) => changeTheme(e.target.value as typeof theme)}
              title="테마 선택"
            >
              {THEMES.map((t) => (
                <option key={t.value} value={t.value}>{t.label}</option>
              ))}
            </select>
          </div>
        </div>
      </header>

      <div className="app-body">
        {!collapsed && (
          <aside className="leftpanel" style={{ width: panelWidth }}>
            {sections.map((sec) => {
              const open = openCards[sec.id] !== false
              const activeSec = sectionContainsPath(sec, location.pathname)
              return (
                <div className={`lp-card${activeSec ? ' is-active' : ''}`} key={sec.id}>
                  <button
                    type="button"
                    className="lp-card-title"
                    onClick={() => toggleCard(sec.id)}
                    aria-expanded={open}
                  >
                    <span>{sec.title}</span>
                    <span className="lp-card-chevron">{open ? '▾' : '▸'}</span>
                  </button>
                  {open && (
                    <div className="lp-card-body">
                      {sec.items.map((it) => (
                        <NavLink
                          key={it.key}
                          to={it.key}
                          title={it.label}
                          className={({ isActive }) => (isActive || selectedKey === it.key ? 'active' : undefined)}
                        >
                          {it.label}
                        </NavLink>
                      ))}
                    </div>
                  )}
                </div>
              )
            })}
          </aside>
        )}

        {!collapsed && (
          <div className={`panel-resizer${dragging ? ' dragging' : ''}`} onMouseDown={startResize} />
        )}

        <button
          type="button"
          className="panel-toggle"
          style={{ left: collapsed ? 0 : panelWidth }}
          title={collapsed ? '패널 펼치기' : '패널 접기'}
          onClick={() => setCollapsed((c) => !c)}
        >
          {collapsed ? '›' : '‹'}
        </button>

        <div className="main-area">
          <div className="content">
            <Outlet />
          </div>
        </div>
      </div>

      {!shop && <SchedulePanel open={scheduleOpen} onClose={() => setScheduleOpen(false)} />}
    </div>
  )
}
