/**
 * NACHVERFOLGUNG: "Nachverfolgungsinformationen" — read-only modal showing the
 * data provenance of an imported gerbil (which source files contributed, how many
 * raw records were merged, how the parents were derived, and human-readable notes).
 *
 * The provenance arrives as a JSON string on the Gerbil DTO (produced by the Python
 * merge step). We parse it here defensively; anything unparseable / absent is shown
 * as "Keine Herkunftsdaten vorhanden." Mirrors the ReportErrorDialog modal pattern.
 */
import { useEffect } from 'react'
import { de } from '../strings/de'
import type { EntityProvenance } from '../api/types'
import './provenanceDialog.css'

/** Leading marker the Python merge prefixes onto discard ("verworfen") history
 *  lines (data thrown away with reason + replacement). Kept in sync with
 *  DISCARD_MARK in tools/import/merge_and_resolve.py. */
const DISCARD_PREFIX = '⚠ '

interface ProvenanceDialogProps {
  open: boolean
  onClose: () => void
  /** Raw provenance JSON string from the entity (Gerbil/Contact/Litter; null = no import data). */
  provenance?: string | null
  /** Optional entity label (e.g. "dieses Tiers", "dieses Kontakts") for the intro line. */
  entityLabel?: string
}

/** Parse the JSON provenance string defensively; null on absence / parse error. */
function parseProvenance(raw?: string | null): EntityProvenance | null {
  if (!raw || !raw.trim()) return null
  try {
    const p = JSON.parse(raw) as Partial<EntityProvenance>
    return {
      sourceFiles: Array.isArray(p.sourceFiles) ? p.sourceFiles : [],
      mergedRecordCount: typeof p.mergedRecordCount === 'number' ? p.mergedRecordCount : 0,
      fromWurfchronik: Boolean(p.fromWurfchronik),
      parentMethod: p.parentMethod,
      parentConfidence: p.parentConfidence,
      notes: Array.isArray(p.notes) ? p.notes : [],
      history: Array.isArray(p.history) ? p.history : [],
    }
  } catch {
    return null
  }
}

export default function ProvenanceDialog({ open, onClose, provenance, entityLabel }: ProvenanceDialogProps) {
  // Close on Escape (only while mounted).
  useEffect(() => {
    if (!open) return
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') onClose()
    }
    window.addEventListener('keydown', onKey)
    return () => window.removeEventListener('keydown', onKey)
  }, [open, onClose])

  if (!open) return null

  const t = de.provenance
  const p = parseProvenance(provenance)
  const method = p?.parentMethod ? (t.methods[p.parentMethod] ?? p.parentMethod) : null
  const confidence = p?.parentConfidence
    ? (t.confidences[p.parentConfidence] ?? p.parentConfidence)
    : null

  return (
    <div className="provenance__backdrop" onClick={onClose} role="presentation">
      <div
        className="provenance__dialog"
        role="dialog"
        aria-modal="true"
        aria-labelledby="provenance-title"
        onClick={(e) => e.stopPropagation()}
      >
        <div className="provenance__header">
          <h2 id="provenance-title" className="provenance__title">
            {t.dialogTitle}
          </h2>
          <button
            type="button"
            className="provenance__close"
            onClick={onClose}
            aria-label={t.close}
          >
            ✕
          </button>
        </div>

        {!p ? (
          <p className="provenance__empty">{t.empty}</p>
        ) : (
          <>
            <p className="provenance__intro">{entityLabel ? t.introFor(entityLabel) : t.intro}</p>

            {p.history.length > 0 && (
              <section className="provenance__section">
                <div className="provenance__section-title">{t.historyTitle}</div>
                {p.history.some((s) => s.startsWith(DISCARD_PREFIX)) && (
                  <p className="provenance__discard-legend">{t.discardLegend}</p>
                )}
                <ol className="provenance__history">
                  {p.history.map((step, i) => {
                    // Discard lines (Python prefixes them with „⚠ “) are styled
                    // distinctly so a thrown-away value stands out from accepted facts.
                    const isDiscard = step.startsWith(DISCARD_PREFIX)
                    return (
                      <li
                        key={`${i}-${step}`}
                        className={
                          isDiscard
                            ? 'provenance__history-step provenance__history-step--discard'
                            : 'provenance__history-step'
                        }
                      >
                        {step}
                      </li>
                    )
                  })}
                </ol>
              </section>
            )}

            <section className="provenance__section">
              <div className="provenance__section-title">
                {t.mergedTitle}
              </div>
              <p className="provenance__merged">{t.mergedCount(p.mergedRecordCount)}</p>
              {p.fromWurfchronik && (
                <p className="provenance__wurfchronik">📖 {t.fromWurfchronik}</p>
              )}
            </section>

            <section className="provenance__section">
              <div className="provenance__section-title">
                {t.sourceFilesTitle} — {t.sourceFilesCount(p.sourceFiles.length)}
              </div>
              {p.sourceFiles.length === 0 ? (
                <p className="provenance__empty">{t.empty}</p>
              ) : (
                <ul className="provenance__files">
                  {p.sourceFiles.map((f) => (
                    <li key={f} className="provenance__file">
                      {f}
                    </li>
                  ))}
                </ul>
              )}
            </section>

            {(method || confidence) && (
              <section className="provenance__section">
                <div className="provenance__section-title">{t.parentsTitle}</div>
                <dl className="provenance__kvlist">
                  {method && (
                    <div className="provenance__kv">
                      <dt>{t.parentMethodLabel}</dt>
                      <dd>{method}</dd>
                    </div>
                  )}
                  {confidence && (
                    <div className="provenance__kv">
                      <dt>{t.parentConfidenceLabel}</dt>
                      <dd>{confidence}</dd>
                    </div>
                  )}
                </dl>
              </section>
            )}

            {p.notes.length > 0 && (
              <section className="provenance__section">
                <div className="provenance__section-title">{t.notesTitle}</div>
                <ul className="provenance__notes">
                  {p.notes.map((n) => (
                    <li key={n}>{n}</li>
                  ))}
                </ul>
              </section>
            )}
          </>
        )}

        <div className="provenance__actions">
          <button type="button" className="btn btn--primary" onClick={onClose}>
            {t.close}
          </button>
        </div>
      </div>
    </div>
  )
}
