/**
 * VerifierRiskDocument.jsx
 *
 * Page 1: Risk Assignment Document table (all snaps, scrollable)
 * Page 2: Report Preview (exact Risk Reduction Plan table structure)
 *         → Print / Download button
 */
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
import {
  completeVerifierAssessment,
  fetchAssessmentListProjection,
  fetchFormWithSectionsAndQuestions,
  fetchObservations,
  fetchVerificationFlowsForAssessment,
  returnAssessmentToExecutor
} from '../../api.js';
import { API_BASE_URL, getAuthToken } from '../../apiConfig.js';
import {
  buildDynamicColumns,
  extractAnswerMapsFromTiming,
  resolveCellRaw
} from '../../utils/oracRiskTableColumns.js';
import './VerifierPage.css';
import './VerifierRiskDocument.css';

// ── Shared helpers ────────────────────────────────────────────────────────────

function fmt(v) { return v || '—'; }

function fmtDate(v) {
  if (!v) return '—';
  try { return new Date(v).toLocaleDateString('en-IN', { day: '2-digit', month: 'short', year: 'numeric' }); }
  catch { return String(v); }
}

function safeJson(str) {
  if (!str) return null;
  if (typeof str === 'object' && !Array.isArray(str)) return str;
  try { return JSON.parse(str); } catch { return null; }
}

function parseTiming(snap) {
  const raw = snap?.snap_timing;
  if (!raw) return {};
  return safeJson(raw) || {};
}

/** Convert MySQL2 LONGBLOB snap → data-URL (chunked safe, handles all Buffer shapes) */
function bufferToDataUrl(raw) {
  if (!raw) return null;
  if (typeof raw === 'string' && raw.startsWith('data:')) return raw;

  // Buffer-like: { type:'Buffer', data:[...] }
  let bytes = null;
  if (raw && typeof raw === 'object' && raw.type === 'Buffer' && Array.isArray(raw.data)) {
    bytes = new Uint8Array(raw.data);
  } else if (raw instanceof Uint8Array) {
    bytes = raw;
  } else if (raw?.buffer instanceof ArrayBuffer) {
    bytes = new Uint8Array(raw.buffer);
  }

  if (bytes) {
    // Chunked to avoid call-stack limit with large images
    const CHUNK = 8192;
    let binary = '';
    for (let i = 0; i < bytes.length; i += CHUNK) {
      binary += String.fromCharCode(...bytes.subarray(i, i + CHUNK));
    }
    try { return `data:image/jpeg;base64,${btoa(binary)}`; } catch { return null; }
  }

  if (typeof raw === 'string' && raw.length > 100 && !/\s/.test(raw)) {
    return `data:image/jpeg;base64,${raw}`;
  }
  if (typeof raw === 'string' && raw.length > 0) {
    return `${API_BASE_URL}/${raw.replace(/\\/g, '/')}`;
  }
  return null;
}

/** `${base}/api/...` with empty base → `/api/...` (same-origin behind Vite proxy). */
function snapImageUrl(snapId, assessmentId) {
  const sid = encodeURIComponent(snapId);
  const aid = encodeURIComponent(assessmentId);
  return `${API_BASE_URL}/api/orac/orac_snaps/${sid}/${aid}/image`;
}

/**
 * SnapImage — fetches snap via the dedicated /image endpoint (bypasses JSON Buffer).
 * Uses blob: URLs (not huge data: URLs). Ref-tracks the URL so cleanup/revoke is correct
 * under React Strict Mode. Do not depend on `snap.snap` (list API omits it).
 */
