// Reusable premium components for the rates page.
const { useState, useEffect, useMemo, useRef } = React;

// ───────── SVG Icons ─────────
const SvgSearch = () => (
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
);

const SvgBell = () => (
  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path><path d="M13.73 21a2 2 0 0 1-3.46 0"></path></svg>
);

const SvgHelp = () => (
  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>
);

const SvgFile = () => (
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline></svg>
);

const SvgTrendDown = () => (
  <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{ color: 'var(--color-error)' }}><polyline points="23 18 13.5 8.5 8.5 13.5 1 6"></polyline><polyline points="17 18 23 18 23 12"></polyline></svg>
);

const SvgChevronRight = () => (
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="9 18 15 12 9 6"></polyline></svg>
);

const SvgLandscape = () => (
  <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z" fill="#79B93C" />
  </svg>
);

// ───────── HEADER ─────────
function Header({ onSignOut, currentUser, mode = 'workspace', onHome }) {
  const initials = currentUser && currentUser.name
    ? currentUser.name.split(' ').map(p => p[0]).join('').slice(0, 2).toUpperCase()
    : currentUser && currentUser.email
      ? currentUser.email.slice(0, 2).toUpperCase()
      : 'LO';
  const isLauncher = mode === 'launcher';
  return (
    <header className="nav">
      <div className="nav-inner">
        <div className="logo-container">
          <div className="logo-icon-circle">
            <SvgLandscape />
          </div>
          <div className="logo-text">
            <span className="logo-text-title">Tri Valley</span>
            <span className="logo-text-subtitle">Home Loans</span>
          </div>
          <div className="divider-vertical"></div>
          <div className="breadcrumbs">
            <button type="button" className="nav-home-link" onClick={onHome || undefined}>Home</button>
            {!isLauncher && (
              <>
                <SvgChevronRight />
                <span>Pricing</span>
              </>
            )}
          </div>
        </div>

        <div className="nav-right-icons">
          <div className="nav-search-bar">
            <span className="nav-search-icon-left"><SvgSearch /></span>
            <input type="text" className="nav-search-input" placeholder="Search....." />
          </div>
          <button className="nav-icon-btn" title="Search">
            <SvgSearch />
          </button>
          <button className="nav-icon-btn" title="Notifications">
            <SvgBell />
            <span className="nav-badge"></span>
          </button>
          <button className="nav-icon-btn" title="Help">
            <SvgHelp />
          </button>
          <div className="nav-profile-badge" onClick={onSignOut} title={`Signed in as ${currentUser ? currentUser.email : ''} — Click to Sign Out`}>
            {initials}
          </div>
        </div>
      </div>
    </header>
  );
}

function AppTileIcon({ kind }) {
  if (kind === 'pricing') {
    return (
      <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <path d="M7 3h10l4 4v14H3V7z"></path>
        <path d="M12 8v8"></path>
        <path d="M9.5 10.5c0-1.1 1.1-2 2.5-2s2.5.9 2.5 2-1.1 2-2.5 2-2.5.9-2.5 2 1.1 2 2.5 2 2.5-.9 2.5-2"></path>
      </svg>
    );
  }

  if (kind === 'borrower') {
    return (
      <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <path d="M3 11l9-7 9 7"></path>
        <path d="M5 10v10h14V10"></path>
        <path d="M9 20v-6h6v6"></path>
      </svg>
    );
  }

  if (kind === 'ops') {
    return (
      <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <rect x="4" y="4" width="16" height="16" rx="3"></rect>
        <path d="M8 8h8"></path>
        <path d="M8 12h5"></path>
        <path d="M8 16h7"></path>
      </svg>
    );
  }

  return (
    <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <rect x="4" y="4" width="16" height="16" rx="3"></rect>
      <path d="M8 8h8"></path>
      <path d="M8 12h8"></path>
      <path d="M8 16h6"></path>
    </svg>
  );
}

function AppLauncherScreen({ onLaunchApp }) {
  const tiles = [
    { id: 'pricing', label: 'Pricing App', icon: 'pricing', onClick: onLaunchApp },
  ];

  const MAX_COLUMNS = 4;
  const columnCount = Math.max(1, Math.min(MAX_COLUMNS, tiles.length));
  const mobileColumnCount = Math.max(1, Math.min(2, tiles.length));

  return (
    <main className="launcher-shell">
      <section className="launcher-stage" aria-label="Application launcher">
        <div
          className="launcher-grid"
          style={{
            '--launcher-columns': columnCount,
            '--launcher-columns-mobile': mobileColumnCount,
          }}
        >
          {tiles.map((tile) => (
            <button
              key={tile.id}
              type="button"
              className="launcher-card launcher-card--active launcher-card--single"
              onClick={tile.onClick}
              aria-label={`Open ${tile.label}`}
            >
              <span className="launcher-icon-frame" aria-hidden="true">
                <span className={`launcher-icon launcher-icon--${tile.icon}`}>
                  <AppTileIcon kind={tile.icon} />
                </span>
              </span>
              <span className="launcher-card-label">{tile.label}</span>
            </button>
          ))}
        </div>
      </section>
    </main>
  );
}

// ───────── Sign-in Overlay (Google OAuth) ─────────
function SignInOverlay({ onSignIn }) {
  // Check for an auth_error query param passed back from the OAuth callback
  const authError = new URLSearchParams(window.location.search).get('auth_error');

  return (
    <div style={{
      minHeight: "100vh",
      display: "grid",
      placeItems: "center",
      backgroundColor: "var(--bg-page)",
      color: "var(--text-main)",
      fontFamily: "'Hanken Grotesk', sans-serif"
    }}>
      <div style={{
        backgroundColor: "var(--bg-card)",
        border: "1px solid var(--border-light)",
        borderRadius: 16,
        padding: "40px 32px",
        width: 380,
        boxShadow: "var(--shadow-lg)",
        textAlign: "center",
      }}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "center", gap: 12, marginBottom: 28 }}>
          <div className="logo-icon-circle">
            <SvgLandscape />
          </div>
          <div className="logo-text" style={{ textAlign: "left" }}>
            <span className="logo-text-title">Tri Valley</span>
            <span className="logo-text-subtitle">Home Loans</span>
          </div>
        </div>
        <h1 style={{ fontSize: 24, fontWeight: 800, margin: "0 0 8px 0", letterSpacing: "-0.02em" }}>Sign In</h1>
        <p style={{ fontSize: 13, color: "var(--text-light)", margin: "0 0 28px 0", lineHeight: 1.5 }}>
          Internal pricing portal — staff access only.
        </p>
        {authError && (
          <div style={{ color: "var(--color-error)", fontSize: 13, marginBottom: 16, fontWeight: 600 }}>
            Sign in failed: {authError}
          </div>
        )}
        <button
          onClick={onSignIn}
          style={{
            width: "100%",
            display: "flex",
            alignItems: "center",
            justifyContent: "center",
            gap: 10,
            padding: "11px 20px",
            backgroundColor: "#fff",
            border: "1px solid #dadce0",
            borderRadius: 8,
            fontSize: 15,
            fontWeight: 600,
            color: "#3c4043",
            cursor: "pointer",
            boxShadow: "0 1px 3px rgba(0,0,0,0.08)",
            fontFamily: "inherit",
          }}
        >
          <svg width="18" height="18" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
            <path d="M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.874 2.684-6.615z" fill="#4285F4" />
            <path d="M9 18c2.43 0 4.467-.806 5.956-2.18l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332A8.997 8.997 0 0 0 9 18z" fill="#34A853" />
            <path d="M3.964 10.71A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.957A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.957 4.042l3.007-2.332z" fill="#FBBC05" />
            <path d="M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0A8.997 8.997 0 0 0 .957 4.958L3.964 6.29C4.672 4.163 6.656 3.58 9 3.58z" fill="#EA4335" />
          </svg>
          Continue with Google
        </button>
      </div>
    </div>
  );
}

