import React, { useEffect, useState } from 'react';
import { useParams, useNavigate, Link } from 'react-router-dom';
import { format } from 'date-fns';
import { dailyStatusesApi, experimentsApi, analysesApi } from '../api/client';
import Button from '../components/ui/Button';
import Modal from '../components/ui/Modal';
import ConfirmDialog from '../components/ui/ConfirmDialog';
import DailyStatusForm from '../components/DailyStatusForm';
import Alert from '../components/ui/Alert';
import CsvAnalysis from '../components/CsvAnalysis';
import AuditLogSection from '../components/AuditLogSection';
import RunSequenceView from '../components/RunSequenceView';
import FileDropZone from '../components/FileDropZone';

function fmtDate(raw) {
  return format(new Date(String(raw).slice(0, 10) + 'T12:00:00'), 'MMMM d, yyyy');
}

function fmtDateTime(raw) {
  return format(new Date(raw), 'MMM d, yyyy · h:mm a');
}

function getFieldValue(status, field) {
  if (field.builtin) return status[field.key];
  return status.custom_fields?.[field.fieldId];
}

// ── Analysis summary card ─────────────────────────────────────────────────────

function AnalysisSummaryCard({ summary, statusId, onSummaryUpdated }) {
  const { counts = {}, total, success_rate, computed_at } = summary;
  const COLORS = {
    Success: 'bg-green-100 text-green-800',
    Failure: 'bg-red-100 text-red-800',
    Other:   'bg-gray-100 text-gray-700',
  };
  const EXTRA = ['bg-indigo-100 text-indigo-800', 'bg-yellow-100 text-yellow-800', 'bg-purple-100 text-purple-800', 'bg-pink-100 text-pink-800'];
  const catList = Object.entries(counts).sort(([, a], [, b]) => b - a);
  let extraIdx = 0;

  const [showForm, setShowForm] = useState(false);

  return (
    <div className="bg-white border border-gray-200 rounded-xl px-5 py-4 mb-6">
      <div className="flex items-center justify-between mb-3">
        <p className="text-xs font-semibold text-gray-500 uppercase tracking-wide">Session metrics</p>
        <div className="flex items-center gap-3">
          {computed_at && <p className="text-[10px] text-gray-400">Updated {fmtDateTime(computed_at)}</p>}
          {!showForm && (
            <button
              type="button"
              onClick={() => setShowForm(true)}
              className="text-[10px] text-gray-400 hover:text-indigo-600 border border-dashed border-gray-200 hover:border-indigo-300 rounded px-2 py-0.5 transition-colors"
            >
              Edit manually
            </button>
          )}
        </div>
      </div>

      {showForm ? (
        <ManualMetricsForm
          statusId={statusId}
          existing={summary}
          onSaved={(updated) => {
            onSummaryUpdated({ ...updated, computed_at: new Date().toISOString() });
            setShowForm(false);
          }}
          onClose={() => setShowForm(false)}
        />
      ) : (
        <div className="flex flex-wrap gap-3 items-center">
          {catList.map(([cat, n]) => {
            const cls = COLORS[cat] ?? EXTRA[extraIdx++ % EXTRA.length];
            return (
              <div key={cat} className={`flex flex-col items-center px-3 py-2 rounded-lg ${cls}`}>
                <span className="text-xs font-medium">{cat}</span>
                <span className="text-xl font-bold leading-tight">{n}</span>
              </div>
            );
          })}
          <div className="flex flex-col items-center px-3 py-2 rounded-lg bg-blue-50 text-blue-800">
            <span className="text-xs font-medium">Total</span>
            <span className="text-xl font-bold leading-tight">{total}</span>
          </div>
          {success_rate != null && (
            <div className="flex flex-col items-center px-3 py-2 rounded-lg bg-indigo-50 text-indigo-800">
              <span className="text-xs font-medium">Success rate</span>
              <span className="text-xl font-bold leading-tight">{(success_rate * 100).toFixed(1)}%</span>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

// ── Manual metrics form ───────────────────────────────────────────────────────

const DEFAULT_CATS = ['Success', 'Failure', 'Other'];

function ManualMetricsForm({ statusId, existing, onSaved, onClose }) {
  const initCounts = () => {
    const base = { ...existing?.counts };
    for (const c of DEFAULT_CATS) if (!(c in base)) base[c] = 0;
    return base;
  };

  const [counts, setCounts] = useState(initCounts);
  const [newCat, setNewCat] = useState('');
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState(null);

  const total = Object.values(counts).reduce((a, b) => a + (Number(b) || 0), 0);
  const successRate = total > 0 && counts['Success'] != null
    ? (Number(counts['Success']) || 0) / total
    : null;

  function setCount(cat, raw) {
    const v = Math.max(0, parseInt(raw, 10) || 0);
    setCounts((prev) => ({ ...prev, [cat]: v }));
  }

  function addCat() {
    const name = newCat.trim();
    if (!name || name in counts) return;
    setCounts((prev) => ({ ...prev, [name]: 0 }));
    setNewCat('');
  }

  function removeCat(cat) {
    if (DEFAULT_CATS.includes(cat)) return;
    setCounts((prev) => { const n = { ...prev }; delete n[cat]; return n; });
  }

  async function save() {
    setSaving(true);
    setError(null);
    try {
      const finalCounts = Object.fromEntries(
        Object.entries(counts).map(([k, v]) => [k, Number(v) || 0])
      );
      await dailyStatusesApi.updateAnalysisSummary(statusId, {
        counts: finalCounts,
        total,
        success_rate: successRate,
        source_analysis_id: null,
      });
      onSaved({ counts: finalCounts, total, success_rate: successRate });
    } catch (err) {
      setError(err.message ?? 'Failed to save');
    } finally {
      setSaving(false);
    }
  }

  return (
    <div className="bg-white border border-gray-200 rounded-xl px-5 py-4 mb-6">
      <p className="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-3">Set metrics manually</p>
      <div className="flex flex-wrap gap-3 items-end mb-3">
        {Object.entries(counts).map(([cat, val]) => (
          <div key={cat} className="flex flex-col items-center gap-1">
            <span className="text-xs text-gray-500">{cat}</span>
            <input
              type="number" min={0} value={val}
              onChange={(e) => setCount(cat, e.target.value)}
              className="w-20 text-center border border-gray-300 rounded px-2 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-400"
            />
            {!DEFAULT_CATS.includes(cat) && (
              <button type="button" onClick={() => removeCat(cat)}
                className="text-[10px] text-red-400 hover:text-red-600">remove</button>
            )}
          </div>
        ))}

        {/* Add custom category inline */}
        <div className="flex flex-col items-center gap-1">
          <span className="text-xs text-gray-400">+ category</span>
          <div className="flex gap-1">
            <input value={newCat} onChange={(e) => setNewCat(e.target.value)}
              onKeyDown={(e) => { if (e.key === 'Enter') addCat(); }}
              placeholder="Name…"
              className="w-24 border border-dashed border-gray-300 rounded px-2 py-1 text-xs focus:outline-none focus:ring-1 focus:ring-indigo-400" />
            <button type="button" onClick={addCat}
              className="text-xs text-indigo-500 hover:text-indigo-700 px-1">Add</button>
          </div>
        </div>
      </div>

      <div className="flex items-center gap-4 text-xs text-gray-500 mb-3">
        <span>Total: <strong className="text-gray-800">{total}</strong></span>
        {successRate != null && (
          <span>Success rate: <strong className="text-gray-800">{(successRate * 100).toFixed(1)}%</strong></span>
        )}
      </div>

      {error && <p className="text-xs text-red-500 mb-2">{error}</p>}
      <div className="flex gap-2">
        <button type="button" onClick={save} disabled={saving}
          className="px-3 py-1.5 rounded-lg text-sm font-medium bg-indigo-600 text-white hover:bg-indigo-700 disabled:opacity-50 transition-colors">
          {saving ? 'Saving…' : 'Save'}
        </button>
        <button type="button" onClick={onClose}
          className="px-3 py-1.5 rounded-lg text-sm text-gray-500 hover:text-gray-700 border border-gray-200 transition-colors">
          Cancel
        </button>
      </div>
    </div>
  );
}

// ── Past analysis row (expandable) ────────────────────────────────────────────

function AnalysisRow({ analysis, onDelete }) {
  const [expanded, setExpanded] = useState(false);
  const [full, setFull] = useState(null);
  const [loadingFull, setLoadingFull] = useState(false);
  const [confirmDelete, setConfirmDelete] = useState(false);
  const [deleting, setDeleting] = useState(false);

  async function expand() {
    if (expanded) { setExpanded(false); return; }
    setExpanded(true);
    if (full) return;
    setLoadingFull(true);
    try {
      const data = await analysesApi.get(analysis.id);
      setFull(data);
    } finally {
      setLoadingFull(false);
    }
  }

  async function handleDelete() {
    setDeleting(true);
    try {
      await analysesApi.delete(analysis.id);
      onDelete(analysis.id);
    } finally {
      setDeleting(false);
    }
  }

  const counts = analysis.category_counts ?? {};
  const summary = Object.entries(counts)
    .sort(([, a], [, b]) => b.total - a.total)
    .map(([cat, d]) => `${cat}: ${d.total}`)
    .join(' · ');

  return (
    <div className="border border-gray-200 rounded-lg overflow-hidden">
      <div
        className="flex items-center justify-between px-4 py-3 cursor-pointer hover:bg-gray-50 transition-colors"
        onClick={expand}
      >
        <div className="flex items-center gap-3 min-w-0">
          <span className="text-gray-400 text-xs">{expanded ? '▾' : '▸'}</span>
          <div className="min-w-0">
            <p className="text-sm font-medium text-gray-800 truncate">
              {analysis.file_name ?? 'Unnamed file'}
            </p>
            <p className="text-xs text-gray-400">
              {fmtDateTime(analysis.created_at)}
              {' · '}
              <span className="font-mono">{analysis.note_col}</span>
              {' · '}
              {analysis.total_note_rows} note rows
            </p>
          </div>
        </div>
        <div className="flex items-center gap-3 ml-4 shrink-0">
          <span className="text-xs text-gray-500 hidden sm:block">{summary}</span>
          <button type="button" onClick={(e) => { e.stopPropagation(); setConfirmDelete(true); }}
            className="text-xs text-red-400 hover:text-red-600 transition-colors">Delete</button>
        </div>
      </div>

      {expanded && (
        <div className="border-t border-gray-100 px-4 py-4 bg-gray-50/40">
          {loadingFull && <p className="text-sm text-gray-400">Loading…</p>}
          {full && <AnalysisResultsView analysis={full} />}
        </div>
      )}

      <ConfirmDialog
        isOpen={confirmDelete}
        onClose={() => setConfirmDelete(false)}
        onConfirm={handleDelete}
        loading={deleting}
        title="Delete Analysis"
        message="Remove this analysis record? The raw CSV is not affected."
      />
    </div>
  );
}

// ── Analysis results display (reused by both live and past) ───────────────────

export function AnalysisResultsView({ analysis }) {
  const { timestamp_col, note_col, total_note_rows,
          category_counts, consecutive_stats, runs } = analysis;
  const customCategories = [];

  function colorsFor(cat) {
    const COLORS = {
      Success: { bg: 'bg-green-100', text: 'text-green-800', dot: 'bg-green-500', border: 'border-green-300' },
      Failure: { bg: 'bg-red-100',   text: 'text-red-800',   dot: 'bg-red-500',   border: 'border-red-300'   },
      Other:   { bg: 'bg-gray-100',  text: 'text-gray-700',  dot: 'bg-gray-400',  border: 'border-gray-300'  },
    };
    const EXTRA = [
      { bg: 'bg-indigo-100', text: 'text-indigo-800', dot: 'bg-indigo-500', border: 'border-indigo-300' },
      { bg: 'bg-yellow-100', text: 'text-yellow-800', dot: 'bg-yellow-500', border: 'border-yellow-300' },
      { bg: 'bg-purple-100', text: 'text-purple-800', dot: 'bg-purple-500', border: 'border-purple-300' },
    ];
    if (COLORS[cat]) return COLORS[cat];
    const idx = customCategories.indexOf(cat) % EXTRA.length;
    return EXTRA[Math.max(0, idx)];
  }

  return (
    <div className="space-y-5 text-sm">
      <p className="text-xs text-gray-400">
        {total_note_rows} note rows · timestamp: <span className="font-mono">{timestamp_col}</span>
        {' '}/ note: <span className="font-mono">{note_col}</span>
      </p>

      {/* Category counts */}
      <div>
        <p className="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-1.5">Category Counts</p>
        <table className="w-full border-collapse text-sm">
          <thead>
            <tr className="bg-white border-b border-gray-200">
              <th className="text-left px-3 py-1.5 text-xs font-semibold text-gray-500">Category</th>
              <th className="text-left px-3 py-1.5 text-xs font-semibold text-gray-500">Breakdown</th>
              <th className="text-right px-3 py-1.5 text-xs font-semibold text-gray-500">Total</th>
            </tr>
          </thead>
          <tbody>
            {Object.entries(category_counts ?? {})
              .sort(([, a], [, b]) => b.total - a.total)
              .map(([cat, data]) => {
                const c = colorsFor(cat);
                const bd = Object.entries(data.byNote ?? {})
                  .sort(([, a], [, b]) => b - a)
                  .map(([n, cnt]) => `${n}: ${cnt}`).join(' · ');
                return (
                  <tr key={cat} className="border-b border-gray-100">
                    <td className="px-3 py-1.5">
                      <span className={`inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-semibold ${c.bg} ${c.text}`}>
                        <span className={`w-1.5 h-1.5 rounded-full ${c.dot}`} />
                        {cat}
                      </span>
                    </td>
                    <td className="px-3 py-1.5 text-gray-500 font-mono text-xs">{bd}</td>
                    <td className="px-3 py-1.5 text-right font-semibold text-gray-800">{data.total}</td>
                  </tr>
                );
              })}
          </tbody>
        </table>
      </div>

      {/* Consecutive stats */}
      {Object.keys(consecutive_stats ?? {}).length > 0 && (
        <div>
          <p className="text-xs font-semibold text-gray-500 uppercase tracking-wide mb-1.5">Consecutive Runs</p>
          <table className="w-full border-collapse text-sm">
            <thead>
              <tr className="bg-white border-b border-gray-200">
                <th className="text-left px-3 py-1.5 text-xs font-semibold text-gray-500">Category</th>
                <th className="text-right px-3 py-1.5 text-xs font-semibold text-gray-500">Runs</th>
                <th className="text-right px-3 py-1.5 text-xs font-semibold text-gray-500">Max</th>
                <th className="text-right px-3 py-1.5 text-xs font-semibold text-gray-500">Avg</th>
                <th className="text-left px-3 py-1.5 text-xs font-semibold text-gray-500">Lengths</th>
              </tr>
            </thead>
            <tbody>
              {Object.entries(consecutive_stats).map(([cat, s]) => {
                const c = colorsFor(cat);
                const summary = Object.entries(
                  s.runLengths.reduce((acc, l) => { acc[l] = (acc[l] || 0) + 1; return acc; }, {})
                ).sort(([a], [b]) => Number(a) - Number(b))
                  .map(([l, cnt]) => `${l}×${cnt}`).join(', ');
                return (
                  <tr key={cat} className="border-b border-gray-100">
                    <td className="px-3 py-1.5">
                      <span className={`inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-semibold ${c.bg} ${c.text}`}>
                        <span className={`w-1.5 h-1.5 rounded-full ${c.dot}`} />
                        {cat}
                      </span>
                    </td>
                    <td className="px-3 py-1.5 text-right text-gray-700">{s.totalRuns}</td>
                    <td className="px-3 py-1.5 text-right text-gray-700">{s.maxRun}</td>
                    <td className="px-3 py-1.5 text-right text-gray-700">{s.avgRun.toFixed(2)}</td>
                    <td className="px-3 py-1.5 text-gray-500 font-mono text-xs">{summary}</td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>
      )}

      <RunSequenceView runs={runs ?? []} sequence={analysis.sequence ?? []} sessionEndTs={analysis.session_end_ts ?? null} />
    </div>
  );
}

// ── Past analyses inline viewer ───────────────────────────────────────────────

function PastAnalysesViewer({ analyses, onDelete, onNewAnalysis }) {
  const [selectedId, setSelectedId]   = useState(() => analyses[0]?.id ?? null);
  const [cache, setCache]             = useState({});
  const [loadingId, setLoadingId]     = useState(null);
  const [confirmDelete, setConfirmDelete] = useState(null);
  const [deleting, setDeleting]       = useState(false);

  // Load full data whenever the selected id changes
  useEffect(() => {
    if (!selectedId || cache[selectedId]) return;
    setLoadingId(selectedId);
    analysesApi.get(selectedId)
      .then((data) => setCache((prev) => ({ ...prev, [selectedId]: data })))
      .catch(() => {})
      .finally(() => setLoadingId(null));
  }, [selectedId]);

  // If the list changes (new analysis added / deleted), keep selection valid
  useEffect(() => {
    if (!analyses.length) { setSelectedId(null); return; }
    if (!analyses.find((a) => a.id === selectedId)) setSelectedId(analyses[0].id);
  }, [analyses]);

  async function handleDelete(id) {
    setDeleting(true);
    try {
      await analysesApi.delete(id);
      setCache((prev) => { const n = { ...prev }; delete n[id]; return n; });
      onDelete(id);
    } finally {
      setDeleting(false);
      setConfirmDelete(null);
    }
  }

  if (!analyses.length) return null;

  const selected  = analyses.find((a) => a.id === selectedId) ?? null;
  const fullData  = selectedId ? (cache[selectedId] ?? null) : null;
  const isLoading = loadingId === selectedId;

  const categorySummary = (a) =>
    Object.entries(a.category_counts ?? {})
      .sort(([, x], [, y]) => y.total - x.total)
      .map(([cat, d]) => `${cat}: ${d.total}`)
      .join(' · ');

  return (
    <div className="mt-8 border-t border-gray-200 pt-6">
      {/* Header */}
      <div className="flex items-center justify-between mb-4">
        <h2 className="text-sm font-semibold text-gray-700 uppercase tracking-wide">
          Past Analyses ({analyses.length})
        </h2>
      </div>

      {/* Tab selector — scrollable if many */}
      {analyses.length > 1 && (
        <div className="flex gap-1.5 overflow-x-auto pb-2 mb-4 scrollbar-thin">
          {analyses.map((a) => {
            const active = a.id === selectedId;
            return (
              <button
                key={a.id}
                type="button"
                onClick={() => setSelectedId(a.id)}
                className={`shrink-0 flex flex-col items-start px-3 py-2 rounded-lg border text-left transition-colors
                  ${active
                    ? 'bg-indigo-50 border-indigo-300 text-indigo-800'
                    : 'bg-white border-gray-200 text-gray-600 hover:border-gray-300 hover:bg-gray-50'}`}
              >
                <span className="text-xs font-medium truncate max-w-[160px]">
                  {a.file_name ?? 'Unnamed file'}
                </span>
                <span className={`text-[10px] mt-0.5 ${active ? 'text-indigo-500' : 'text-gray-400'}`}>
                  {fmtDateTime(a.created_at)}
                </span>
              </button>
            );
          })}
        </div>
      )}

      {/* Selected analysis panel */}
      {selected && (
        <div className="bg-white border border-gray-200 rounded-xl overflow-hidden">
          {/* Panel header */}
          <div className="flex items-start justify-between px-4 py-3 border-b border-gray-100 bg-gray-50/50">
            <div>
              <p className="text-sm font-medium text-gray-800">
                {selected.file_name ?? 'Unnamed file'}
              </p>
              <p className="text-xs text-gray-400 mt-0.5">
                {fmtDateTime(selected.created_at)}
                {' · '}
                <span className="font-mono">{selected.note_col}</span>
                {' · '}
                {selected.total_note_rows} note rows
                {categorySummary(selected) && (
                  <span className="ml-2 text-gray-500">{categorySummary(selected)}</span>
                )}
              </p>
            </div>
            <button
              type="button"
              onClick={() => setConfirmDelete(selected.id)}
              className="text-xs text-red-400 hover:text-red-600 transition-colors shrink-0 ml-4 mt-0.5"
            >
              Delete
            </button>
          </div>

          {/* Panel body */}
          <div className="px-4 py-4">
            {isLoading && (
              <p className="text-sm text-gray-400 py-4 text-center">Loading…</p>
            )}
            {!isLoading && fullData && <AnalysisResultsView analysis={fullData} />}
          </div>
        </div>
      )}

      <ConfirmDialog
        isOpen={!!confirmDelete}
        onClose={() => setConfirmDelete(null)}
        onConfirm={() => handleDelete(confirmDelete)}
        loading={deleting}
        title="Delete Analysis"
        message="Remove this analysis record? The raw CSV is not affected."
      />
    </div>
  );
}

// ── Page ──────────────────────────────────────────────────────────────────────

export default function DailyStatusDetail() {
  const { id } = useParams();
  const navigate = useNavigate();

  const [status, setStatus] = useState(null);
  const [template, setTemplate] = useState([]);
  const [allStatuses, setAllStatuses] = useState([]);
  const [analyses, setAnalyses] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  const [showEdit, setShowEdit] = useState(false);
  const [showDelete, setShowDelete] = useState(false);
  const [deleteLoading, setDeleteLoading] = useState(false);
  const [showManualForm, setShowManualForm] = useState(false);

  async function load(statusId = id) {
    setLoading(true);
    setError(null);
    try {
      const s = await dailyStatusesApi.get(statusId);
      const [tmpl, siblings, pastAnalyses] = await Promise.all([
        experimentsApi.getTemplate(s.animal.experiment_id),
        dailyStatusesApi.list(s.animal_id),
        analysesApi.listForStatus(statusId),
      ]);
      setStatus(s);
      setTemplate(tmpl);
      setAllStatuses(siblings);
      setAnalyses(pastAnalyses);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  }

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

  async function handleDelete() {
    setDeleteLoading(true);
    try {
      await dailyStatusesApi.delete(status.id);
      navigate(`/animals/${status.animal_id}`, { replace: true });
    } catch (err) {
      setError(err.message);
      setShowDelete(false);
    } finally {
      setDeleteLoading(false);
    }
  }

  if (loading) return <div className="max-w-3xl mx-auto px-4 py-8 text-gray-400">Loading…</div>;
  if (error) return (
    <div className="max-w-3xl mx-auto px-4 py-8">
      <Alert type="error" message={error} />
      <Button variant="secondary" className="mt-4" onClick={() => navigate(-1)}>← Back</Button>
    </div>
  );

  const animal = status.animal;
  const activeFields = template.filter((f) => f.active);

  const currentIdx = allStatuses.findIndex((s) => s.id === status.id);
  const prevStatus = currentIdx > 0 ? allStatuses[currentIdx - 1] : null;
  const nextStatus = currentIdx < allStatuses.length - 1 ? allStatuses[currentIdx + 1] : null;

  return (
    <div className="max-w-3xl mx-auto px-4 py-8">
      {/* Breadcrumb */}
      <nav className="text-sm text-gray-500 mb-4">
        <Link to="/" className="hover:text-blue-600">Experiments</Link>
        <span className="mx-2">/</span>
        <Link to={`/experiments/${animal.experiment_id}`} className="hover:text-blue-600">Experiment</Link>
        <span className="mx-2">/</span>
        <Link to={`/animals/${animal.id}`} className="hover:text-blue-600">{animal.animal_name}</Link>
        <span className="mx-2">/</span>
        <span className="text-gray-900 font-medium">{fmtDate(status.date)}</span>
      </nav>

      {/* Header */}
      <div className="flex items-start justify-between mb-6">
        <div>
          <h1 className="text-2xl font-bold text-gray-900">{fmtDate(status.date)}</h1>
          <p className="text-sm text-gray-500 mt-0.5">
            {animal.animal_name}
            {animal.animal_id_string && <> · <span className="font-mono">{animal.animal_id_string}</span></>}
          </p>
        </div>
        <Button variant="secondary" onClick={() => setShowEdit(true)}>Edit entry</Button>
      </div>

      {error && <Alert type="error" message={error} onDismiss={() => setError(null)} />}

      {/* Field values */}
      <div className="bg-white border border-gray-200 rounded-xl p-6 mb-6">
        {activeFields.length === 0 ? (
          <p className="text-sm text-gray-400 italic">No template fields configured.</p>
        ) : (
          <dl className="grid grid-cols-1 sm:grid-cols-2 gap-x-8 gap-y-4">
            {activeFields.map((f) => {
              const value = getFieldValue(status, f);
              const label = f.unit ? `${f.label} (${f.unit})` : f.label;
              return (
                <div key={f.fieldId} className={f.type === 'textarea' ? 'sm:col-span-2' : ''}>
                  <dt className="text-xs font-semibold text-gray-400 uppercase tracking-wide mb-0.5">{label}</dt>
                  <dd className="text-gray-800 whitespace-pre-wrap break-words">
                    {value ?? <span className="text-gray-300 italic">—</span>}
                  </dd>
                </div>
              );
            })}
          </dl>
        )}
      </div>

      {/* Analysis summary (pinned metrics) */}
      {status.analysis_summary ? (
        <AnalysisSummaryCard
          summary={status.analysis_summary}
          statusId={status.id}
          onSummaryUpdated={(summary) => setStatus((prev) => ({ ...prev, analysis_summary: summary }))}
        />
      ) : (
        <div className="mb-4">
          <button
            type="button"
            onClick={() => setShowManualForm(true)}
            className="text-xs text-gray-400 hover:text-indigo-600 border border-dashed border-gray-200 hover:border-indigo-300 rounded-lg px-3 py-1.5 transition-colors"
          >
            Set metrics manually
          </button>
        </div>
      )}
      {showManualForm && !status.analysis_summary && (
        <ManualMetricsForm
          statusId={status.id}
          existing={null}
          onSaved={(summary) => {
            setStatus((prev) => ({ ...prev, analysis_summary: { ...summary, computed_at: new Date().toISOString() } }));
            setShowManualForm(false);
          }}
          onClose={() => setShowManualForm(false)}
        />
      )}

      {/* Past analyses — inline viewer */}
      <PastAnalysesViewer
        analyses={analyses}
        onDelete={(deletedId) => setAnalyses((prev) => prev.filter((x) => x.id !== deletedId))}
      />

      {/* CSV Analysis — after past analyses */}
      <CsvAnalysis
        dailyStatusId={status.id}
        animal={status.animal}
        onSaved={(saved) => setAnalyses((prev) => [saved, ...prev])}
        onSummaryPushed={(summary) => setStatus((prev) => ({ ...prev, analysis_summary: { ...summary, computed_at: new Date().toISOString() } }))}
      />

      {/* Session file registry */}
      <FileDropZone
        rows={[{ animal, status }]}
        date={String(status.date).slice(0, 10)}
      />

      {/* Full modification history for this entry */}
      <AuditLogSection tableName="daily_statuses" recordId={status.id} />

      {/* Prev / Next navigation */}
      <div className="flex justify-between items-center mt-8 mb-6">
        <div>
          {prevStatus && (
            <button type="button" onClick={() => navigate(`/daily-statuses/${prevStatus.id}`)}
              className="text-sm text-blue-600 hover:text-blue-800 hover:underline">
              ← {fmtDate(prevStatus.date)}
            </button>
          )}
        </div>
        <Link to={`/animals/${animal.id}`} className="text-sm text-gray-500 hover:text-gray-800">
          All entries
        </Link>
        <div>
          {nextStatus && (
            <button type="button" onClick={() => navigate(`/daily-statuses/${nextStatus.id}`)}
              className="text-sm text-blue-600 hover:text-blue-800 hover:underline">
              {fmtDate(nextStatus.date)} →
            </button>
          )}
        </div>
      </div>

      {/* Edit modal */}
      <Modal isOpen={showEdit} onClose={() => setShowEdit(false)} title="Edit Daily Status" size="full">
        <DailyStatusForm
          existing={status}
          animalId={animal.id}
          experimentId={animal.experiment_id}
          template={template}
          onTemplateUpdate={setTemplate}
          onSuccess={(updated) => { setStatus({ ...updated, animal }); setShowEdit(false); }}
          onCancel={() => setShowEdit(false)}
          onRequestDelete={() => { setShowEdit(false); setShowDelete(true); }}
        />
      </Modal>

      <ConfirmDialog
        isOpen={showDelete}
        onClose={() => setShowDelete(false)}
        onConfirm={handleDelete}
        loading={deleteLoading}
        title="Delete Daily Status"
        message={`Delete the entry for ${fmtDate(status.date)}? This cannot be undone.`}
        confirmWord="delete"
      />
    </div>
  );
}