function SnapImage({ snap, className, style }) {
  const [src, setSrc] = useState(null);
  const objectUrlRef = useRef(null);

  useEffect(() => {
    const sidRaw = snap?.snap_id;
    const aidRaw = snap?.assessment_id;
    const sid = sidRaw != null ? Number(sidRaw) : NaN;
    const aid = aidRaw != null ? Number(aidRaw) : NaN;
    if (!Number.isFinite(sid) || !Number.isFinite(aid)) {
      setSrc(bufferToDataUrl(snap?.snap));
      return undefined;
    }

    const hasSnap = snap?.has_snap;
    const definitelyNoBlob =
      hasSnap === 0 ||
      hasSnap === false ||
      hasSnap === '0' ||
      (typeof hasSnap === 'string' && hasSnap.trim() === '0');
    if (definitelyNoBlob) {
      setSrc(bufferToDataUrl(snap?.snap));
      return undefined;
    }

    let cancelled = false;
    const token = getAuthToken();

    fetch(snapImageUrl(sid, aid), {
      headers: token ? { Authorization: `Bearer ${token}` } : {},
      cache: 'no-store',
      mode: 'cors',
      credentials: 'omit'
    })
      .then(async (r) => {
        if (!r.ok) {
          const errText = await r.text().catch(() => '');
          if (import.meta.env.DEV && errText) {
            console.warn('[SnapImage]', r.status, snapImageUrl(sid, aid), errText.slice(0, 200));
          }
          return null;
        }
        return r.blob();
      })
      .then((blob) => {
        if (cancelled) return;
        if (!blob || blob.size === 0) {
          setSrc(bufferToDataUrl(snap?.snap));
          return;
        }
        if (objectUrlRef.current) {
          URL.revokeObjectURL(objectUrlRef.current);
          objectUrlRef.current = null;
        }
        const url = URL.createObjectURL(blob);
        objectUrlRef.current = url;
        setSrc(url);
      })
      .catch((err) => {
        if (import.meta.env.DEV) console.warn('[SnapImage] fetch failed', err);
        if (!cancelled) setSrc(bufferToDataUrl(snap?.snap));
      });

    return () => {
      cancelled = true;
      if (objectUrlRef.current) {
        URL.revokeObjectURL(objectUrlRef.current);
        objectUrlRef.current = null;
      }
    };
  }, [snap?.snap_id, snap?.assessment_id, snap?.has_snap]);

  if (!src) {
    return (
      <div className={`vrd-snap-ph ${className || ''}`} style={style}>
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
          <rect x="3" y="6" width="18" height="14" rx="2"/><circle cx="12" cy="13" r="3"/>
          <path d="M9 6l1.5-3h3L15 6"/>
        </svg>
      </div>
    );
  }
  return (
    <img
      key={src}
      src={src}
      alt=""
      className={className}
      style={style}
      loading="eager"
      decoding="async"
      draggable={false}
      onError={() => {
        if (import.meta.env.DEV) {
          console.warn('[SnapImage] <img> decode failed for snap', snap?.snap_id, snap?.assessment_id);
        }
        const u = objectUrlRef.current;
        objectUrlRef.current = null;
        if (u) URL.revokeObjectURL(u);
        setSrc(null);
      }}
    />
  );
}


// ── RPN role detection (same rules as SnapDetailCreatePage) ──────────────────
function getRpnRole(questionText) {
  const t = (questionText || '').toLowerCase();
  if (t.includes('likelihood of harm')) return 'likelihood';
  if (t.includes('severity of harm')) return 'severity';
  if (t.includes('rpn')) return 'rpn';
  return null;
}

function extractSnapData(snap) {
  const t = parseTiming(snap);
  return extractAnswerMapsFromTiming(t);
}

function renderVerifierDocQuestionCell(byCol, byQid, col) {
  const raw = resolveCellRaw(byCol, byQid, col);
  const display = raw != null && String(raw).trim() !== '' ? String(raw) : '—';
  const role = getRpnRole(col.label);
  if (role === 'likelihood') {
    return <span className="vrd-badge vrd-badge--l">{display}</span>;
  }
  if (role === 'severity') {
    return <span className="vrd-badge vrd-badge--s">{display}</span>;
  }
  if (role === 'rpn') {
    const rpn = Number(display);
    const rpnCls =
      display === '—'
        ? ''
        : rpn >= 32
          ? 'vrd-rpn--hi'
          : rpn >= 8
            ? 'vrd-rpn--mid'
            : 'vrd-rpn--lo';
    return <span className={`vrd-rpn-badge ${rpnCls}`.trim()}>{display}</span>;
  }
  return display;
}

function renderReportQuestionCell(byCol, byQid, col) {
  const raw = resolveCellRaw(byCol, byQid, col);
  const display = raw != null && String(raw).trim() !== '' ? String(raw) : '—';
  const role = getRpnRole(col.label);
  if (role === 'likelihood') {
    return <span className="rp-num rp-num--l">{display}</span>;
  }
  if (role === 'severity') {
    return <span className="rp-num rp-num--s">{display}</span>;
  }
  if (role === 'rpn') {
    const rpnNum = Number(display);
    const rpnClass =
      display === '—'
        ? ''
        : rpnNum >= 32
          ? 'rp-rpn--high'
          : rpnNum >= 8
            ? 'rp-rpn--med'
            : 'rp-rpn--low';
    return <span className={`rp-rpn ${rpnClass}`.trim()}>{display}</span>;
  }
  return display;
}

