'use client'

import { useEffect, useState } from 'react'
import BulkDiffPanel from './BulkDiffPanel'

interface HistoryEntry {
  cid: string
  version: string | null
  document_type: string | null
  document_id: string | null
  parent_cid: string | null
  created_at: string | null
  checksum: string | null
}

interface DiffResponse {
  kind: 'text' | 'binary'
  cid_a: string
  cid_b: string
  metadata_diff: Record<string, { old: unknown; new: unknown }>
  diff?: string
  added_lines?: number
  removed_lines?: number
  note?: string
}

interface Props {
  cid: string
  onClose: () => void
}

function shorten(cid: string): string {
  if (cid.length <= 14) return cid
  return cid.slice(0, 8) + '…' + cid.slice(-6)
}

export default function CIDHistoryModal({ cid, onClose }: Props) {
  const [history, setHistory] = useState<HistoryEntry[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [diffPair, setDiffPair] = useState<{ a: string; b: string } | null>(null)
  const [diff, setDiff] = useState<DiffResponse | null>(null)
  const [diffLoading, setDiffLoading] = useState(false)
  const [showBulkDiff, setShowBulkDiff] = useState(false)

  useEffect(() => {
    let cancel = false
    setLoading(true)
    setError(null)
    fetch(`/api/sdk/v1/dsms/documents/${encodeURIComponent(cid)}/history`)
      .then(async (r) => {
        if (!r.ok) throw new Error(`HTTP ${r.status}`)
        const json = await r.json()
        if (!cancel) setHistory(json.history || [])
      })
      .catch((e) => {
        if (!cancel) setError(e?.message || 'Fehler beim Laden')
      })
      .finally(() => {
        if (!cancel) setLoading(false)
      })
    return () => {
      cancel = true
    }
  }, [cid])

  async function loadDiff(a: string, b: string) {
    setDiffPair({ a, b })
    setDiff(null)
    setDiffLoading(true)
    try {
      const res = await fetch(
        `/api/sdk/v1/dsms/documents/${encodeURIComponent(a)}/diff/${encodeURIComponent(b)}`
      )
      if (res.ok) {
        const json = (await res.json()) as DiffResponse
        setDiff(json)
      } else {
        setDiff({ kind: 'binary', cid_a: a, cid_b: b, metadata_diff: {}, note: `HTTP ${res.status}` })
      }
    } finally {
      setDiffLoading(false)
    }
  }

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4" onClick={onClose}>
      <div
        className="w-full max-w-3xl max-h-[90vh] overflow-hidden flex flex-col bg-white dark:bg-gray-800 rounded-xl shadow-xl"
        onClick={(e) => e.stopPropagation()}
      >
        <div className="flex items-center justify-between px-5 py-3 border-b border-gray-200 dark:border-gray-700">
          <div>
            <h2 className="text-sm font-semibold text-gray-900 dark:text-white">DSMS-Versionsverlauf</h2>
            <code className="text-[10px] font-mono text-gray-500 dark:text-gray-400">{shorten(cid)}</code>
          </div>
          <button onClick={onClose} className="text-gray-500 hover:text-gray-700 dark:text-gray-400 text-sm">
            Schliessen
          </button>
        </div>

        <div className="flex-1 overflow-y-auto p-5 space-y-4">
          {loading && <div className="text-sm text-gray-500">Verlauf wird geladen…</div>}
          {error && <div className="text-sm text-red-600 dark:text-red-400">{error}</div>}

          {!loading && !error && history.length === 0 && (
            <div className="text-sm text-gray-500 italic">
              Kein Versionsverlauf gefunden. Diese CID hat keine parent_cid-Kette.
            </div>
          )}

          {!loading && !error && history.length > 0 && (
            <>
              <div className="flex items-center justify-between gap-3 flex-wrap">
                <div className="text-xs text-gray-500 dark:text-gray-400">
                  {history.length} Version{history.length > 1 ? 'en' : ''} in der Kette (neueste oben).
                </div>
                {history.length > 1 && (
                  <button
                    onClick={() => setShowBulkDiff((v) => !v)}
                    className="text-[11px] px-2 py-1 rounded border border-purple-300 text-purple-700 hover:bg-purple-50 dark:border-purple-700 dark:text-purple-300 dark:hover:bg-purple-900/30"
                    title="Aggregierter Diff ueber alle Versionen"
                  >
                    {showBulkDiff ? 'Bulk-Diff ausblenden' : `Bulk-Diff V1 → V${history[0].version || '?'} anzeigen`}
                  </button>
                )}
              </div>

              {showBulkDiff && <BulkDiffPanel cid={cid} onClose={() => setShowBulkDiff(false)} />}
              <ol className="relative border-l-2 border-emerald-500/40 pl-4 space-y-3">
                {history.map((entry, idx) => {
                  const next = history[idx + 1]
                  return (
                    <li key={entry.cid} className="relative">
                      <div className="absolute -left-[1.4rem] top-1.5 w-3 h-3 rounded-full bg-emerald-500 ring-2 ring-white dark:ring-gray-800" />
                      <div className="bg-gray-50 dark:bg-gray-900/40 rounded-lg p-3 border border-gray-200 dark:border-gray-700">
                        <div className="flex items-center justify-between gap-2">
                          <div className="min-w-0">
                            <div className="text-sm font-medium text-gray-900 dark:text-white">
                              Version {entry.version || '?'} {idx === 0 && <span className="ml-2 text-[10px] text-emerald-600 font-semibold">AKTUELL</span>}
                            </div>
                            <code className="text-[10px] font-mono text-gray-500 dark:text-gray-400 break-all">{entry.cid}</code>
                          </div>
                          {next && (
                            <button
                              onClick={() => loadDiff(next.cid, entry.cid)}
                              className="shrink-0 text-[11px] text-purple-600 hover:text-purple-800 dark:text-purple-400 hover:underline"
                              title="Aenderungen zur Vorversion anzeigen"
                            >
                              Diff zu V{next.version || '?'}
                            </button>
                          )}
                        </div>
                        <div className="mt-1 text-[11px] text-gray-500 dark:text-gray-400 flex flex-wrap gap-x-3 gap-y-0.5">
                          {entry.document_type && <span>Typ: {entry.document_type}</span>}
                          {entry.document_id && <span>Dok-ID: {entry.document_id}</span>}
                          {entry.created_at && <span>{new Date(entry.created_at).toLocaleString('de-DE')}</span>}
                        </div>
                        {entry.checksum && (
                          <div className="mt-1 text-[10px] text-gray-400 font-mono">SHA-256: {entry.checksum.slice(0, 16)}…</div>
                        )}
                      </div>
                    </li>
                  )
                })}
              </ol>
            </>
          )}

          {diffPair && (
            <div className="mt-4 border-t border-gray-200 dark:border-gray-700 pt-4 space-y-2">
              <div className="flex items-center justify-between">
                <h3 className="text-xs font-semibold text-gray-900 dark:text-white">
                  Diff: {shorten(diffPair.a)} → {shorten(diffPair.b)}
                </h3>
                <button onClick={() => { setDiff(null); setDiffPair(null) }} className="text-[11px] text-gray-500 hover:text-gray-700">
                  Schliessen
                </button>
              </div>
              {diffLoading && <div className="text-xs text-gray-500">Diff wird geladen…</div>}
              {!diffLoading && diff && (
                <>
                  {Object.keys(diff.metadata_diff || {}).length > 0 && (
                    <div className="text-xs">
                      <div className="font-medium text-gray-700 dark:text-gray-300 mb-1">Metadaten-Aenderungen</div>
                      <table className="w-full">
                        <tbody>
                          {Object.entries(diff.metadata_diff).map(([field, { old, new: nv }]) => (
                            <tr key={field} className="border-b border-gray-100 dark:border-gray-800">
                              <td className="py-0.5 pr-2 font-mono text-[10px] text-gray-500">{field}</td>
                              <td className="py-0.5 pr-2 text-red-600 dark:text-red-400 line-through">{JSON.stringify(old)}</td>
                              <td className="py-0.5 text-green-700 dark:text-green-400">{JSON.stringify(nv)}</td>
                            </tr>
                          ))}
                        </tbody>
                      </table>
                    </div>
                  )}
                  {diff.kind === 'text' && diff.diff && (
                    <>
                      <div className="text-[11px] text-gray-500">
                        {diff.added_lines ?? 0} Zeilen hinzu, {diff.removed_lines ?? 0} entfernt
                      </div>
                      <pre className="text-[10px] font-mono whitespace-pre-wrap bg-gray-900 text-gray-100 p-3 rounded max-h-64 overflow-y-auto">
                        {diff.diff}
                      </pre>
                    </>
                  )}
                  {diff.kind === 'binary' && (
                    <div className="text-xs text-amber-700 dark:text-amber-400 italic">
                      {diff.note || 'Binaere Datei — kein Text-Diff verfuegbar.'}
                    </div>
                  )}
                </>
              )}
            </div>
          )}
        </div>
      </div>
    </div>
  )
}