// ───────── Upload Zone (T10) ─────────
function UploadZone() {
  const [dragOver, setDragOver] = useState(false);
  const [file, setFile] = useState(null);
  const [status, setStatus] = useState('idle'); // idle | uploading | success | error
  const [errorMsg, setErrorMsg] = useState('');
  const inputRef = useRef(null);

  const processFile = async (f) => {
    const ALLOWED = new Set(['application/pdf', 'image/jpeg', 'image/png', 'image/jpg']);
    if (!ALLOWED.has(f.type)) {
      setStatus('error'); setErrorMsg('Only PDF, JPG, or PNG files are allowed.'); return;
    }
    if (f.size > 10 * 1024 * 1024) {
      setStatus('error'); setErrorMsg('File must be under 10 MB.'); return;
    }
    setFile(f); setStatus('uploading'); setErrorMsg('');
    const form = new FormData();
    form.append('file', f);
    try {
      const res = await fetch('/api/upload', { method: 'POST', body: form });
      const json = await res.json();
      if (!res.ok) throw new Error(json?.error?.message || `HTTP ${res.status}`);
      setStatus('success');
    } catch (err) {
      setStatus('error'); setErrorMsg(err.message);
    }
  };

  const reset = () => { setFile(null); setStatus('idle'); setErrorMsg(''); };
  const fmtSize = (b) => b < 1048576 ? `${(b / 1024).toFixed(1)} KB` : `${(b / 1048576).toFixed(1)} MB`;

  return (
    <div
      className={`upload-zone${dragOver ? ' upload-zone-over' : ''}${status === 'success' ? ' upload-zone-success' : ''}`}
      onDragOver={(e) => { e.preventDefault(); setDragOver(true); }}
      onDragLeave={() => setDragOver(false)}
      onDrop={(e) => { e.preventDefault(); setDragOver(false); const f = e.dataTransfer.files[0]; if (f) processFile(f); }}
      onClick={() => status === 'idle' && inputRef.current?.click()}
    >
      <input
        ref={inputRef}
        type="file"
        accept=".pdf,.jpg,.jpeg,.png"
        style={{ display: 'none' }}
        onChange={(e) => { const f = e.target.files[0]; if (f) processFile(f); e.target.value = ''; }}
      />
      {status === 'idle' && (
        <>
          <div className="upload-zone-icon">
            <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" style={{ color: 'var(--primary)' }}>
              <polyline points="16 16 12 12 8 16" />
              <line x1="12" y1="12" x2="12" y2="21" />
              <path d="M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3" />
            </svg>
          </div>
          <div className="upload-zone-primary">Mortgage Statement</div>
          <div className="upload-zone-secondary">Drag &amp; drop or tap to browse PDF/JPG</div>
          <button className="btn-primary upload-zone-select" onClick={(e) => { e.stopPropagation(); inputRef.current?.click(); }}>Select File</button>
        </>
      )}
      {status === 'uploading' && (
        <>
          <div className="upload-zone-icon">⏳</div>
          <div className="upload-zone-primary">Uploading {file?.name}…</div>
          <div className="upload-zone-secondary">{file && fmtSize(file.size)}</div>
        </>
      )}
      {status === 'success' && (
        <>
          <div className="upload-zone-icon">✅</div>
          <div className="upload-zone-primary">{file?.name}</div>
          <div className="upload-zone-secondary">{file && fmtSize(file.size)} · uploaded successfully</div>
          <button className="upload-zone-reset" onClick={(e) => { e.stopPropagation(); reset(); }}>Upload another</button>
        </>
      )}
      {status === 'error' && (
        <>
          <div className="upload-zone-icon">❌</div>
          <div className="upload-zone-primary">Upload failed</div>
          <div className="upload-zone-secondary" style={{ color: 'var(--color-error)' }}>{errorMsg}</div>
          <button className="upload-zone-reset" onClick={(e) => { e.stopPropagation(); reset(); }}>Try again</button>
        </>
      )}
    </div>
  );
}

// ───────── Tooltip Icon (U1, U2) ─────────
// CSS-only tooltip — no JS, keyboard accessible, WCAG-friendly.
function TooltipIcon({ tip }) {
  return (
    <span className="tooltip-icon-wrap" tabIndex="0" role="img" aria-label={tip}>
      <svg className="tooltip-icon-svg" width="13" height="13" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
        <path d="M8 1a7 7 0 1 0 0 14A7 7 0 0 0 8 1zm0 3.2a.9.9 0 1 1 0 1.8.9.9 0 0 1 0-1.8zm-.8 3h1.6v4.6H7.2V7.2z" />
      </svg>
      <span className="tooltip-bubble" role="tooltip">{tip}</span>
    </span>
  );
}

// ───────── Empty State (U3) ─────────
// Reusable enterprise-grade empty state — no emojis, uses design tokens.
function EmptyState({ title, body }) {
  return (
    <div className="empty-state">
      <svg className="empty-state-icon" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        <rect x="3" y="3" width="18" height="18" rx="3" />
        <path d="M9 9h6M9 12h6M9 15h4" />
      </svg>
      <p className="empty-state-title">{title}</p>
      {body && <p className="empty-state-body">{body}</p>}
    </div>
  );
}