// ── Confirmation Modal ────────────────────────────────────────────────────────
function ConfirmModal({ onConfirm, onCancel }) {
  return (
    <div className="vrd-overlay" role="dialog" aria-modal>
      <div className="vrd-confirm-modal">
        <div className="vrd-confirm-icon">
          <svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="#ffffff" strokeWidth="2.2">
            <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
            <polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/>
            <line x1="16" y1="17" x2="8" y2="17"/>
          </svg>
        </div>
        <h3>Generate Report</h3>
        <p>Do You Want To Generate Report?</p>
        <div className="vrd-confirm-btns">
          <button className="vrd-btn vrd-btn--ghost" onClick={onCancel}>Cancel</button>
          <button className="vrd-btn vrd-btn--red" onClick={onConfirm}>OK, Generate</button>
        </div>
      </div>
    </div>
  );
}

function ReturnToExecutorModal({ note, onNoteChange, onConfirm, onCancel, submitting }) {
  return (
    <div className="vrd-overlay" role="dialog" aria-modal>
      <div className="vrd-confirm-modal vrd-return-modal">
        <h3>Returned to executor</h3>
        <p>Optional note for the executor (stored in verification history):</p>
        <textarea
          className="vrd-return-textarea"
          value={note}
          onChange={(e) => onNoteChange(e.target.value)}
          rows={4}
          placeholder="e.g. Please re-check snap time at 00:12…"
          disabled={submitting}
        />
        <div className="vrd-confirm-btns">
          <button type="button" className="vrd-btn vrd-btn--ghost" onClick={onCancel} disabled={submitting}>
            Cancel
          </button>
          <button type="button" className="vrd-btn vrd-btn--red" onClick={onConfirm} disabled={submitting}>
            {submitting ? 'Sending…' : 'Return'}
          </button>
        </div>
      </div>
    </div>
  );
}

