import { useEffect, useMemo, useState } from 'react'
import { diffWords } from 'diff'
import Modal from '../../../components/Modal.jsx'
import { dateTime } from '../../../lib/format.js'
import { api } from '../../../api/client.js'

// Plain-text view of a body, for a readable word-level diff.
function toText(html) {
  if (!html) return ''
  if (typeof window === 'undefined' || !window.DOMParser) return html
  const doc = new DOMParser().parseFromString(html, 'text/html')
  return doc.body.textContent || ''
}

export default function WikiHistory({ slug, onClose, onRestored }) {
  const [revisions, setRevisions] = useState([])
  const [current, setCurrent] = useState(null)
  const [selected, setSelected] = useState(null) // full revision snapshot
  const [loading, setLoading] = useState(true)
  const [busy, setBusy] = useState(false)
  const [error, setError] = useState('')

  useEffect(() => {
    let active = true
    Promise.all([api.admin.listWikiRevisions(slug), api.admin.getWiki(slug)])
      .then(([revs, page]) => {
        if (!active) return
        setRevisions(revs)
        setCurrent(page)
      })
      .catch(() => active && setError('Could not load history.'))
      .finally(() => active && setLoading(false))
    return () => {
      active = false
    }
  }, [slug])

  async function selectRevision(id) {
    setError('')
    try {
      const rev = await api.admin.getWikiRevision(slug, id)
      setSelected(rev)
    } catch (err) {
      setError(err.message || 'Could not load revision.')
    }
  }

  async function restore() {
    if (!selected) return
    if (!confirm(`Restore the page to revision #${selected.id}? This creates a new revision.`)) return
    setBusy(true)
    try {
      await api.admin.restoreWikiRevision(slug, selected.id)
      onRestored()
    } catch (err) {
      setError(err.message || 'Could not restore.')
      setBusy(false)
    }
  }

  // Diff the selected revision (old) against the current saved page (new).
  const parts = useMemo(
    () => (selected ? diffWords(toText(selected.body), toText(current?.body || '')) : []),
    [selected, current],
  )

  return (
    <Modal
      title={`History — ${slug}`}
      onClose={onClose}
      width={760}
      footer={
        <>
          <button onClick={onClose} disabled={busy} className="pill">
            Close
          </button>
          <button onClick={restore} disabled={busy || !selected} className="btn btn-primary btn-sq">
            {busy ? 'Restoring…' : 'Restore this revision'}
          </button>
        </>
      }
    >
      {loading && <span className="spin" />}
      {!loading && error && (
        <p className="sans" style={{ margin: 0, color: '#d98b84', fontSize: '0.85rem' }}>{error}</p>
      )}
      {!loading && !error && (
        <div className="wiki-history">
          <ul className="wiki-history-list">
            {revisions.map((r, i) => (
              <li key={r.id}>
                <button
                  type="button"
                  className={`wiki-rev${selected?.id === r.id ? ' is-active' : ''}`}
                  onClick={() => selectRevision(r.id)}
                >
                  <span className="wiki-rev-note">
                    {r.change_note || 'Edit'}
                    {i === 0 && <span className="wiki-rev-latest"> · latest</span>}
                  </span>
                  <span className="wiki-rev-meta">
                    {dateTime(r.created_at)}
                    {r.editor ? ` · ${r.editor}` : ''}
                  </span>
                </button>
              </li>
            ))}
            {revisions.length === 0 && <li className="dim sans" style={{ fontSize: '0.85rem' }}>No revisions yet.</li>}
          </ul>

          <div className="wiki-history-diff">
            {!selected ? (
              <p className="muted sans" style={{ fontSize: '0.9rem' }}>
                Select a revision to see what changed between it and the current page.
              </p>
            ) : (
              <>
                <p className="sans dim" style={{ margin: '0 0 10px', fontSize: '0.76rem' }}>
                  Diff: revision #{selected.id} → current
                </p>
                <div className="wiki-diff">
                  {parts.length === 0 || (parts.length === 1 && !parts[0].added && !parts[0].removed) ? (
                    <span className="muted">No textual differences.</span>
                  ) : (
                    parts.map((p, i) => {
                      let cls = ''
                      if (p.added) cls = 'diff-add'
                      else if (p.removed) cls = 'diff-del'
                      return (
                        <span key={`${i}:${p.value}`} className={cls}>
                          {p.value}
                        </span>
                      )
                    })
                  )}
                </div>
              </>
            )}
          </div>
        </div>
      )}
    </Modal>
  )
}