// ───────── Scenario Form (Left Sidebar) ─────────
function ScenarioForm({ scenario, setScenario, onPrice }) {
  const [activeTab, setActiveTab] = useState("upload"); // "upload" | "manual"
  const set = (patch) => setScenario({ ...scenario, ...patch });
  const dpPct = ((scenario.downPayment / scenario.homePrice) * 100) || 0;

  return (
    <div className="sidebar">
      <div>
        <h2>{activeTab === 'upload' ? 'Secure Documents' : 'Submit Loan Details'}</h2>
        <p className="subtitle">{activeTab === 'upload' ? 'Upload your mortgage statement to begin extraction.' : 'Provide your loan estimate to get the best competitive rates instantly.'}</p>
      </div>

      <div className="toggle-tabs">
        <button
          className={`toggle-tab-btn ${activeTab === "upload" ? "active" : ""}`}
          onClick={() => setActiveTab("upload")}
        >
          Upload Document
        </button>
        <button
          className={`toggle-tab-btn ${activeTab === "manual" ? "active" : ""}`}
          onClick={() => setActiveTab("manual")}
        >
          Manual Entry
        </button>
      </div>

      {activeTab === "upload" ? (
        <window.UploadZone />
      ) : (
        <div className="sidebar-form">
          <div className="form-field">
            <label>Loan Purpose *</label>
            <select className="form-select" value={scenario.loanPurpose} onChange={(e) => set({ loanPurpose: e.target.value })}>
              <option value="purchase">Purchase</option>
              <option value="refi">Refinance</option>
              <option value="cashout">Cash-Out</option>
            </select>
          </div>

          <div className="form-field">
            <label>Purchase Price *</label>
            <div className="form-input-group">
              <input
                type="text"
                className="form-input tabular"
                value={scenario.homePrice.toLocaleString()}
                onChange={(e) => {
                  const val = parseInt(e.target.value.replace(/[^0-9]/g, "")) || 0;
                  set({ homePrice: val, downPayment: Math.min(scenario.downPayment, val) });
                }}
              />
            </div>
          </div>

          <div className="form-row">
            <div className="form-field">
              <label>Down Payment *</label>
              <div className="form-input-group-suffix">
                <input
                  type="number"
                  className="form-input tabular"
                  value={Math.round(dpPct)}
                  onChange={(e) => {
                    const pct = Math.min(100, Math.max(0, parseFloat(e.target.value) || 0));
                    set({ downPayment: Math.round(scenario.homePrice * (pct / 100)) });
                  }}
                />
              </div>
            </div>
            <div className="form-field">
              <label>Loan Amount *</label>
              <div className="form-input-group">
                <input
                  type="text"
                  className="form-input tabular"
                  value={(scenario.homePrice - scenario.downPayment).toLocaleString()}
                  disabled
                  style={{ backgroundColor: "#f1f5f9" }}
                />
              </div>
            </div>
          </div>

          <div className="form-field">
            <label>Credit Score *</label>
            <input
              type="number"
              className="form-input tabular"
              min="300"
              max="850"
              placeholder="700"
              value={scenario.credit}
              onChange={(e) => {
                const v = Math.min(850, Math.max(300, parseInt(e.target.value, 10) || 300));
                set({ credit: v });
              }}
            />
          </div>

          <div className="form-field">
            <label>Occupancy *</label>
            <select className="form-select" value={scenario.occupancy} onChange={(e) => set({ occupancy: e.target.value })}>
              <option value="primary">Primary</option>
              <option value="second">2nd Home</option>
              <option value="invest">Investment</option>
            </select>
          </div>

          <div className="form-field">
            <label>Property Type *</label>
            <select className="form-select" value={scenario.propertyType} onChange={(e) => set({ propertyType: e.target.value })}>
              <option value="sfh">Single Family</option>
              <option value="condo">Condo</option>
              <option value="townhouse">Townhouse</option>
              <option value="multi">2–4 Unit</option>
            </select>
          </div>

          <div className="form-field">
            <label>Loan Type *</label>
            <select className="form-select" value={scenario.loanType || "Conventional"} onChange={(e) => set({ loanType: e.target.value })}>
              <option value="Conventional">Conventional</option>
              <option value="FHA">FHA</option>
              <option value="VA">VA</option>
              <option value="Jumbo">Jumbo</option>
            </select>
          </div>

          <div className="form-row">
            <div className="form-field">
              <label>ZIP Code *</label>
              <input
                type="text"
                className="form-input mono"
                maxLength={5}
                value={scenario.zip}
                onChange={(e) => set({ zip: e.target.value.replace(/[^0-9]/g, "") })}
              />
            </div>
            <div className="form-field">
              <label>State *</label>
              <input
                type="text"
                className="form-input mono"
                maxLength={2}
                value={scenario.state}
                placeholder="CA"
                onChange={(e) => set({ state: e.target.value.replace(/[^A-Za-z]/g, "").toUpperCase() })}
              />
            </div>
          </div>

          <div className="form-field">
            <label>Lock Days *</label>
            <select className="form-select" value={scenario.lockDays || "15"} onChange={(e) => set({ lockDays: e.target.value })}>
              <option value="15">15 Days</option>
              <option value="30">30 Days</option>
              <option value="45">45 Days</option>
              <option value="60">60 Days</option>
            </select>
          </div>

          <div className="form-field">
            <label className="label-with-tooltip">
              Search By
              <TooltipIcon tip="Sorts pricing results by the selected metric — Rate shows lowest interest rate first, APR includes fees in the sort, Fees prioritizes lowest closing costs." />
            </label>
            <select className="form-select" value={scenario.searchBy || "Rate"} onChange={(e) => set({ searchBy: e.target.value })}>
              <option value="Rate">Rate</option>
              <option value="APR">APR</option>
              <option value="Fees">Fees</option>
            </select>
          </div>

          <div className="radio-group-container">
            <span className="radio-group-label">Military Veteran *</span>
            <div className="radio-options">
              <label className="radio-option">
                <input
                  type="radio"
                  name="military"
                  value="yes"
                  checked={scenario.military === "yes"}
                  onChange={() => set({ military: "yes" })}
                /> Yes
              </label>
              <label className="radio-option">
                <input
                  type="radio"
                  name="military"
                  value="no"
                  checked={scenario.military !== "yes"}
                  onChange={() => set({ military: "no" })}
                /> No
              </label>
            </div>
          </div>

          <button type="button" className="btn-generate" onClick={onPrice}>
            Generate Pricing
          </button>
        </div>
      )}

      <hr className="sidebar-separator" />

      <RecentSubmissions />
    </div>
  );
}

