// DocsLayout.jsx — v0.19.0 / roadmap item #30.
//
// Left-side flyout nav + content area for the `/docs/*` route tree:
//
//   /docs                       → redirect to /docs/user-guide
//   /docs/user-guide            → DOCS.md (existing v0.14.0 content)
//   /docs/sessions              → redirect to /docs/sessions/about
//   /docs/sessions/about        → README.md from the sessions repo
//   /docs/sessions/:nnnn        → per-session index page
//   /docs/sessions/:nnnn/:file  → per-transcript view
//
// The flyout is a persistent left sidebar on desktop and a slide-out
// drawer on mobile (toggled by the icon button in the docs header).
// The session list is driven by the `/api/docs/sessions/manifest`
// fetch:
//   - loading        → skeleton in the nav (three placeholder rows)
//   - manifest 502   → error banner in the nav with "Try again"
//   - empty manifest → only "About" under Sessions; no NNNN rows
//
// Amplitude analytics (per SPEC §21):
//   - track('Doc Viewed', { section: '...' }) on each sub-route mount;
//     the sub-route component owns the fire (it knows the section).
//   - flyout buttons + links carry `aria-label` + `data-amp-track-name`
//     so autocapture rows are readable rather than ":nth-child(7)".

import { useEffect, useState, useCallback } from 'react'
import { Link, useNavigate, useLocation, Outlet } from 'react-router-dom'
import { getSessionsManifest } from '../api.js'

export default function DocsLayout({ authenticated }) {
  const [manifest, setManifest] = useState(null)
  const [manifestState, setManifestState] = useState('loading') // loading | ok | error
  const [drawerOpen, setDrawerOpen] = useState(false)
  const [reloadTick, setReloadTick] = useState(0)
  const navigate = useNavigate()
  const location = useLocation()

  useEffect(() => {
    let active = true
    setManifestState('loading')
    getSessionsManifest()
      .then(payload => {
        if (!active) return
        setManifest(payload || {})
        setManifestState('ok')
      })
      .catch(() => {
        if (!active) return
        setManifest({})
        setManifestState('error')
      })
    return () => { active = false }
  }, [reloadTick])

  // Close the mobile drawer on every navigation so a click in the nav
  // doesn't strand the user on a drawer-open view.
  useEffect(() => {
    setDrawerOpen(false)
  }, [location.pathname])

  const retryManifest = useCallback(() => {
    setReloadTick(t => t + 1)
  }, [])

  return (
    <div className="docs-layout">
      <header className="docs-header">
        <button
          className="docs-back"
          onClick={() => (history.length > 1 ? navigate(-1) : navigate('/'))}
          aria-label="Back to previous page"
          data-amp-track-name="Docs Back"
        >
          ← Back
        </button>
        <button
          className="docs-drawer-toggle"
          onClick={() => setDrawerOpen(o => !o)}
          aria-label="Toggle docs navigation"
          aria-expanded={drawerOpen}
          data-amp-track-name="Docs Drawer Toggle"
        >
          <span aria-hidden>☰</span>
        </button>
        <span className="docs-title">Docs</span>
        {!authenticated && (
          <Link
            className="docs-signin"
            to="/"
            aria-label="Home"
            data-amp-track-name="Docs Home"
          >
            Home
          </Link>
        )}
      </header>
      <div className={'docs-body' + (drawerOpen ? ' docs-body--drawer-open' : '')}>
        <aside className="docs-nav" aria-label="Docs navigation">
          <DocsNav
            manifest={manifest}
            manifestState={manifestState}
            onRetry={retryManifest}
            currentPath={location.pathname}
          />
        </aside>
        <main className="docs-content">
          <Outlet />
        </main>
      </div>
      {drawerOpen && (
        <button
          className="docs-drawer-scrim"
          aria-label="Close drawer"
          onClick={() => setDrawerOpen(false)}
          data-amp-track-name="Docs Drawer Close"
        />
      )}
    </div>
  )
}

function DocsNav({ manifest, manifestState, onRetry, currentPath }) {
  const isActive = (path) => currentPath === path || currentPath.startsWith(path + '/')

  // Sort session keys ascending (newest sessions render last). The
  // manifest's keys are zero-padded 4-digit strings so lexicographic
  // order is the same as numeric.
  const sessionKeys = Object.keys(manifest || {}).sort()

  return (
    <nav className="docs-nav-inner">
      <div className="docs-nav-section">
        <div className="docs-nav-section-label">Docs</div>
        <ul className="docs-nav-list">
          <li>
            <Link
              to="/docs/user-guide"
              className={isActive('/docs/user-guide') ? 'active' : ''}
              aria-label="User Guide"
              data-amp-track-name="Docs Nav User Guide"
            >
              User Guide
            </Link>
          </li>
        </ul>
      </div>

      <div className="docs-nav-section">
        <div className="docs-nav-section-label">Sessions</div>
        <ul className="docs-nav-list">
          <li>
            <Link
              to="/docs/sessions/about"
              className={currentPath === '/docs/sessions/about' ? 'active' : ''}
              aria-label="About sessions"
              data-amp-track-name="Docs Nav Sessions About"
            >
              About
            </Link>
          </li>
        </ul>

        {manifestState === 'loading' && (
          <ul className="docs-nav-list docs-nav-skeleton" aria-hidden>
            <li><span className="skeleton-row" /></li>
            <li><span className="skeleton-row" /></li>
            <li><span className="skeleton-row" /></li>
          </ul>
        )}

        {manifestState === 'error' && (
          <div className="docs-nav-error" role="alert">
            <span>Couldn't load session list.</span>
            <button
              type="button"
              onClick={onRetry}
              aria-label="Retry session list"
              data-amp-track-name="Docs Nav Sessions Retry"
            >
              Try again
            </button>
          </div>
        )}

        {manifestState === 'ok' && sessionKeys.length > 0 && (
          <ul className="docs-nav-list">
            {sessionKeys.map(nnnn => {
              const entry = manifest[nnnn] || {}
              const title = entry.title || ''
              const label = title ? `${nnnn} — ${title}` : nnnn
              const to = `/docs/sessions/${nnnn}`
              return (
                <li key={nnnn}>
                  <Link
                    to={to}
                    className={isActive(to) ? 'active' : ''}
                    aria-label={`Session ${nnnn}${title ? ': ' + title : ''}`}
                    data-amp-track-name="Docs Nav Session"
                    data-amp-track-session={nnnn}
                  >
                    {label}
                  </Link>
                </li>
              )
            })}
          </ul>
        )}
      </div>
    </nav>
  )
}
