// DocsSpec.jsx — v0.20.0.
//
// Per-spec view at `/docs/specs/:name`. Fetches a configured spec
// body via the backend mediator (which proxies the gitea raw URL)
// and renders it through the shared MarkdownPreview. The page header
// pulls the spec's `title` from the manifest so the breadcrumb-free
// page still names what you're looking at.
//
// Empty-state contract:
//   404 → "This spec isn't published yet / unknown name" with a hint
//         to pick a configured spec from the nav.
//   502 → "Couldn't reach the spec source" + retry button.
//
// History view is intentionally absent — the operator's framing for
// v0.20.0 is "current version only; git is the history surface".
// A small "View on gitea" link beside the title points at the
// upstream source URL the manifest carries so the history gesture
// remains one click away.

import { useEffect, useState, useCallback } from 'react'
import { Link, useParams } from 'react-router-dom'
import MarkdownPreview from './MarkdownPreview.jsx'
import { getSpec, getSpecsManifest } from '../api.js'
import { EVENTS, track } from '../lib/analytics'

export default function DocsSpec() {
  const { name } = useParams()
  const [title, setTitle] = useState('')
  const [sourceUrl, setSourceUrl] = useState('')
  const [body, setBody] = useState('')
  const [status, setStatus] = useState('loading') // loading | ok | notfound | error
  const [reloadTick, setReloadTick] = useState(0)

  useEffect(() => {
    track(EVENTS.DOC_VIEWED, { section: `specs/${name}` })
  }, [name])

  // Title + upstream URL from the manifest (cheap — the manifest is
  // derived from an env var on the backend, no network).
  useEffect(() => {
    let active = true
    getSpecsManifest()
      .then(payload => {
        if (!active) return
        const entry = (payload && payload.specs || []).find(s => s.name === name)
        setTitle((entry && entry.title) || '')
        setSourceUrl((entry && entry.url) || '')
      })
      .catch(() => {
        // Title + source link are decorative; the body fetch below
        // is the load-bearing one. A failed manifest fetch just
        // leaves the page rendering the bare name.
      })
    return () => { active = false }
  }, [name])

  useEffect(() => {
    let active = true
    setStatus('loading')
    getSpec(name)
      .then(text => {
        if (!active) return
        setBody(text || '')
        setStatus('ok')
      })
      .catch(e => {
        if (!active) return
        if (e.status === 404) {
          setStatus('notfound')
        } else {
          setStatus('error')
        }
      })
    return () => { active = false }
  }, [name, reloadTick])

  const retry = useCallback(() => setReloadTick(t => t + 1), [])

  const header = title || `Spec: ${name}`

  return (
    <article className="docs-article">
      <header className="docs-article-header">
        <h1 className="docs-article-title">{header}</h1>
        {sourceUrl && (
          <a
            className="docs-source-link"
            href={sourceUrl}
            target="_blank"
            rel="noopener noreferrer"
            aria-label="View spec source on gitea"
            data-amp-track-name="Docs Spec Source Link"
            data-amp-track-spec={name}
          >
            View source
          </a>
        )}
      </header>
      {status === 'loading' && <p className="muted">Loading…</p>}
      {status === 'notfound' && (
        <div className="docs-empty">
          <p>This spec isn't available.</p>
          <p>
            <Link
              to="/docs/user-guide"
              aria-label="User guide"
              data-amp-track-name="Docs Spec Notfound User Guide Link"
            >
              ← Back to the user guide
            </Link>
          </p>
        </div>
      )}
      {status === 'error' && (
        <div className="docs-error" role="alert">
          <p>Couldn't reach the spec source.</p>
          <button
            type="button"
            onClick={retry}
            aria-label="Retry"
            data-amp-track-name="Docs Spec Retry"
          >
            Try again
          </button>
        </div>
      )}
      {status === 'ok' && (
        <div className="philosophy-body">
          <MarkdownPreview content={body} />
        </div>
      )}
    </article>
  )
}