// ───────── Recent Submissions ─────────
function RecentSubmissions() {
  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch('/api/submissions/recent')
      .then((r) => r.json())
      .then((d) => { setItems(d.items || []); setLoading(false); })
      .catch(() => setLoading(false));
  }, []);

  const fmtDate = (iso) => {
    if (!iso) return '';
    return new Date(iso).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
  };

  // Map DB session state to badge CSS class and label
  const TAG = {
    active: { cls: 'pending', label: 'active' },
    compared: { cls: 'verified', label: 'compared' },
    abandoned: { cls: 'archived', label: 'archived' },
  };

  return (
    <div className="recent-submissions-section">
      <div className="recent-header-row">
        <h3>Recent Submissions</h3>
        <a href="#" className="recent-view-all" onClick={(e) => e.preventDefault()}>View All</a>
      </div>
      <div className="recent-list">
        {loading && (
          <p style={{ color: 'var(--text-light)', fontSize: 13, padding: '8px 0' }}>Loading…</p>
        )}
        {!loading && items.length === 0 && (
          <p style={{ color: 'var(--text-light)', fontSize: 13, padding: '8px 0' }}>No submissions yet.</p>
        )}
        {items.map((item) => {
          const tag = TAG[item.state] || { cls: 'pending', label: item.state };
          return (
            <div key={item.id} className="recent-item">
              <div className="recent-item-left">
                <div className="recent-icon-wrapper">
                  <SvgFile />
                </div>
                <div className="recent-details">
                  <span className="recent-filename" title={item.name}>{item.name}</span>
                  <span className="recent-meta">{fmtDate(item.lastActivityAt)}</span>
                </div>
              </div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <span className={`recent-tag ${tag.cls}`}>{tag.label}</span>
                <span className="recent-arrow"><SvgChevronRight /></span>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ───────── Adjustment Reason Panel ─────────
function AdjustmentPanel({ row }) {
  if (!row || !row.adjustments || row.adjustments.length === 0) return null;

  const fmt = (n) => {
    if (n === 0) return <span style={{ color: 'var(--text-light)' }}>0.000</span>;
    const s = (n > 0 ? '+' : '') + n.toFixed(3);
    return <span style={{ color: n > 0 ? 'var(--color-success)' : 'var(--color-error)', fontWeight: 600 }}>{s}</span>;
  };

  return (
    <div className="adjustment-panel">
      <div className="adjustment-panel-header">
        <span className="adjustment-panel-title">Adjustment reason</span>
        <span className="adjustment-panel-subtitle">for <strong>{row.label}</strong> @ {row.rate?.toFixed(3)}%</span>
      </div>
      <table className="adjustment-table">
        <thead>
          <tr>
            <th>Description</th>
            <th className="adj-num-col">Price</th>
            <th className="adj-num-col">Rate</th>
          </tr>
        </thead>
        <tbody>
          {row.adjustments.map((a, i) => (
            <tr key={i}>
              <td className="adj-desc-cell">{a.desc}</td>
              <td className="adj-num-col tabular">{fmt(a.priceAdj)}</td>
              <td className="adj-num-col tabular">{fmt(a.rateAdj)}</td>
            </tr>
          ))}
        </tbody>
        <tfoot>
          <tr className="adjustment-total-row">
            <td>Total adjustments</td>
            <td className="adj-num-col tabular">{fmt(row.totalPriceAdj)}</td>
            <td className="adj-num-col tabular">{fmt(row.totalRateAdj)}</td>
          </tr>
        </tfoot>
      </table>
    </div>
  );
}

// ───────── Price / Rate Tiers Grid (T2) ─────────
function PriceTiersGrid({ rows, activeRow, selectedRows = [], onSelectTier }) {
  if (!activeRow) return null;

  const tiers = useMemo(() => {
    return rows
      .filter(r => r.label.trim() === activeRow.label.trim())
      .sort((a, b) => a.rate - b.rate);
  }, [rows, activeRow]);

  if (tiers.length === 0) return null;

  const loanAmt = activeRow.loanAmount || 680000;
  const TAX_INS = 450;

  const fmtPct = (n) => {
    if (n === 0) return <span style={{ color: 'var(--text-light)' }}>—</span>;
    const s = (n > 0 ? '+' : '') + n.toFixed(3) + '%';
    return <span style={{ color: n > 0 ? 'var(--color-success)' : 'var(--color-error)', fontWeight: 600 }}>{s}</span>;
  };

  return (
    <div className="price-tiers-panel">
      <div className="price-tiers-header">
        <span className="price-tiers-title">Rate / Price Tiers</span>
        <span className="price-tiers-subtitle">
          {activeRow.label} — {tiers.length} option{tiers.length !== 1 ? 's' : ''}
        </span>
      </div>
      <div className="price-tiers-scroll">
        <table className="price-tiers-table">
          <thead>
            <tr>
              <th style={{ width: 40 }}></th>
              <th>Rate</th>
              <th>Price</th>
              <th>Discount %</th>
              <th>Discount $</th>
              <th>Lender Fees</th>
              <th>P&amp;I</th>
              <th>Total Expense</th>
            </tr>
          </thead>
          <tbody>
            {tiers.map(t => {
              const discountPct = typeof t.discountPct === 'number' ? t.discountPct : 0;
              const price100 = typeof t.price100 === 'number' ? t.price100 : (100 + discountPct);
              const discountAmt = Math.round(loanAmt * (discountPct / 100));
              const totalExp = (t.payment || 0) + TAX_INS;
              // A tier is selected if its key is in selectedRows, else fall back to activeRow
              const selectedTierKey = tiers.find(t2 => selectedRows.includes(t2.key))?.key ?? activeRow.key;
              const isActive = t.key === selectedTierKey;
              return (
                <tr key={t.key} className={isActive ? 'tier-row-active' : ''} style={{ cursor: 'pointer' }} onClick={() => onSelectTier && onSelectTier(activeRow.key, t.key)}>
                  <td onClick={e => e.stopPropagation()}>
                    <input
                      type="checkbox"
                      checked={isActive}
                      onChange={() => onSelectTier && onSelectTier(activeRow.key, t.key)}
                      style={{ accentColor: 'var(--primary)', width: 16, height: 16, cursor: 'pointer' }}
                    />
                  </td>
                  <td className="tier-rate-cell tabular">{t.rate?.toFixed(3)}%</td>
                  <td className="tabular">{price100.toFixed(3)}</td>
                  <td className="tabular">{fmtPct(discountPct)}</td>
                  <td className={`tabular ${discountAmt < 0 ? 'tier-cost-cell' : discountAmt > 0 ? 'tier-rebate-cell' : ''}`}>
                    {discountAmt !== 0 ? (discountAmt > 0 ? '+' : '-') : ''} ${Math.abs(discountAmt).toLocaleString()}
                  </td>
                  <td className="tabular">$1,495</td>
                  <td className="tabular">${(t.payment || 0).toLocaleString()}</td>
                  <td className="tabular tier-expense-cell">${totalExp.toLocaleString()}</td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
}

// ───────── Rates Table ─────────
// ───────── Lock Period Panel (Screen C) ─────────
function LockPeriodPanel({ lockDays, onLockDaysChange, fetchedAt }) {
  const LOCK_OPTIONS = [15, 30, 45, 60];
  const currentDays = parseInt(lockDays || 15);
  const today = new Date(); today.setHours(0, 0, 0, 0);
  const lockExpiry = new Date(today); lockExpiry.setDate(today.getDate() + currentDays);
  const minDate = new Date(today); minDate.setDate(today.getDate() + 1);

  const fmtDate = (d) =>
    `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;

  const onExpiryChange = (val) => {
    if (!val) return;
    const [yr, mo, dy] = val.split('-').map(Number);
    const picked = new Date(yr, mo - 1, dy);
    const daysAway = Math.round((picked - today) / 86400000);
    const snapped = LOCK_OPTIONS.reduce((best, opt) =>
      Math.abs(opt - daysAway) < Math.abs(best - daysAway) ? opt : best);
    onLockDaysChange(String(snapped));
  };

  const fmtTimestamp = (ts) => {
    if (!ts) return '—';
    return new Date(ts).toLocaleString('en-US', {
      month: 'short', day: 'numeric', year: 'numeric',
      hour: 'numeric', minute: '2-digit'
    });
  };

  return (
    <div className="lock-period-panel">
      <div className="lock-period-section">
        <span className="lock-period-title">Lock Period</span>
        <div className="lock-chips">
          {LOCK_OPTIONS.map(opt => (
            <button
              key={opt}
              type="button"
              className={`lock-chip${currentDays === opt ? ' lock-chip-active' : ''}`}
              onClick={() => onLockDaysChange(String(opt))}
            >
              {opt}d
            </button>
          ))}
        </div>
      </div>

      <div className="lock-period-section">
        <label className="lock-period-meta-label" htmlFor="lock-expiry-row-picker">
          Lock Expiration On
        </label>
        <input
          id="lock-expiry-row-picker"
          type="date"
          className="form-input lock-expiry-input"
          value={fmtDate(lockExpiry)}
          min={fmtDate(minDate)}
          onChange={(e) => onExpiryChange(e.target.value)}
        />
      </div>

      <div className="lock-period-section">
        <span className="lock-period-meta-label">Last Pricing Update</span>
        <span className="lock-pricing-update-value">{fmtTimestamp(fetchedAt)}</span>
      </div>
    </div>
  );
}

// ───────── Rate Table ─────────
function RateTable({ rows, filter, selectedRows = [], onToggleSelect, onSelectTier, scenario, onLockDaysChange, fetchedAt }) {
  const [expandedKey, setExpandedKey] = useState(null);

  const toggleExpand = (key) => setExpandedKey(prev => prev === key ? null : key);

  const filtered = useMemo(() => {
    if (filter === "all") return rows;
    if (filter === "fixed") return rows.filter((r) => /fixed/i.test(r.label) && !/fha|va|jumbo/i.test(r.label));
    if (filter === "arm") return rows.filter((r) => /ARM/.test(r.label) || r.key.includes("arm"));
    if (filter === "gov") return rows.filter((r) => /FHA|VA/.test(r.label) || r.key.startsWith("fha") || r.key.startsWith("va"));
    if (filter === "jumbo") return rows.filter((r) => /Jumbo/i.test(r.label) || r.key.startsWith("jumbo"));
    return rows;
  }, [rows, filter]);

  // Derived columns calculations based on row data to match table specification
  const computedRows = useMemo(() => {
    return filtered.map((r, i) => {
      // Small dynamic mock calculations matching typical values
      const investor = r.investor || '—';
      const rebatePct = r.points < 0 ? -r.points : (r.key.includes('fha') ? 0.25 : (r.key.includes('va') ? 0.375 : 0.125));
      const rebateAmt = Math.round(r.loanAmount * (rebatePct / 100));
      const price = (100 + rebatePct).toFixed(3);
      const lenderFees = 1495;
      const taxesAndIns = 450;
      const piti = Math.round(r.payment + taxesAndIns);

      return {
        ...r,
        investor,
        rebatePct,
        rebateAmt,
        price,
        lenderFees,
        taxesAndIns,
        piti
      };
    });
  }, [filtered]);

  return (
    <div className="table-container">
      <table className="rates-table">
        <thead>
          <tr>
            <th style={{ width: 40 }}></th>
            <th>Product</th>
            <th>Investor</th>
            <th>Rate</th>
            <th>APR</th>
            <th>Price</th>
            <th>Rebate %</th>
            <th>Rebate $</th>
            <th>Lender Fees</th>
            <th>P&amp;I</th>
            <th className="th-with-tooltip">T&amp;I <TooltipIcon tip="Taxes & Insurance — estimated monthly property taxes and homeowners insurance" /></th>
            <th>PITI</th>
            <th style={{ width: 36 }}></th>
          </tr>
        </thead>
        <tbody>
          {computedRows.length === 0 ? (
            <tr>
              <td colSpan="12" className="empty-state-table-cell">
                <EmptyState
                  title="No rates available"
                  body="Adjust your scenario inputs or check the backend connection."
                />
              </td>
            </tr>
          ) : (
            computedRows.map((r) => {
              const isSelected = selectedRows.includes(r.key);
              const isExpanded = expandedKey === r.key;
              return (
                <React.Fragment key={r.key}>
                  <tr className={isSelected ? "selected" : ""}>
                    <td>
                      <input
                        type="checkbox"
                        checked={isSelected}
                        onChange={() => onToggleSelect(r.key)}
                      />
                    </td>
                    <td className="table-product-cell">{r.label}</td>
                    <td>{r.investor}</td>
                    <td className="table-rate-cell tabular">{r.rate.toFixed(3)}%</td>
                    <td className="tabular">{r.apr.toFixed(3)}%</td>
                    <td className="tabular">{r.price}</td>
                    <td className="tabular">{r.rebatePct.toFixed(3)}%</td>
                    <td className="tabular">${r.rebateAmt.toLocaleString()}</td>
                    <td className="tabular">${r.lenderFees.toLocaleString()}</td>
                    <td className="tabular">${r.payment.toLocaleString()}</td>
                    <td className="tabular">${r.taxesAndIns.toLocaleString()}</td>
                    <td className="table-piti-cell tabular">${r.piti.toLocaleString()}</td>
                    <td className="table-expand-toggle-cell">
                      <button
                        className={`row-expand-btn${isExpanded ? ' row-expand-btn--open' : ''}`}
                        onClick={() => toggleExpand(r.key)}
                        aria-label={isExpanded ? 'Collapse row details' : 'Expand row details'}
                        aria-expanded={isExpanded}
                      >
                        <SvgChevronRight />
                      </button>
                    </td>
                  </tr>
                  {isExpanded && (
                    <tr className="rate-table-expand-row">
                      <td colSpan={13} className="rate-table-expand-cell">
                        <AdjustmentPanel row={r} />
                        <PriceTiersGrid rows={rows} activeRow={r} selectedRows={selectedRows} onSelectTier={onSelectTier} />
                        <LockPeriodPanel
                          lockDays={scenario?.lockDays}
                          onLockDaysChange={onLockDaysChange}
                          fetchedAt={fetchedAt}
                        />
                      </td>
                    </tr>
                  )}
                </React.Fragment>
              );
            })
          )}
        </tbody>
      </table>
    </div>
  );
}

// ───────── Market Trend Block ─────────
function MarketTrend() {
  const [stats, setStats] = useState(null);

  useEffect(() => {
    fetch('/api/dashboard-stats')
      .then((r) => r.json())
      .then((d) => setStats(d))
      .catch(() => { });
  }, []);

  const rate = stats?.bestRate30y;

  // A8: Contextual market summary — computes bps delta from rates30y session data
  const rates30y = (stats?.rates30y || []).map((r) => r.rate);
  let heading, body;
  if (rate != null) {
    heading = `Best 30Y Fixed: ${rate.toFixed(3)}%`;
    if (rates30y.length >= 2) {
      const first = rates30y[0], last = rates30y[rates30y.length - 1];
      const deltaBps = Math.round((last - first) * 100);
      if (Math.abs(deltaBps) >= 1) {
        const dir = deltaBps < 0 ? 'dropped' : 'rose';
        body = `Avg. 30Y Fixed ${dir} ${Math.abs(deltaBps)}bps this session.`;
      } else {
        body = 'Avg. 30Y Fixed holding steady this session.';
      }
    } else {
      body = 'Based on your most recent pricing run.';
    }
  } else {
    heading = 'Rates Trending Down';
    // A8 fallback: structured, not generic marketing language
    body = 'Price a scenario to generate a live market summary.';
  }

  return (
    <div className="market-trend-card">
      <div className="trend-left">
        <h3>Market Trend</h3>
        <h4>{heading}</h4>
        <p>{body}</p>
      </div>
      <div className="trend-icon">
        <SvgTrendDown />
      </div>
    </div>
  );
}

// ───────── Stats Widgets ─────────
function StatsWidgets() {
  const [stats, setStats] = useState(null);

  useEffect(() => {
    fetch('/api/dashboard-stats')
      .then((r) => r.json())
      .then((d) => setStats(d))
      .catch(() => { });
  }, []);

  const fmtDollar = (n) => {
    if (n == null) return '—';
    if (n >= 1e6) return `$${(n / 1e6).toFixed(1)}M`;
    if (n >= 1e3) return `$${(n / 1e3).toFixed(0)}K`;
    return `$${n}`;
  };

  const lockVol = stats?.lockVolume ?? null;
  const avgScore = stats?.avgCreditScore ?? null;
  const count = stats?.scenarioCount ?? null;
  // Progress bars: lock vol cap at $10M = 100%; credit score range 300–850
  const lockPct = lockVol != null ? Math.min(100, Math.round((lockVol / 10e6) * 100)) : 0;
  const scorePct = avgScore != null ? Math.round(((avgScore - 300) / 550) * 100) : 0;

  return (
    <div className="stats-row">
      <div className="stat-card">
        <span className="stat-card-label">Lock Volume (30d)</span>
        <div className="stat-card-val-row">
          <span className="stat-card-value">{fmtDollar(lockVol)}</span>
        </div>
        <div className="stat-progress-bar-bg">
          <div className="stat-progress-bar-fill" style={{ width: `${lockPct}%` }}></div>
        </div>
      </div>

      <div className="stat-card">
        <span className="stat-card-label">Avg. Credit Score (30d)</span>
        <div className="stat-card-val-row">
          <span className="stat-card-value">{avgScore != null ? avgScore : '—'}</span>
          {/* A5: month-over-month trend — placeholder until backend analytics API ships */}
          <span className="stat-card-trend stat-card-trend--placeholder" title="Month-over-month change (backend analytics pending)">
            +1 from last month
          </span>
        </div>
        <div className="stat-progress-bar-bg">
          <div className="stat-progress-bar-fill" style={{ width: `${scorePct}%` }}></div>
        </div>
      </div>
    </div>
  );
}

// ───────── Live Market Trends (T6) ─────────
function LiveMarketTrends({ fetchedAt }) {
  const [stats, setStats] = useState(null);

  useEffect(() => {
    fetch('/api/dashboard-stats').then((r) => r.json()).then((d) => setStats(d)).catch(() => { });
  }, []);

  // Discrete bar chart sparkline — 3 green shades, matches Figma
  const DEMO_BARS = [0.55, 0.80, 0.65, 0.90, 0.70, 0.50, 0.85];
  const BAR_SHADES = ['#256521', '#256521', '#3d7a1a', '#3d7a1a', '#5fa622', '#5fa622', '#8BC638'];

  const BarSparkline = ({ rates }) => {
    const hasData = rates && rates.length >= 2;
    const W = 200, H = 56, P = 4;
    const n = 7;
    const slotW = (W - P * 2) / n;
    const barW = Math.max(10, slotW - 6);

    let barHeights;
    if (hasData) {
      const trimmed = rates.slice(-7);
      const padded = trimmed.length < 7
        ? [...Array(7 - trimmed.length).fill(trimmed[0] || 0), ...trimmed]
        : trimmed;
      const min = Math.min(...padded), max = Math.max(...padded), rng = max - min || 0.5;
      barHeights = padded.map(v => Math.max(8, ((v - min) / rng) * (H - P * 2 - 8) + 8));
    } else {
      barHeights = DEMO_BARS.map(f => Math.round(f * (H - P * 2)));
    }

    return (
      <svg viewBox={`0 0 ${W} ${H}`} width="100%" height="56" preserveAspectRatio="none" aria-hidden="true">
        {barHeights.map((barH, i) => {
          const x = P + i * slotW + (slotW - barW) / 2;
          const y = H - P - barH;
          return (
            <rect key={i} x={x.toFixed(1)} y={y.toFixed(1)} width={barW.toFixed(1)} height={barH.toFixed(1)}
              fill={BAR_SHADES[i]} rx="3" />
          );
        })}
      </svg>
    );
  };

  // D5: Relative timestamp
  const relativeTime = (ts) => {
    if (!ts) return null;
    const diff = Math.floor((Date.now() - new Date(ts).getTime()) / 1000);
    if (diff < 60) return 'just now';
    if (diff < 3600) return `${Math.floor(diff / 60)}m ago`;
    if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`;
    return `${Math.floor(diff / 86400)}d ago`;
  };
  const ts = relativeTime(fetchedAt);

  const rates30y = (stats?.rates30y || []).map((r) => r.rate);
  const rates15y = (stats?.rates15y || []).map((r) => r.rate);

  // Delta vs yesterday's best rate; falls back to session-start delta if no yesterday data
  const computeDelta = (best, yesterday) => {
    if (best != null && yesterday != null) return Math.round((best - yesterday) * 1000) / 1000;
    return null;
  };
  const delta30y = computeDelta(stats?.bestRate30y, stats?.yesterdayBest30y);
  const delta15y = computeDelta(stats?.bestRate15y, stats?.yesterdayBest15y);
  const hasYesterday = stats?.yesterdayBest30y != null || stats?.yesterdayBest15y != null;

  const DeltaChip = ({ delta }) => {
    if (delta === null) {
      return <span className="live-trend-delta live-trend-delta-neutral">— vs yesterday</span>;
    }
    const up = delta > 0;
    return (
      <span className={`live-trend-delta ${up ? 'live-trend-delta-up' : 'live-trend-delta-down'}`}>
        {up ? '↑' : '↓'} {Math.abs(delta).toFixed(2)}%<br />vs yesterday
      </span>
    );
  };

  return (
    <div className="live-market-trends-panel">
      <div className="live-market-trends-header-row">
        <h3 className="live-market-trends-title">Live Market Trends</h3>
        {ts && <span className="live-market-trends-ts">Last update: {ts}</span>}
      </div>
      <div className="live-market-trends-grid">
        <div className="live-trend-track">
          <div className="live-trend-track-header">
            <div className="live-trend-track-label-rate">
              <span className="live-trend-track-label">30-Year Fixed</span>
              <span className="live-trend-track-rate">{stats?.bestRate30y != null ? `${stats.bestRate30y.toFixed(3)}%` : '—'}</span>
            </div>
            <DeltaChip delta={delta30y} />
          </div>
          <BarSparkline rates={rates30y} />
        </div>
        <div className="live-trend-track">
          <div className="live-trend-track-header">
            <div className="live-trend-track-label-rate">
              <span className="live-trend-track-label">15-Year Fixed</span>
              <span className="live-trend-track-rate">{stats?.bestRate15y != null ? `${stats.bestRate15y.toFixed(3)}%` : '—'}</span>
            </div>
            <DeltaChip delta={delta15y} />
          </div>
          <BarSparkline rates={rates15y} />
        </div>
      </div>
    </div>
  );
}

// ───────── Quick Calculator (T7) ─────────
function QuickCalculator({ scenario }) {
  const [homePrice, setHomePrice] = useState(750000);
  const [downPct, setDownPct] = useState(20);
  const [rate, setRate] = useState(6.5);

  const loanAmt = homePrice * (1 - downPct / 100);
  const r = rate / 100 / 12;
  const n = 30 * 12; // fixed 30yr for purchasing power calc
  const pmt = r > 0 ? loanAmt * r * Math.pow(1 + r, n) / (Math.pow(1 + r, n) - 1) : loanAmt / n;
  const maxLoan = r > 0 ? pmt * (Math.pow(1 + r, n) - 1) / (r * Math.pow(1 + r, n)) : pmt * n;
  const purchasingPower = Math.round(maxLoan / (1 - downPct / 100));

  const fmtShort = (n) => n >= 1e6 ? `$${(n / 1e6).toFixed(2)}M` : n >= 1e3 ? `$${Math.round(n / 1e3)}K` : `$${n}`;

  const creditScoreLabel = (() => {
    const score = scenario?.credit;
    if (!score) return null;
    if (score >= 760) return { label: score + '+', cls: 'qc-score-excellent' };
    if (score >= 740) return { label: score + ' · Very Good', cls: 'qc-score-very-good' };
    if (score >= 720) return { label: score + ' · Good', cls: 'qc-score-good' };
    if (score >= 700) return { label: score + ' · Fair', cls: 'qc-score-fair' };
    return { label: score + ' · Below Avg', cls: 'qc-score-low' };
  })();

  return (
    <div className="quick-calc-panel">
      <h3 className="quick-calc-title">Quick Calculator</h3>

      <div className="quick-calc-sliders">
        <div className="quick-calc-field">
          <div className="quick-calc-field-header">
            <label>Home Price</label>
            <span className="quick-calc-field-val">${homePrice.toLocaleString()}</span>
          </div>
          <input type="range" className="quick-calc-slider" min="100000" max="3000000" step="25000"
            value={homePrice} onChange={(e) => setHomePrice(Number(e.target.value))} />
          <div className="quick-calc-range-labels"><span>$100K</span><span>$3M</span></div>
        </div>

        <div className="quick-calc-field">
          <div className="quick-calc-field-header">
            <label>Down Payment (%)</label>
            <span className="quick-calc-field-val">{downPct}%</span>
          </div>
          <input type="range" className="quick-calc-slider" min="3" max="50" step="1"
            value={downPct} onChange={(e) => setDownPct(Number(e.target.value))} />
          <div className="quick-calc-range-labels"><span>3%</span><span>50%</span></div>
        </div>

        <div className="quick-calc-field">
          <div className="quick-calc-field-header">
            <label>Interest Rate</label>
            <span className="quick-calc-field-val">{rate.toFixed(1)}%</span>
          </div>
          <input type="range" className="quick-calc-slider" min="1" max="15" step="0.1"
            value={rate} onChange={(e) => setRate(Number(e.target.value))} />
          <div className="quick-calc-range-labels"><span>1%</span><span>15%</span></div>
        </div>

        <button
          type="button"
          className="btn-primary qc-personalize-btn"
          onClick={() => { }}
          aria-label="Personalize this quote with your full loan details"
        >
          Personalize Quote
        </button>
      </div>

      <div className="quick-calc-chips">
        <div className="quick-calc-chip">
          <span className="quick-calc-chip-label">Purchasing Power</span>
          <span className="quick-calc-chip-val">{fmtShort(purchasingPower)}</span>
        </div>
        <div className="quick-calc-chip">
          <span className="quick-calc-chip-label">Credit Score Range</span>
          <span className={`quick-calc-chip-val${creditScoreLabel ? ` ${creditScoreLabel.cls}` : ''}`}>
            {creditScoreLabel ? creditScoreLabel.label : '—'}
          </span>
        </div>
      </div>
    </div>
  );
}

// ───────── Bottom Loan Comparison horizontal card deck ─────────
function LoanComparisonDeck({ rows = [], selectedRows = [], scenario, onCompare }) {
  const TAX_INS = 450;

  const selected = selectedRows
    .map(k => rows.find(r => r.key === k))
    .filter(Boolean);

  const [baseline, ...options] = selected;

  const loanAmt = (scenario?.homePrice || 850000) - (scenario?.downPayment || 170000);
  const ltv = Math.round((loanAmt / (scenario?.homePrice || 850000)) * 100);
  const miMo = ltv > 80 ? Math.round(loanAmt * 0.005 / 12) : 0;

  const totalMonthly = (row) => row ? Math.round(row.payment + TAX_INS + miMo) : 0;

  const totalInterest = (row) => row
    ? Math.round(row.payment * 360 - loanAmt)
    : 0;

  const fd = (n) => `$${Math.abs(Math.round(n)).toLocaleString()}`;

  const maxSavings = baseline
    ? Math.max(0, ...options.map(o => totalInterest(baseline) - totalInterest(o)))
    : 0;

  const labelForOption = (idx) => {
    const labels = ['Option A', 'Option B', 'Option C', 'Option D', 'Option E', 'Option F'];
    return labels[idx] || `Option ${idx + 1}`;
  };

  const LOAN_PURPOSE_LABELS = { purchase: 'Purchase', refi: 'Refinance', cashout: 'Cash-Out' };
  const loanTypeBadge = LOAN_PURPOSE_LABELS[scenario?.loanPurpose] || 'Option';

  return (
    <div className="loan-comparison-container">
      <div className="comparison-header-row">
        <div>
          <h3>Loan Comparison</h3>
          <p>
            {baseline
              ? `Comparing ${baseline.label}${options.length ? ` vs. ${options[0].label}` : ''}`
              : 'Check rows in the rate table above to compare'}
          </p>
        </div>
      </div>

      {selected.length === 0 ? (
        <EmptyState
          title="No rows selected"
          body="Check rows in the rate table above to add comparison options."
        />
      ) : (
        <>
          <div className="comparison-deck">
            {/* Baseline card */}
            <div className="comparison-card baseline active">
              <span className="comp-card-badge">Baseline</span>
              <h4 className="comp-card-title" title={baseline.label}>{baseline.label}</h4>
              <div className="comp-card-metric-row">
                <span className="comp-card-label">Interest Rate</span>
                <span className="comp-card-val tabular">{baseline.rate.toFixed(3)}%</span>
              </div>
              <div className="comp-card-metric-row">
                <span className="comp-card-label">APR</span>
                <span className="comp-card-val comp-card-val--muted tabular">{baseline.apr.toFixed(3)}%</span>
              </div>
              <div className="comp-card-metric-row" style={{ marginTop: 'auto', paddingTop: 8 }}>
                <span className="comp-card-monthly-label">Total Monthly</span>
                <span className="comp-card-monthly-val tabular">{fd(totalMonthly(baseline))}</span>
              </div>
            </div>

            {/* Option cards — one per additional selection */}
            {options.map((o, i) => (
              <div key={o.key} className="comparison-card">
                <span className="comp-card-badge">{loanTypeBadge}</span>
                <h4 className="comp-card-title" title={o.label}>{labelForOption(i)}</h4>
                <div className="comp-card-metric-row">
                  <span className="comp-card-label">Interest Rate</span>
                  <span className="comp-card-val tabular">{o.rate.toFixed(3)}%</span>
                </div>
                <div className="comp-card-metric-row">
                  <span className="comp-card-label">APR</span>
                  <span className="comp-card-val comp-card-val--muted tabular">{o.apr.toFixed(3)}%</span>
                </div>
                <div className="comp-card-metric-row" style={{ marginTop: 'auto', paddingTop: 8 }}>
                  <span className="comp-card-monthly-label">Total Monthly</span>
                  <span className="comp-card-monthly-val tabular">{fd(totalMonthly(o))}</span>
                </div>
              </div>
            ))}
          </div>

          <div className="comparison-banner-row">
            <span className="comparison-banner-text">
              {maxSavings > 500
                ? <>You save <strong>{fd(maxSavings)}</strong> in interest with the best option</>
                : <>Compare options to find the best rate for your borrower</>}
            </span>
            {selected.length >= 2 && (
              <button className="btn-compare-deck" onClick={onCompare}>
                → Compare
              </button>
            )}
          </div>
        </>
      )}
    </div>
  );
}

// ───────── Disclosure / Footer ─────────
function Disclosure() {
  return (
    <footer className="disc-section">
      <h4>Rate &amp; APR Assumptions</h4>
      <p>
        Rates shown are illustrative for a pilot LO application and are not an absolute commitment to lend.
        Annual Percentage Rate (APR) assumes a single-family primary residence in the requested ZIP code,
        a 15 to 30-day rate lock, and standard lender fees plus discount points as shown.
        Conforming loan limits apply. Loans above conforming levels use jumbo pricing. FHA pricing assumes minimum 3.5% down with required upfront and monthly
        MIP. VA pricing assumes a qualifying veteran with no down payment and an applicable funding fee.
      </p>
      <p>
        Adjustable-rate mortgages (ARMs) carry an introductory fixed period after which the rate adjusts
        based on the SOFR index plus a margin. Property taxes, homeowners insurance, HOA dues, and mortgage insurance (if required) are not
        included in the rate but are reflected in the estimated monthly payment breakdowns.
      </p>

      <div className="disc-footer">
        {/* TODO: Add real NMLS number before any production deployment */}
        <span>© {new Date().getFullYear()} Trivalley Home Loans, Inc.</span>
        <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
          <span style={{ border: "1px solid var(--text-light)", padding: "1px 4px", borderRadius: 3, fontWeight: "bold" }}>⌂</span>
          Equal Housing Lender
        </span>
        <span>Rates as of {new Date().toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" })} PT</span>
      </div>
    </footer>
  );
}

// ───────── Full-page Comparison Screen ─────────
function ComparisonScreen({ rows, selectedKeys, onBack, fetchedAt, scenario }) {
  const selected = selectedKeys.map(k => rows.find(r => r.key === k)).filter(Boolean);
  const [baseline, ...options] = selected;
  const [activeOptIdx, setActiveOptIdx] = useState(0);
  const [showAmort, setShowAmort] = useState(false);

  const opt = options[activeOptIdx] || null;

  const fd = (n) => `$${Math.abs(Math.round(n)).toLocaleString()}`;
  const fdr = (n) => `${n.toFixed(3)}%`;
  const TAX_INS = 450;

  const miMo = (row) => {
    if (!row) return 0;
    const lv = Math.round(((row.loanAmount - (row.loanAmount * 0)) / row.loanAmount) * 100);
    return lv > 80 ? Math.round(row.loanAmount * 0.005 / 12) : 0;
  };

  const totalMonthly = (row) => row ? row.payment + TAX_INS + miMo(row) : 0;

  const cc = (row) => row ? 1495 + Math.max(0, Math.round(row.loanAmount * 0.005)) : 0;

  const totalInterest = (row) => {
    if (!row) return 0;
    const r = row.rate / 100 / 12;
    const n = 360;
    const p = r > 0 ? row.payment : 0;
    return Math.round(p * n - (row.loanAmount || 0));
  };

  const lifeSavings = baseline && opt ? totalInterest(baseline) - totalInterest(opt) : 0;
  const monthlySavings = baseline && opt ? Math.round(totalMonthly(baseline) - totalMonthly(opt)) : 0;

  const computeAmort = (row, termYrs = 30) => {
    if (!row) return [];
    const r = row.rate / 100 / 12;
    const n = termYrs * 12;
    const pmt = r > 0 ? row.loanAmount * r * Math.pow(1 + r, n) / (Math.pow(1 + r, n) - 1) : row.loanAmount / n;
    const amortRows = [];
    let bal = row.loanAmount;
    for (let i = 1; i <= 12; i++) {
      const int = bal * r;
      const prin = pmt - int;
      bal = Math.max(0, bal - prin);
      amortRows.push({ month: i, pmt: Math.round(pmt), prin: Math.round(prin), int: Math.round(int), bal: Math.round(bal) });
    }
    return amortRows;
  };

  const DETAIL_ROWS = baseline && opt ? [
    ['Loan Type', 'Conforming', 'Conforming'],
    ['Loan Term', '30 yr', '30 yr'],
    ['Monthly P&I', fd(baseline.payment), fd(opt.payment)],
    ['Interest Rate', fdr(baseline.rate), fdr(opt.rate)],
    ['APR', fdr(baseline.apr), fdr(opt.apr)],
    ['Mortgage Ins.', miMo(baseline) ? fd(miMo(baseline)) : '$0', miMo(opt) ? fd(miMo(opt)) : '$0'],
    ['Taxes & Ins.', fd(TAX_INS), fd(TAX_INS)],
    ['Total Monthly', fd(totalMonthly(baseline)), fd(totalMonthly(opt))],
    ['Closing Costs', fd(cc(baseline)), fd(cc(opt))],
    ['Points', '0.00', '1.125'],
    ['Lender Credits', '$0.00', `(${fd(Math.max(0, cc(baseline) - cc(opt)))})`],
    ['Est. Closing Savings', '—', fd(Math.max(0, cc(baseline) - cc(opt)))],
    ['Total Interest', fd(totalInterest(baseline)), fd(totalInterest(opt))],
    ['Amortization', '30 yrs', '30 yrs'],
  ] : [];

  const amortBaseline = computeAmort(baseline);
  const amortRows = computeAmort(opt || baseline);

  const labelForOption = (idx) => {
    const labels = ['Option A', 'Option B', 'Option C'];
    return labels[idx] || `Option ${idx + 1}`;
  };

  if (!baseline) return null;

  return (
    <div className="cscreen-wrapper">
      <div className="cscreen-main">
        {/* Header */}
        <div className="cscreen-header">
          <button className="cscreen-back-btn" onClick={onBack}>
            ← Loan Comparison
          </button>
          <span className="cscreen-subtitle">
            Baseline vs. {opt ? opt.label : 'select an option'}
          </span>
        </div>

        {/* Comparison cards */}
        <div className="cscreen-cards-row">
          {/* Baseline card */}
          <div className="comparison-card baseline active">
            <span className="comp-card-badge">Baseline</span>
            <h4 className="comp-card-title">{baseline.label}</h4>
            <div className="comp-card-metric-row">
              <span className="comp-card-label">Interest Rate</span>
              <span className="comp-card-val tabular">{fdr(baseline.rate)}</span>
            </div>
            <div className="comp-card-metric-row">
              <span className="comp-card-label">APR</span>
              <span className="comp-card-val comp-card-val--muted tabular">{fdr(baseline.apr)}</span>
            </div>
            <div className="comp-card-metric-row" style={{ marginTop: 'auto', paddingTop: 8 }}>
              <span className="comp-card-monthly-label">Total Monthly</span>
              <span className="comp-card-monthly-val tabular">{fd(totalMonthly(baseline))}</span>
            </div>
          </div>

          {/* Option cards */}
          {options.map((o, i) => (
            <div
              key={o.key}
              className={`comparison-card${i === activeOptIdx ? ' active' : ''}`}
              onClick={() => setActiveOptIdx(i)}
            >
              <span className="comp-card-badge">{labelForOption(i)}</span>
              <h4 className="comp-card-title" title={o.label}>{o.label}</h4>
              <div className="comp-card-metric-row">
                <span className="comp-card-label">Interest Rate</span>
                <span className="comp-card-val tabular">{fdr(o.rate)}</span>
              </div>
              <div className="comp-card-metric-row">
                <span className="comp-card-label">APR</span>
                <span className="comp-card-val comp-card-val--muted tabular">{fdr(o.apr)}</span>
              </div>
              <div className="comp-card-metric-row" style={{ marginTop: 'auto', paddingTop: 8 }}>
                <span className="comp-card-monthly-label">Total Monthly</span>
                <span className="comp-card-monthly-val tabular">{fd(totalMonthly(o))}</span>
              </div>
            </div>
          ))}
        </div>

        {/* Savings banner */}
        {lifeSavings > 0 && (
          <div className="cscreen-savings-banner">
            <div className="cscreen-savings-icon" aria-hidden="true">
              <svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
                <circle cx="18" cy="18" r="18" fill="var(--color-success-bg)" />
                <path d="M11 18.5l4.5 4.5 9.5-10.5" stroke="var(--forest)" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" />
              </svg>
            </div>
            <div>
              <div className="cscreen-savings-label">EST. LIFE OF LOAN SAVINGS*</div>
              <div className="cscreen-savings-amount">{fd(lifeSavings)}</div>
              <div className="cscreen-savings-sub">Significant reduction in interest expense over the full 30-year term.</div>
            </div>
          </div>
        )}

        {/* Detailed comparison table */}
        {opt && (
          <div className="cscreen-detail">
            <h4 className="cscreen-detail-title">Detailed Comparison</h4>
            <div className="detail-comparison-table-wrap">
              <table className="detail-comparison-table">
                <thead>
                  <tr>
                    <th>Metric</th>
                    <th>Current</th>
                    <th className="detail-col-option">{labelForOption(activeOptIdx)}</th>
                  </tr>
                </thead>
                <tbody>
                  {DETAIL_ROWS.map(([label, base, optVal], i) => (
                    <tr key={i}>
                      <td>{label}</td>
                      <td className="tabular">{base}</td>
                      <td className={`tabular detail-col-option${/Rate|Monthly|Interest/.test(label) ? ' detail-col-highlight' : ''}`}>{optVal}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>

            <button className="cscreen-amort-toggle" onClick={() => setShowAmort(v => !v)}>
              {showAmort ? '▲ Hide' : '▼ Show'} Amortization Schedule · First 12 Months
            </button>

            {showAmort && (
              <div className="detail-comparison-table-wrap" style={{ marginTop: 8 }}>
                <table className="detail-comparison-table">
                  <thead>
                    <tr>
                      <th>Month</th>
                      <th>Baseline P&amp;I</th>
                      <th>Baseline Interest</th>
                      <th>Baseline Balance</th>
                      <th className="detail-col-option">{opt ? labelForOption(activeOptIdx) : 'Option'} P&amp;I</th>
                      <th className="detail-col-option">{opt ? labelForOption(activeOptIdx) : 'Option'} Interest</th>
                      <th className="detail-col-option">{opt ? labelForOption(activeOptIdx) : 'Option'} Balance</th>
                    </tr>
                  </thead>
                  <tbody>
                    {amortBaseline.map((b, i) => {
                      const o = amortRows[i];
                      const saves = b.int - (o ? o.int : b.int);
                      return (
                        <tr key={b.month}>
                          <td>{b.month}</td>
                          <td className="tabular">${b.pmt.toLocaleString()}</td>
                          <td className="tabular">${b.int.toLocaleString()}</td>
                          <td className="tabular">${b.bal.toLocaleString()}</td>
                          <td className={`tabular detail-col-option${o && o.pmt < b.pmt ? ' detail-col-highlight' : ''}`}>{o ? `$${o.pmt.toLocaleString()}` : '—'}</td>
                          <td className={`tabular detail-col-option${saves > 0 ? ' detail-col-highlight' : ''}`}>{o ? `$${o.int.toLocaleString()}` : '—'}</td>
                          <td className="tabular detail-col-option">{o ? `$${o.bal.toLocaleString()}` : '—'}</td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>
            )}

            <p className="cscreen-disclaimer">
              * Est. Life of Loan Savings is based on total interest paid over the full loan term assuming no early payoff.
            </p>
          </div>
        )}
      </div>

      {/* Right sidebar */}
      <div className="cscreen-sidebar">
        <LiveMarketTrends fetchedAt={fetchedAt} />
        <QuickCalculator scenario={scenario} />
      </div>
    </div>
  );
}

// Export components to global window context so app.jsx can access them.
Object.assign(window, {
  Header,
  AppLauncherScreen,
  ScenarioForm,
  RateTable,
  AdjustmentPanel,
  PriceTiersGrid,
  LockPeriodPanel,
  MarketTrend,
  StatsWidgets,
  LiveMarketTrends,
  QuickCalculator,
  LoanComparisonDeck,
  ComparisonScreen,
  Disclosure,
  SignInOverlay,
  TooltipIcon,
  EmptyState,
});