import { useState } from 'react'
import { Link, useSearchParams } from 'react-router-dom'
import PublicLayout from '../../components/PublicLayout.jsx'
import PageHeader from '../../components/PageHeader.jsx'
import { Loading, ErrorState, EmptyState } from '../../components/PageState.jsx'
import { useAsync } from '../../lib/useAsync.js'
import { api } from '../../api/client.js'
import { useSite } from '../../contexts/SiteContext.jsx'

function SearchBox({ initial, onSubmit }) {
  const [term, setTerm] = useState(initial || '')
  return (
    <form
      onSubmit={(e) => {
        e.preventDefault()
        onSubmit(term.trim())
      }}
      style={{ display: 'flex', gap: 8, maxWidth: 460, margin: '0 auto 8px' }}
    >
      <input
        type="search"
        value={term}
        onChange={(e) => setTerm(e.target.value)}
        className="input"
        placeholder="Search the wiki…"
      />
      <button type="submit" className="btn btn-primary btn-sq">
        Search
      </button>
    </form>
  )
}

// Group published pages under their category, preserving category sort order and
// collecting anything uncategorized into a trailing section.
function groupByCategory(categories, pages) {
  const byId = new Map(categories.map((c) => [c.id, { ...c, pages: [] }]))
  const uncategorized = []
  for (const page of pages) {
    const bucket = page.category_id != null ? byId.get(page.category_id) : null
    if (bucket) bucket.pages.push(page)
    else uncategorized.push(page)
  }
  const sections = [...byId.values()].filter((c) => c.pages.length > 0)
  if (uncategorized.length) {
    sections.push({ id: 'uncategorized', title: 'Other Pages', description: '', pages: uncategorized })
  }
  return sections
}

function PageCard({ page }) {
  return (
    <Link to={`/wiki/${page.slug}`} className="card" style={{ padding: 22 }}>
      <h3 className="display" style={{ margin: '0 0 6px', fontSize: '1.1rem', color: 'var(--head)' }}>
        {page.title}
      </h3>
      <p className="muted" style={{ margin: 0, fontSize: '0.92rem' }}>
        {page.excerpt || 'Open the guide →'}
      </p>
    </Link>
  )
}

export default function Wiki() {
  const { siteShortName } = useSite()
  const [searchParams, setSearchParams] = useSearchParams()
  const activeCategory = searchParams.get('category')
  const activeTag = searchParams.get('tag')
  const activeQ = searchParams.get('q')
  // Search / tag views fetch a filtered page list; otherwise all pages (grouped here).
  const pageOpts = activeQ ? { q: activeQ } : activeTag ? { tag: activeTag } : {}
  const { loading, error, data } = useAsync(
    () =>
      Promise.all([api.wikiCategories(), api.wiki(pageOpts)]).then(([categories, pages]) => ({
        categories,
        pages,
      })),
    [activeTag, activeQ],
  )

  const allSections = data ? groupByCategory(data.categories, data.pages) : []
  const sections = activeCategory
    ? allSections.filter((s) => s.slug === activeCategory)
    : allSections
  const hasPages = data && data.pages.length > 0
  const flat = Boolean(activeTag || activeQ) // flat-list views
  const filtered = Boolean(activeCategory || activeTag || activeQ)

  const runSearch = (term) => setSearchParams(term ? { q: term } : {})

  return (
    <PublicLayout section="wiki">
      <div className="shell page-body">
        <PageHeader
          center
          eyebrow="Knowledge base"
          title={`${siteShortName} Wiki`}
          lead="A calm starting point for shard guides, the world and its lore, gameplay systems, and community rules."
        />
        <SearchBox initial={activeQ || ''} onSubmit={runSearch} />

        {loading && <Loading />}
        {error && <ErrorState message="Could not load the wiki right now." />}
        {!loading && !error && !hasPages && !filtered && <EmptyState>No wiki pages yet.</EmptyState>}

        {!loading && !error && filtered && (
          <p className="sans" style={{ margin: '0 0 8px', fontSize: '0.85rem' }}>
            <Link to="/wiki" style={{ color: 'var(--accent)', textDecoration: 'none' }}>
              ← All sections
            </Link>
            {activeTag && <span className="muted"> · Tagged #{activeTag}</span>}
            {activeQ && <span className="muted"> · Results for “{activeQ}”</span>}
          </p>
        )}

        {/* Flat list: search results or a tag filter (both cross categories). */}
        {!loading && !error && flat &&
          (data.pages.length === 0 ? (
            <EmptyState>{activeQ ? 'No pages match that search.' : 'No pages with this tag.'}</EmptyState>
          ) : (
            <div className="grid-4" style={{ marginTop: 12 }}>
              {data.pages.map((p) => (
                <PageCard key={p.slug} page={p} />
              ))}
            </div>
          ))}

        {/* Category / full view: grouped sections. */}
        {!loading && !error && !flat && hasPages && activeCategory && sections.length === 0 && (
          <EmptyState>No pages in this section yet.</EmptyState>
        )}
        {!flat &&
          sections.map((section) => (
            <section key={section.id} style={{ marginTop: 36 }}>
              <h2
                className="display"
                style={{ margin: '0 0 4px', fontSize: '1.5rem', color: 'var(--accent)' }}
              >
                {section.title}
              </h2>
              {section.description && (
                <p className="muted" style={{ margin: '0 0 16px', fontSize: '0.95rem' }}>
                  {section.description}
                </p>
              )}
              <div className="grid-4" style={{ marginTop: section.description ? 0 : 12 }}>
                {section.pages.map((p) => (
                  <PageCard key={p.slug} page={p} />
                ))}
              </div>
            </section>
          ))}
      </div>
    </PublicLayout>
  )
}