// ── Report Preview (full-width, printable) — shared by verifier flow & uploader download ──
export function ReportPreview({
  assessment,
  snaps,
  formSchema,
  onBack,
  backLabel = '← Back to Document',
  toolbarChipText = 'Report Generated Successfully'
}) {
  const printRef = useRef(null);
  const dynCols = buildDynamicColumns(formSchema);

  function handlePrint() {
    window.print();
  }

  const today = new Date().toLocaleDateString('en-IN', { day: '2-digit', month: '2-digit', year: 'numeric' });

  const totalCols = dynCols.length + 3;

  return (
    <div className="dashboard-main rp-shell">
      {/* ── Non-printable toolbar ── */}
      <div className="rp-toolbar no-print">
        <button type="button" className="rp-back-btn" onClick={onBack}>
          {backLabel}
        </button>
        <div className="rp-success-chip">
          <span className="rp-dot" />
          {toolbarChipText}
        </div>
        <button className="rp-print-btn" onClick={handlePrint}>
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
            <path d="M6 9V2h12v7M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/>
            <rect x="6" y="14" width="12" height="8"/>
          </svg>
          Download / Print Report
        </button>
      </div>

      {/* ── Printable document ── */}
      <div className="rp-doc" ref={printRef} id="rp-printable">

        {/* Document heading row */}
        <table className="rp-header-table">
          <tbody>
            <tr>
              <td className="rp-meta-cell" style={{ width: '22%' }}>
                <div className="rp-meta-row"><span className="rp-meta-lbl">Site</span><span className="rp-meta-val">{fmt(assessment?.location_name)}</span></div>
                <div className="rp-meta-row"><span className="rp-meta-lbl">Section/Work area</span><span className="rp-meta-val">{fmt(assessment?.department_name)}</span></div>
                <div className="rp-meta-row"><span className="rp-meta-lbl">Contract Details</span><span className="rp-meta-val">{fmt(assessment?.contract_details ?? assessment?.contact_details)}</span></div>
              </td>
              <td className="rp-title-cell">
                <div className="rp-doc-title">Risk Reduction Plan</div>
              </td>
              <td className="rp-dateupdated-cell" style={{ width: '20%' }}>
                <div className="rp-meta-row"><span className="rp-meta-lbl">Date updated</span><span className="rp-meta-val">{today}</span></div>
                <div className="rp-logo-circle">
                  <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="#ffffff" strokeWidth="1.8">
                    <path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10 10-4.5 10-10S17.5 2 12 2z"/>
                    <path d="M12 8v4l3 3"/>
                  </svg>
                </div>
              </td>
            </tr>
          </tbody>
        </table>

        {/* Main risk table */}
        <div className="rp-table-outer">
          <table className="rp-table">
            <thead>
              <tr className="rp-thead-top">
                <th className="rp-th rp-th--serial">#</th>
                <th className="rp-th rp-th--img">Risk violation image</th>
                <th className="rp-th">Snap time</th>
                {dynCols.map((col) => (
                  <th key={col.colKey} className="rp-th rp-th--wide">
                    {col.label}
                  </th>
                ))}
              </tr>
            </thead>
            <tbody>
              {snaps.length === 0 ? (
                <tr>
                  <td colSpan={totalCols} className="rp-empty">No risk observations found for this assessment.</td>
                </tr>
              ) : snaps.map((snap, i) => {
                const { byCol, byQid, violationTime } = extractSnapData(snap);
                return (
                  <tr key={snap.snap_id || i} className={i % 2 === 0 ? 'rp-tr rp-tr--even' : 'rp-tr rp-tr--odd'}>
                    <td className="rp-td rp-td--center">{i + 1}</td>
                    <td className="rp-td rp-td--img">
                      <SnapImage snap={snap} className="rp-snap-img" />
                    </td>
                    <td className="rp-td rp-td--center rp-td--mono">{violationTime}</td>
                    {dynCols.map((col) => (
                      <td key={col.colKey} className="rp-td">
                        {renderReportQuestionCell(byCol, byQid, col)}
                      </td>
                    ))}
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>

        {/* Document footer */}
        <div className="rp-doc-footer">
          <span>Generated: {today}</span>
          <span>Total Risk Observations: {snaps.length}</span>
          <span>Assessment: {fmt(assessment?.video_title)}</span>
        </div>
      </div>
    </div>
  );
}

// ── Dynamic table for the main document view ──────────────────────────────────
function DynamicSnapTable({ snaps, formSchema }) {
  const dynCols = buildDynamicColumns(formSchema);
  const totalCols = dynCols.length + 3;
  return (
    <table className="vp-table vrd-table">
      <thead>
        <tr>
          <th className="vp-th vrd-th vrd-th--narrow" style={{ width: 40 }}>#</th>
          <th className="vp-th vrd-th" style={{ width: 110 }}>
            Risk violation image
          </th>
          <th className="vp-th vrd-th" style={{ width: 88 }}>
            Snap time
          </th>
          {dynCols.map((col) => (
            <th key={col.colKey} className="vp-th vrd-th">
              {col.label}
            </th>
          ))}
        </tr>
      </thead>
      <tbody>
        {snaps.length === 0 ? (
          <tr>
            <td colSpan={totalCols} className="vp-empty vrd-td-empty">
              <svg width="38" height="38" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.2" opacity="0.35">
                <rect x="3" y="3" width="18" height="18" rx="2"/><path d="M9 9h.01M15 9h.01M9 15h6"/>
              </svg>
              <p>No snap observations for this assessment.</p>
            </td>
          </tr>
        ) : snaps.map((snap, i) => {
          const { byCol, byQid, violationTime } = extractSnapData(snap);
          return (
            <tr key={snap.snap_id || i} className="vp-row vrd-tr">
              <td className="vp-td vrd-td vrd-td--ctr">{i + 1}</td>
              <td className="vp-td vrd-td vrd-td--img">
                <SnapImage snap={snap} className="vrd-snap-img" />
              </td>
              <td className="vp-td vrd-td vrd-td--ctr vrd-td--mono">{violationTime}</td>
              {dynCols.map((col) => (
                <td key={col.colKey} className="vp-td vrd-td">
                  {renderVerifierDocQuestionCell(byCol, byQid, col)}
                </td>
              ))}
            </tr>
          );
        })}
      </tbody>
    </table>
  );
}

// ── Risk Assignment Document (main view) ──────────────────────────────────────
export default function VerifierRiskDocument({ assessment, onBack }) {
  const [snaps, setSnaps]               = useState([]);
  const [loading, setLoading]           = useState(true);
  const [error, setError]               = useState('');
  const [showConfirm, setShowConfirm]   = useState(false);
  const [generating, setGenerating]     = useState(false);
  const [reportReady, setReportReady]   = useState(false);
  const [reportGenerated, setReportGenerated] = useState(false);
  const [showReturnModal, setShowReturnModal] = useState(false);
  const [returnNote, setReturnNote]     = useState('');
  const [returnSubmitting, setReturnSubmitting] = useState(false);
  const [verificationFlowCount, setVerificationFlowCount] = useState(0);
  const [formSchema, setFormSchema]     = useState(null);
  /** Same merge as UserRiskReductionReportPage — list projection can be fresher than queue row. */
  const [resolvedAssessment, setResolvedAssessment] = useState(assessment);
  const assessmentRef = useRef(assessment);
  useLayoutEffect(() => {
    assessmentRef.current = assessment;
  });
  useEffect(() => {
    setResolvedAssessment(assessment);
  }, [assessment?.assessment_id]);

  const load = useCallback(() => {
    const aid = Number(assessment?.assessment_id);
    if (!Number.isFinite(aid) || aid <= 0) {
      setSnaps([]);
      setLoading(false);
      return;
    }
    setLoading(true);
    setError('');
    Promise.all([
      fetchObservations(aid),
      fetchVerificationFlowsForAssessment(aid).catch(() => []),
      fetchAssessmentListProjection(aid).catch(() => null)
    ])
      .then(([rows, flows, projRow]) => {
        const snapList = Array.isArray(rows) ? rows : [];
        setSnaps(snapList);
        setVerificationFlowCount(Array.isArray(flows) ? flows.length : 0);

        const base = assessmentRef.current;
        const merged =
          projRow && typeof projRow === 'object' ? { ...base, ...projRow } : { ...base };
        setResolvedAssessment(merged);

        // Extract form_id from first snap's timing or from assessment, then load schema
        const firstSnap = snapList[0];
        const timingFormId = firstSnap ? safeJson(firstSnap.snap_timing)?.form_id : null;
        const formId = timingFormId ?? merged.form_id ?? merged.orac_form_id;
        const fid = formId != null ? Number(formId) : null;
        if (fid && Number.isFinite(fid) && fid > 0) {
          fetchFormWithSectionsAndQuestions(fid)
            .then((schema) => setFormSchema(schema))
            .catch(() => setFormSchema(null));
        } else {
          setFormSchema(null);
        }
      })
      .catch((e) => setError(e.message))
      .finally(() => setLoading(false));
  }, [assessment?.assessment_id, assessment?.form_id, assessment?.orac_form_id]);

  useEffect(() => { load(); }, [load]);

  function handleGenerateClick() { setShowConfirm(true); }

  async function handleConfirmOk() {
    setShowConfirm(false);
    if (!assessment?.assessment_id) return;
    setGenerating(true);
    setError('');
    try {
      await completeVerifierAssessment(assessment.assessment_id);
      setReportGenerated(true);
      setReportReady(true);
    } catch (e) {
      setError(e.message || 'Could not complete verification.');
    } finally {
      setGenerating(false);
    }
  }

  async function handleReturnSubmit() {
    if (!assessment?.assessment_id) return;
    setReturnSubmitting(true);
    setError('');
    try {
      await returnAssessmentToExecutor(assessment.assessment_id, returnNote);
      setShowReturnModal(false);
      setReturnNote('');
      onBack();
    } catch (e) {
      setError(e.message || 'Could not return to executor.');
    } finally {
      setReturnSubmitting(false);
    }
  }

  // ── Show report preview (same data + UI as UserRiskReductionReportPage) ──
  if (reportReady) {
    return (
      <ReportPreview
        assessment={resolvedAssessment}
        snaps={snaps}
        formSchema={formSchema}
        onBack={() => setReportReady(false)}
        backLabel="← Back to Document"
        toolbarChipText="Risk Reduction Plan"
      />
    );
  }

  return (
    <main className="dashboard-main vp-main vrd-page">
      <div className="vp-shell">
        <nav className="vrd-breadcrumb-bar" aria-label="Breadcrumb">
          <button type="button" className="vrd-crumb-back" onClick={onBack}>
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
              <path d="M15 18l-6-6 6-6" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
            Home
          </button>
          <span className="vrd-crumb-sep">/</span>
          <span className="vrd-crumb-cur">Risk Assignment Document</span>
        </nav>

        <header className="vp-hero">
          <div className="vp-hero-text">
            <p className="vp-eyebrow">Verifier queue</p>
            <h1 className="vp-title">Risk Assignment Document</h1>
            <p className="vp-lede">
              {fmt(resolvedAssessment?.video_title)} · {fmt(resolvedAssessment?.location_name)}
            </p>
          </div>
          <div className="vp-hero-aside">
            {reportGenerated && (
              <span className="vrd-generated-badge">
                <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
                  <path d="M20 6L9 17l-5-5" strokeLinecap="round" strokeLinejoin="round"/>
                </svg>
                Report Generated
              </span>
            )}
            <button
              className="vrd-btn-hero-outline"
              type="button"
              onClick={() => setShowReturnModal(true)}
              disabled={loading || generating || returnSubmitting}
            >
              Return To Executor
            </button>
            <button type="button" className="vrd-btn-hero-primary" onClick={handleGenerateClick} disabled={loading || generating}>
              {generating ? (
                <>
                  <span className="vrd-mini-spin" />
                  Generating…
                </>
              ) : (
                <>
                  <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                    <path d="M12 5v14M5 12l7 7 7-7" />
                  </svg>
                  Generate Report
                </>
              )}
            </button>
          </div>
        </header>

        <div className="vrd-meta-strip">
          {[
            ['Location', resolvedAssessment?.location_name],
            ['Section / Work Area', resolvedAssessment?.department_name],
            ['Contract Details', resolvedAssessment?.contract_details ?? resolvedAssessment?.contact_details],
            ['Executor', resolvedAssessment?.executor_name || resolvedAssessment?.executor_id],
            ['Capture Date', fmtDate(resolvedAssessment?.video_capture_date)],
          ].flatMap(([label, val], i) => [
            i > 0 ? <div key={`sep-${i}-${label}`} className="vrd-meta-sep" aria-hidden /> : null,
            <div key={`${i}-${label}`} className="vrd-meta-item">
              <span className="vrd-meta-lbl">{label}</span>
              <span className="vrd-meta-val">{fmt(val)}</span>
            </div>
          ])}
        </div>

        {error && (
          <div className="vp-error vrd-err-bar">
            {error}{' '}
            <button type="button" className="vrd-retry" onClick={load}>
              Retry
            </button>
          </div>
        )}

        {/* Table */}
        <div className="vp-table-wrapper vrd-tbl-wrap">
          {loading ? (
            <div className="vp-loading vrd-loader">
              <div className="vp-spinner" />
              <span>Loading risk observations…</span>
            </div>
          ) : (
            <DynamicSnapTable
              snaps={snaps}
              formSchema={formSchema}
            />
          )}
        </div>

        {/* Footer */}
        {!loading && (
          <div className="vp-footer vrd-foot">
            <span className="vp-footer-meta vrd-foot-meta">
              {snaps.length} observation{snaps.length !== 1 ? 's' : ''} recorded
              {verificationFlowCount > 0
                ? ` · ${verificationFlowCount} prior return${verificationFlowCount !== 1 ? 's' : ''} on file`
                : ''}
            </span>
            <button type="button" className="vrd-btn-footer-dark" onClick={handleGenerateClick} disabled={loading || generating}>
              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden>
                <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3" />
              </svg>
              Generate &amp; Preview Report
            </button>
          </div>
        )}
      </div>

      {/* Confirm modal */}
      {showConfirm && (
        <ConfirmModal onConfirm={handleConfirmOk} onCancel={() => setShowConfirm(false)} />
      )}
      {showReturnModal && (
        <ReturnToExecutorModal
          note={returnNote}
          onNoteChange={setReturnNote}
          submitting={returnSubmitting}
          onCancel={() => {
            if (!returnSubmitting) {
              setShowReturnModal(false);
              setReturnNote('');
            }
          }}
          onConfirm={handleReturnSubmit}
        />
      )}
    </main>
  );
}
