const { useState, useRef, useCallback, useEffect, useMemo } = React;

const API = "/api";

// ─── Responsive hook ─────────────────────────────────────────
function useIsMobile(breakpoint = 768) {
  const [isMobile, setIsMobile] = useState(() => window.innerWidth < breakpoint);
  useEffect(() => {
    const mq = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);
    const handler = (e) => setIsMobile(e.matches);
    mq.addEventListener("change", handler);
    return () => mq.removeEventListener("change", handler);
  }, [breakpoint]);
  return isMobile;
}

// ─── API ──────────────────────────────────────────────────────

async function extractTextFromPDF(file) {
  const arrayBuffer = await file.arrayBuffer();
  const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise;
  let text = "";
  for (let i = 1; i <= pdf.numPages; i++) {
    const page = await pdf.getPage(i);
    const content = await page.getTextContent();
    text += content.items.map(item => item.str).join(" ") + "\n\n";
  }
  return text;
}

async function analyzeText(text) {
  const r = await fetch(`${API}/analyze`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ text }),
  });
  if (!r.ok) throw new Error((await r.json().catch(() => ({}))).detail || "Analysis failed. Please try again.");
  return r.json();
}

// ─── Hardcoded demo data (works without any API call) ─────────

const DEMO_DATA = {
  text: "This agreement between the Client and XYZ Financial Services establishes the terms under which XYZ will manage your investment portfolio.\n\nSection 2 \u2013 Fees: The annual management fee shall be 1.25% of total assets under management, charged quarterly in arrears. Additional transaction fees of $9.95 per trade may apply for individual stock purchases outside the model portfolio.\n\nSection 3 \u2013 Termination: Early termination of this agreement within the first 24 months will result in a penalty fee equal to 3% of total assets under management at the time of termination.\n\nSection 4 \u2013 Amendments: XYZ reserves the right to modify fee structures with 30 days written notice to the Client. Continued use of services after notification constitutes acceptance of modified terms.\n\nSection 5 \u2013 Liability: XYZ shall not be held liable for investment losses resulting from market conditions, acts of God, or regulatory changes. Client acknowledges that all investments carry inherent risk and past performance is not indicative of future results.",
  overview: {
    type: "Investment Management Agreement",
    summary: "This agreement gives XYZ Financial Services authority to manage your investment portfolio. You'll pay 1.25% annually plus potential trade fees, and face a 3% penalty for leaving early.",
    issuer: "XYZ Financial Services"
  },
  annotations: [
    {
      id: "1", start: 157, end: 261,
      type: "danger", impact_level: "HIGH",
      label: "Annual fee of 1.25% on all your assets",
      explanation: "You'll be charged 1.25% of everything they manage for you, taken out every quarter. On a $100,000 portfolio, that's $1,250/year.",
      impact_reason: "This is a recurring fee that directly reduces your investment returns every year.",
      original_text: "The annual management fee shall be 1.25% of total assets under management, charged quarterly in arrears.",
      financial_terms: [{ term: "Assets Under Management", definition: "The total market value of investments that XYZ manages on your behalf" }],
      confidence: "HIGH", confidence_note: "", section: "KEY_CLAUSES"
    },
    {
      id: "2", start: 405, end: 569,
      type: "danger", impact_level: "HIGH",
      label: "3% penalty if you leave within 2 years",
      explanation: "If you cancel within the first 24 months, you lose 3% of your total portfolio value. On $100,000, that's a $3,000 fee just to leave.",
      impact_reason: "This locks you into the agreement and could cost thousands if your circumstances change.",
      original_text: "Early termination of this agreement within the first 24 months will result in a penalty fee equal to 3% of total assets under management at the time of termination.",
      financial_terms: [{ term: "Early Termination Fee", definition: "A penalty charged when you end the agreement before the minimum period" }],
      confidence: "HIGH", confidence_note: "", section: "KEY_CLAUSES"
    },
    {
      id: "3", start: 595, end: 772,
      type: "warning", impact_level: "MEDIUM",
      label: "They can change fees with only 30 days notice",
      explanation: "XYZ can increase their fees and you automatically agree if you keep using their services after 30 days. You'd need to actively leave to avoid new fees.",
      impact_reason: "Your costs could increase at any time with minimal notice, and staying counts as agreeing.",
      original_text: "XYZ reserves the right to modify fee structures with 30 days written notice to the Client.",
      financial_terms: [],
      confidence: "MEDIUM", confidence_note: "", section: "KEY_CLAUSES"
    },
    {
      id: "4", start: 797, end: 917,
      type: "info", impact_level: "LOW",
      label: "They accept no responsibility for investment losses",
      explanation: "Standard disclaimer that XYZ is not liable if your investments lose money due to market conditions. This is typical in investment agreements.",
      impact_reason: "Standard boilerplate but worth noting \u2014 you bear all investment risk.",
      original_text: "XYZ shall not be held liable for investment losses resulting from market conditions, acts of God, or regulatory changes.",
      financial_terms: [],
      confidence: "LOW", confidence_note: "This clause may have additional implications depending on your state's consumer protection laws.", section: "KEY_CLAUSES"
    },
    {
      id: "5", start: 262, end: 378,
      type: "warning", impact_level: "MEDIUM",
      label: "Hidden $9.95 per trade fee",
      explanation: "Each time you buy individual stocks outside their recommended portfolio, you pay an extra $9.95. Active traders could see these fees add up quickly.",
      estimated_impact: "$9.95 per trade, potentially $500+/year for active traders",
      original_text: "Additional transaction fees of $9.95 per trade may apply for individual stock purchases outside the model portfolio.",
      confidence: "HIGH", confidence_note: "",
      section: "HIDDEN_COSTS"
    }
  ],
  hidden_costs: [
    {
      original_text: "Additional transaction fees of $9.95 per trade may apply for individual stock purchases outside the model portfolio.",
      what_it_means: "If you want to buy individual stocks instead of their recommended mix, each trade costs $9.95 extra. This could add up if you're an active trader.",
      estimated_impact: "$9.95/trade \u2014 could mean $500+ per year for active traders"
    },
    {
      original_text: "Early termination of this agreement within the first 24 months will result in a penalty fee equal to 3% of total assets.",
      what_it_means: "Leaving early is expensive. On a $200,000 portfolio, you'd pay $6,000 just to switch providers.",
      estimated_impact: "3% of portfolio value \u2014 $3,000 on $100k, $6,000 on $200k"
    }
  ],
  questions: [
    {
      question: "Can the early termination fee be waived if XYZ raises their management fees?",
      why_it_matters: "If they increase fees significantly, you shouldn't be penalized for wanting to leave.",
      related_clause: "Sections 3 and 4"
    },
    {
      question: "Is there a cap on how much the management fee can be increased?",
      why_it_matters: "Without a cap, your 1.25% fee could theoretically be raised to any amount.",
      related_clause: "Section 4"
    },
    {
      question: "Are there any additional fees not mentioned in this agreement (account maintenance, transfer fees, etc.)?",
      why_it_matters: "Some firms have hidden fees not disclosed in the main agreement.",
      related_clause: "Section 2"
    }
  ]
};

// ─── Impact helpers ───────────────────────────────────────────

const IMPACT = {
  HIGH:   { hl: "hl-high",   dot: "bg-red-500",   activeBorder: "border-l-red-500",   badge: "text-red-700 bg-red-50 border border-red-200",   label: "High" },
  MEDIUM: { hl: "hl-medium", dot: "bg-amber-500",  activeBorder: "border-l-amber-500", badge: "text-amber-700 bg-amber-50 border border-amber-200", label: "Medium" },
  LOW:    { hl: "hl-low",    dot: "bg-blue-500",   activeBorder: "border-l-blue-500",  badge: "text-blue-700 bg-blue-50 border border-blue-200",  label: "Low" },
};

function impactOf(ann) {
  return ann.impact_level || (ann.section === "HIDDEN_COSTS" ? "HIGH" : "MEDIUM");
}

function confidenceOf(ann) {
  return ann.confidence || "HIGH";
}

// ─── Icons ───────────────────────────────────────────────────

function IconCheck({ className = "w-3.5 h-3.5" }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" strokeWidth={2.5} viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7"/>
    </svg>
  );
}

function IconWarning({ className = "w-3.5 h-3.5" }) {
  return (
    <svg className={className} fill="currentColor" viewBox="0 0 20 20">
      <path fillRule="evenodd" d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.168 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 6a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 6zm0 9a1 1 0 100-2 1 1 0 000 2z" clipRule="evenodd"/>
    </svg>
  );
}

function IconFlag({ className = "w-3 h-3" }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" strokeWidth={1.5} viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" d="M3 21v-4m0 0V5a2 2 0 012-2h6.5l1 1H21l-3 6 3 6h-8.5l-1-1H5a2 2 0 00-2 2z"/>
    </svg>
  );
}

function IconArrow({ className = "w-5 h-5" }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" strokeWidth={1.5} viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" d="M15 19l-7-7 7-7"/>
    </svg>
  );
}

function IconUpload({ className = "w-5 h-5" }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" strokeWidth={1.5} viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5"/>
    </svg>
  );
}

function IconAnnotate({ className = "w-5 h-5" }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" strokeWidth={1.5} viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" d="M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 01.865-.501 48.172 48.172 0 003.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0012 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018z"/>
    </svg>
  );
}

function IconDecide({ className = "w-5 h-5" }) {
  return (
    <svg className={className} fill="none" stroke="currentColor" strokeWidth={1.5} viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75L11.25 15 15 9.75m-3-7.036A11.959 11.959 0 013.598 6 11.99 11.99 0 003 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285z"/>
    </svg>
  );
}

function IconTilde() {
  return <span className="text-amber-500 font-bold text-sm leading-none">~</span>;
}

function IconThumbUp({ className = "w-3.5 h-3.5", filled = false }) {
  return (
    <svg className={className} fill={filled ? "currentColor" : "none"} stroke="currentColor" strokeWidth={filled ? 0 : 1.5} viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" d="M6.633 10.25c.806 0 1.533-.446 2.031-1.08a9.041 9.041 0 0 1 2.861-2.4c.723-.384 1.35-.956 1.653-1.715a4.498 4.498 0 0 0 .322-1.672V3a.75.75 0 0 1 .75-.75 2.25 2.25 0 0 1 2.25 2.25c0 1.152-.26 2.243-.723 3.218-.266.558.107 1.282.725 1.282m0 0h3.126c1.026 0 1.945.694 2.054 1.715.045.422.068.85.068 1.285a11.95 11.95 0 0 1-2.649 7.521c-.388.482-.987.729-1.605.729H13.48c-.483 0-.964-.078-1.423-.23l-3.114-1.04a4.501 4.501 0 0 0-1.423-.23H5.904m10.598-9.75H14.25M5.904 18.5c.083.205.173.405.27.602.197.4-.078.898-.523.898h-.908c-.889 0-1.713-.518-1.972-1.368a12 12 0 0 1-.521-3.507c0-1.553.295-3.036.831-4.398C3.387 10.203 4.167 9.75 5 9.75h1.053c.472 0 .745.556.5.96a8.958 8.958 0 0 0-1.302 4.665c0 1.194.232 2.333.654 3.375Z"/>
    </svg>
  );
}

function IconThumbDown({ className = "w-3.5 h-3.5", filled = false }) {
  return (
    <svg className={className} fill={filled ? "currentColor" : "none"} stroke="currentColor" strokeWidth={filled ? 0 : 1.5} viewBox="0 0 24 24">
      <path strokeLinecap="round" strokeLinejoin="round" d="M7.498 15.25H4.372c-1.026 0-1.945-.694-2.054-1.715a12.137 12.137 0 0 1-.068-1.285c0-2.848.992-5.464 2.649-7.521C5.287 4.247 5.886 4 6.504 4h4.016a4.5 4.5 0 0 1 1.423.23l3.114 1.04a4.5 4.5 0 0 0 1.423.23h1.294M7.498 15.25c.618 0 .991.724.725 1.282A7.471 7.471 0 0 0 7.5 19.75 2.25 2.25 0 0 0 9.75 22a.75.75 0 0 0 .75-.75v-.633c0-.573.11-1.14.322-1.672.304-.76.93-1.33 1.653-1.715a9.04 9.04 0 0 0 2.86-2.4c.498-.634 1.226-1.08 2.032-1.08h.384m-10.253 1.5H9.7m8.075-9.75c.083.205.173.405.27.602.197.4-.078.898-.523.898h-.908c-.889 0-1.713-.518-1.972-1.368a12 12 0 0 1-.521-3.507c0-1.553.295-3.036.831-4.398C15.387 3.203 16.167 2.75 17 2.75h1.053c.472 0 .745.556.5.96a8.958 8.958 0 0 0-1.302 4.665c0 1.194.232 2.333.654 3.375Z"/>
    </svg>
  );
}

// ─── Shared components ───────────────────────────────────────

function Toast({ message, visible, fading }) {
  if (!visible) return null;
  return (
    <div className={`fixed bottom-20 left-1/2 -translate-x-1/2 px-5 py-2.5 bg-neutral-900 text-white text-[13px] z-50 ${fading ? "toast-exit" : "toast-enter"}`}>
      {message}
    </div>
  );
}

function ToggleSwitch({ on, onToggle, label }) {
  return (
    <div className="flex items-center gap-3 cursor-pointer select-none" onClick={onToggle}>
      <div className={`toggle-track ${on ? "on" : ""}`}>
        <div className="toggle-thumb"></div>
      </div>
      <span className="text-[13px] text-neutral-600 whitespace-nowrap">{label}</span>
    </div>
  );
}

// ═══════════════════════════════════════════════════════════════
//  LANDING PAGE
// ═══════════════════════════════════════════════════════════════

function InputView({ onAnalyze, analyzing, onTestMock }) {
  const [text, setText] = useState("");
  const [dragOver, setDragOver] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [err, setErr] = useState(null);
  const [fname, setFname] = useState(null);
  const [showPaste, setShowPaste] = useState(false);
  const ref = useRef(null);
  const isMobile = useIsMobile();

  const handleFile = useCallback(async (file) => {
    if (!file) return;
    if (!["application/pdf", "text/plain"].includes(file.type)) { setErr("Please upload a PDF or TXT file."); return; }
    setErr(null); setUploading(true);
    try {
      if (file.type === "text/plain") { setText(await file.text()); }
      else { setText(await extractTextFromPDF(file)); }
      setFname(file.name);
      setShowPaste(true);
    } catch (e) { setErr(e.message || "Failed to read file."); }
    finally { setUploading(false); }
  }, []);

  const has = text.trim().length > 0;

  return (
    <div className="min-h-screen flex flex-col bg-white">
      {/* Nav */}
      <nav className={`flex items-center justify-between border-b border-neutral-100 ${isMobile ? "px-4 py-4" : "px-8 py-5"}`}>
        <span className="text-[16px] font-semibold tracking-tight text-neutral-900">ClearTerms</span>
        {onTestMock && (
          <button
            onClick={onTestMock}
            disabled={analyzing}
            className="px-4 py-2 text-[13px] font-medium text-white bg-brand-600 hover:bg-brand-700 transition-colors disabled:opacity-40"
          >
            Try Demo
          </button>
        )}
      </nav>

      {/* Hero */}
      <main className={`flex-1 flex flex-col items-center justify-center landing-fade-in ${isMobile ? "px-4" : "px-6"}`}>
        <div className={`max-w-2xl w-full text-center ${isMobile ? "mb-8 mt-8" : "mb-14"}`}>
          <h1 className={`font-bold tracking-tight text-neutral-900 leading-[1.15] ${isMobile ? "text-[28px] mb-4" : "text-[42px] mb-5"}`}>
            Understand what you're signing.{isMobile ? " " : <br />}Before you sign it.
          </h1>
          <p className={`text-neutral-500 leading-relaxed max-w-xl mx-auto ${isMobile ? "text-[15px]" : "text-[18px]"}`}>
            ClearTerms annotates financial agreements in plain language{" \u2014 "}without changing a single word.
          </p>
        </div>

        {/* Upload area */}
        <div className={`w-full ${isMobile ? "max-w-full px-0" : "max-w-lg"}`}>
          {!showPaste ? (
            <div>
              {/* Upload zone */}
              <div
                className={`border-2 border-dashed hover:border-brand-400 transition-colors cursor-pointer ${
                  dragOver ? "border-brand-500 bg-brand-50" : "border-neutral-300"
                }`}
                onClick={() => !uploading && ref.current?.click()}
                onDragOver={e => { e.preventDefault(); setDragOver(true); }}
                onDragLeave={() => setDragOver(false)}
                onDrop={e => { e.preventDefault(); setDragOver(false); handleFile(e.dataTransfer.files?.[0]); }}
              >
                <div className={`flex flex-col items-center justify-center px-6 ${isMobile ? "py-10" : "py-14"}`}>
                  {uploading ? (
                    <div className="text-center">
                      <div className="animate-spin inline-block w-6 h-6 border-2 border-neutral-300 border-t-brand-600 rounded-full mb-3"></div>
                      <p className="text-[15px] text-neutral-500">Extracting text...</p>
                    </div>
                  ) : (
                    <div className="text-center">
                      <IconUpload className="w-7 h-7 text-neutral-300 mx-auto mb-4" />
                      <p className="text-[16px] font-medium text-neutral-900 mb-1">Upload Agreement</p>
                      <p className="text-[14px] text-neutral-500">{isMobile ? "Tap to browse — PDF or TXT" : "PDF or TXT — drag and drop or click to browse"}</p>
                    </div>
                  )}
                </div>
              </div>
              <input ref={ref} type="file" accept=".pdf,.txt" className="hidden"
                onChange={e => { handleFile(e.target.files?.[0]); e.target.value = ""; }} />

              {/* Action row: paste link only (Try Demo moved to nav) */}
              <div className="flex items-center justify-center mt-5">
                <button
                  onClick={() => setShowPaste(true)}
                  className="text-[14px] text-neutral-500 hover:text-brand-600 transition-colors"
                >
                  Or paste text
                </button>
              </div>
            </div>
          ) : (
            <div>
              {/* Paste area */}
              <div className="border border-neutral-200">
                {fname && (
                  <div className="flex items-center justify-between px-4 py-2.5 border-b border-neutral-100 bg-neutral-50">
                    <span className="text-[13px] text-neutral-500">{fname}</span>
                    <button onClick={() => { setText(""); setFname(null); }} className="text-[12px] text-neutral-400 hover:text-neutral-600">Clear</button>
                  </div>
                )}
                <textarea
                  value={text}
                  onChange={e => { setText(e.target.value); setFname(null); setErr(null); }}
                  rows={isMobile ? 7 : 10}
                  placeholder="Paste your agreement text here..."
                  className={`w-full resize-none text-[15px] text-neutral-800 leading-relaxed focus:outline-none bg-white ${isMobile ? "p-4" : "p-6"}`}
                  autoFocus={!fname}
                />
              </div>
              <div className="flex items-center gap-3 mt-4">
                <button
                  onClick={() => has && onAnalyze(text)}
                  disabled={analyzing || uploading || !has}
                  className="flex-1 py-3 text-[15px] font-medium bg-brand-600 text-white hover:bg-brand-700 disabled:opacity-30 disabled:cursor-not-allowed transition-colors"
                >
                  {analyzing ? "Analyzing..." : "Analyze Agreement"}
                </button>
                <button
                  onClick={() => { setShowPaste(false); if (!fname) setText(""); }}
                  className="py-3 px-5 text-[14px] text-neutral-400 hover:text-neutral-600 transition-colors"
                >
                  Back
                </button>
              </div>
            </div>
          )}
        </div>

        {err && (
          <div className="mt-4 px-4 py-2.5 text-[14px] text-red-700 bg-red-50 border border-red-100 max-w-lg w-full">{err}</div>
        )}

        {/* How it works */}
        <div className={`max-w-2xl w-full ${isMobile ? "mt-12 mb-6" : "mt-24 mb-8"}`}>
          <h2 className={`text-[12px] font-semibold uppercase tracking-[0.15em] text-neutral-400 text-center ${isMobile ? "mb-8" : "mb-12"}`}>How it works</h2>
          <div className={`grid gap-8 ${isMobile ? "grid-cols-1 max-w-xs mx-auto" : "grid-cols-3 gap-12"}`}>
            {/* Step 1 */}
            <div className="text-center">
              <div className="w-11 h-11 mx-auto mb-4 flex items-center justify-center text-brand-600 bg-brand-50 rounded-full">
                <IconUpload className="w-5 h-5" />
              </div>
              <p className="text-[15px] font-medium text-neutral-900 mb-1.5">Upload</p>
              <p className="text-[14px] text-neutral-400 leading-relaxed">Drop in any financial agreement PDF</p>
            </div>
            {/* Step 2 */}
            <div className="text-center">
              <div className="w-11 h-11 mx-auto mb-4 flex items-center justify-center text-brand-600 bg-brand-50 rounded-full">
                <IconAnnotate className="w-5 h-5" />
              </div>
              <p className="text-[15px] font-medium text-neutral-900 mb-1.5">AI Annotates</p>
              <p className="text-[14px] text-neutral-400 leading-relaxed">Key clauses highlighted with plain language explanations</p>
            </div>
            {/* Step 3 — visually distinct */}
            <div className="text-center">
              <div className={`mx-auto mb-4 flex items-center justify-center text-brand-700 bg-brand-100 rounded-full border-2 border-brand-200 ${isMobile ? "w-12 h-12" : "w-14 h-14"}`}>
                <IconDecide className={isMobile ? "w-6 h-6" : "w-7 h-7"} />
              </div>
              <p className="text-[16px] font-semibold text-neutral-900 mb-1.5">You Decide</p>
              <p className="text-[14px] text-neutral-500 leading-relaxed font-medium">You read, you ask questions, you make the call</p>
            </div>
          </div>
        </div>

        {/* Trust line */}
        <div className={`max-w-xl w-full text-center ${isMobile ? "mt-4 mb-10" : "mt-8 mb-16"}`}>
          <p className="text-[13px] text-neutral-400 leading-relaxed">
            Your documents are analyzed in real-time and never stored. AI annotations are for reference only — the original terms remain authoritative.
          </p>
        </div>
      </main>

      {/* Footer */}
      <footer className={`border-t border-neutral-100 text-center ${isMobile ? "py-4 px-4" : "py-6"}`}>
        <p className="text-[13px] text-neutral-400">Built as a demonstration of responsible AI design in financial services</p>
      </footer>
    </div>
  );
}

// ═══════════════════════════════════════════════════════════════
//  ANALYSIS PAGE
// ═══════════════════════════════════════════════════════════════

// ─── Navigation bar ──────────────────────────────────────────

function NavBar({ activeTab, setActiveTab, hasCompare, isMobile }) {
  return (
    <nav className={`flex items-center justify-between border-b border-neutral-100 bg-white flex-shrink-0 ${isMobile ? "px-4 py-3" : "px-8 py-4"}`}>
      <div className="flex items-center gap-3">
        <button onClick={() => window.__clearBack?.()} className="text-neutral-400 hover:text-neutral-700 transition-colors" title="New analysis">
          <IconArrow />
        </button>
        <span className={`font-semibold tracking-tight text-neutral-900 ${isMobile ? "text-[14px]" : "text-[16px]"}`}>ClearTerms</span>
      </div>
      {hasCompare && (
        <div className="flex items-center gap-1 bg-neutral-100 p-0.5">
          <button
            onClick={() => setActiveTab("analysis")}
            className={`py-1.5 text-[13px] font-medium transition-colors ${isMobile ? "px-3" : "px-4"} ${
              activeTab === "analysis" ? "bg-white text-neutral-900 shadow-sm" : "text-neutral-500 hover:text-neutral-700"
            }`}
          >Analysis</button>
          <button
            onClick={() => setActiveTab("compare")}
            className={`py-1.5 text-[13px] font-medium transition-colors ${isMobile ? "px-3" : "px-4"} ${
              activeTab === "compare" ? "bg-white text-neutral-900 shadow-sm" : "text-neutral-500 hover:text-neutral-700"
            }`}
          >Compare</button>
        </div>
      )}
    </nav>
  );
}

// ─── Document summary card ───────────────────────────────────

function SummaryCard({ overview, annotations, confStats, showOriginal, setShowOriginal, isMobile }) {
  const counts = useMemo(() => {
    const c = { HIGH: 0, MEDIUM: 0, LOW: 0 };
    (annotations || []).forEach(a => { const l = impactOf(a); if (c[l] !== undefined) c[l]++; });
    return c;
  }, [annotations]);

  return (
    <div className="flex-shrink-0">
      <div className={`bg-white border-b border-neutral-200 ${isMobile ? "px-4 py-3" : "px-8 py-4"}`}>
        {isMobile ? (
          /* ── Mobile layout: stacked ── */
          <div>
            <div className="flex items-center justify-between mb-2">
              <div className="flex-1 min-w-0">
                {overview?.type && (
                  <span className="text-[10px] font-semibold uppercase tracking-[0.15em] text-brand-700 bg-brand-50 px-2 py-0.5 inline-block mb-1">
                    {overview.type}
                  </span>
                )}
                {overview?.issuer && (
                  <p className="text-[16px] font-semibold text-neutral-900">{overview.issuer}</p>
                )}
              </div>
              {/* Impact counters — compact row */}
              <div className="flex items-center gap-2 flex-shrink-0">
                {[["HIGH", counts.HIGH, "bg-red-500", "text-red-700"], ["MEDIUM", counts.MEDIUM, "bg-amber-400", "text-amber-700"], ["LOW", counts.LOW, "bg-blue-500", "text-blue-700"]].map(([level, n, bg, textColor]) => (
                  <div key={level} className="flex flex-col items-center gap-0.5">
                    <div className={`w-7 h-7 rounded-full ${bg} flex items-center justify-center`}>
                      <span className="text-white text-[12px] font-bold">{n}</span>
                    </div>
                    <span className={`text-[9px] font-semibold uppercase tracking-wider ${textColor}`}>{level}</span>
                  </div>
                ))}
              </div>
            </div>
            {overview?.summary && (
              <p className="text-[13px] text-neutral-600 leading-relaxed mb-2">{overview.summary}</p>
            )}
            {confStats.total > 0 && (
              <p className="text-[11px] text-neutral-400 flex items-center gap-1.5 mb-2">
                <IconCheck className="w-3 h-3 text-brand-500" />
                {confStats.high} of {confStats.total} high confidence
              </p>
            )}
          </div>
        ) : (
          /* ── Desktop layout: horizontal ── */
          <div className="flex items-start gap-8">
            {/* Left: doc type + issuer */}
            <div className="flex-shrink-0">
              {overview?.type && (
                <span className="text-[11px] font-semibold uppercase tracking-[0.15em] text-brand-700 bg-brand-50 px-3 py-1 inline-block mb-2">
                  {overview.type}
                </span>
              )}
              {overview?.issuer && (
                <p className="text-[18px] font-semibold text-neutral-900">{overview.issuer}</p>
              )}
              {/* Confidence summary */}
              {confStats.total > 0 && (
                <p className="text-[12px] text-neutral-400 mt-2 flex items-center gap-1.5">
                  <IconCheck className="w-3.5 h-3.5 text-brand-500" />
                  {confStats.high} of {confStats.total} annotations are high confidence
                </p>
              )}
            </div>

            {/* Center: summary text */}
            <div className="flex-1 min-w-0">
              {overview?.summary && (
                <p className="text-[15px] text-neutral-600 leading-relaxed">{overview.summary}</p>
              )}
            </div>

            {/* Right: impact counters */}
            <div className="flex items-center gap-3 flex-shrink-0">
              {[["HIGH", counts.HIGH, "bg-red-500", "text-red-700"], ["MEDIUM", counts.MEDIUM, "bg-amber-400", "text-amber-700"], ["LOW", counts.LOW, "bg-blue-500", "text-blue-700"]].map(([level, n, bg, textColor]) => (
                <div key={level} className="flex flex-col items-center gap-1">
                  <div className={`w-9 h-9 rounded-full ${bg} flex items-center justify-center`}>
                    <span className="text-white text-[14px] font-bold">{n}</span>
                  </div>
                  <span className={`text-[10px] font-semibold uppercase tracking-wider ${textColor}`}>{level}</span>
                </div>
              ))}
            </div>
          </div>
        )}

        {/* Toggle: Show Original Only — compact placement */}
        <div className={`mt-2 pt-2 border-t border-neutral-100 flex items-center ${isMobile ? "justify-start" : "justify-between"}`}>
          <ToggleSwitch on={showOriginal} onToggle={() => setShowOriginal(v => !v)} label="Show Original Only" />
          {!isMobile && <p className="text-[12px] text-neutral-400 italic">AI is just a layer you can remove anytime</p>}
        </div>
      </div>

      {/* Low confidence banner */}
      {confStats.lowPct > 0.3 && (
        <div className={`low-confidence-banner flex items-center justify-center gap-2 ${isMobile ? "px-4 text-[12px]" : ""}`}>
          <IconWarning className="w-4 h-4 text-amber-600 flex-shrink-0" />
          <span>{isMobile ? "Consider professional review for this document type." : "This document type may be outside our expertise. We recommend professional review."}</span>
        </div>
      )}
    </div>
  );
}

// ─── Document panel (left 65%) ───────────────────────────────

function DocumentPanel({ text, annotations, active, onSelect, filter, showOriginal, isMobile }) {
  const refs = useRef({});

  useEffect(() => {
    if (active && refs.current[active]) {
      refs.current[active].scrollIntoView({ behavior: "smooth", block: "center" });
    }
  }, [active]);

  const positioned = useMemo(() => {
    let list = (annotations || []).filter(a => a.start >= 0 && a.end > a.start);
    const sorted = [...list].sort((a, b) => a.start - b.start);
    const clean = []; let end = 0;
    for (const a of sorted) { if (a.start >= end) { clean.push(a); end = a.end; } }
    return clean;
  }, [annotations]);

  const padCls = isMobile ? "px-4 py-5" : "px-16 py-10";

  if (showOriginal) {
    return (
      <div className={`h-full overflow-y-auto bg-white ${padCls}`}>
        <div className="doc-text max-w-3xl mx-auto">{text}</div>
      </div>
    );
  }

  const parts = [];
  let cursor = 0;
  for (const ann of positioned) {
    const level = impactOf(ann);
    const show = !filter || filter === level;
    if (ann.start > cursor) parts.push(<span key={`t${ann.id}`}>{text.slice(cursor, ann.start)}</span>);
    const isActive = active === ann.id;
    parts.push(
      <span
        key={ann.id}
        ref={el => refs.current[ann.id] = el}
        className={`${show ? IMPACT[level].hl : ""} ${isActive ? "active hl-active-ring" : ""}`}
        onClick={() => show && onSelect(ann.id)}
      >
        {text.slice(ann.start, ann.end)}
      </span>
    );
    cursor = ann.end;
  }
  if (cursor < text.length) parts.push(<span key="end">{text.slice(cursor)}</span>);

  return (
    <div className={`h-full overflow-y-auto bg-white ${padCls}`}>
      <div className="doc-text max-w-3xl mx-auto">{parts}</div>
    </div>
  );
}

// ─── Annotation card ─────────────────────────────────────────

function AnnotationCard({ ann, isActive, onClick, onReport, onFeedback }) {
  const level = impactOf(ann);
  const conf = confidenceOf(ann);
  const s = IMPACT[level];
  const cardRef = useRef(null);
  const [termsOpen, setTermsOpen] = useState(false);
  const [feedback, setFeedback] = useState(null); // "up" | "down" | null

  useEffect(() => {
    if (isActive && cardRef.current) {
      cardRef.current.scrollIntoView({ behavior: "smooth", block: "nearest" });
    }
  }, [isActive]);

  const handleFeedback = (type, e) => {
    e.stopPropagation();
    setFeedback(prev => prev === type ? null : type);
    if (onFeedback) onFeedback(ann.id, type);
  };

  const isLow = conf === "LOW";
  const borderClass = isActive ? `border-l-4 ${s.activeBorder}` : "border-l-4 border-l-transparent";
  const lowClass = isLow ? "card-low-confidence" : "";

  // Truncated explanation for collapsed state
  const truncated = ann.explanation && ann.explanation.length > 60 ? ann.explanation.slice(0, 60) + "..." : ann.explanation;

  return (
    <div
      ref={cardRef}
      onClick={onClick}
      className={`${borderClass} ${lowClass} border border-neutral-200 bg-white mx-4 my-3 px-5 py-4 cursor-pointer transition-all hover:border-neutral-300 ${
        isActive ? "border-neutral-300" : ""
      }`}
    >
      {/* Header: impact badge left, confidence right */}
      <div className="flex items-center justify-between mb-2">
        <span className={`text-[11px] font-semibold uppercase tracking-wider px-2.5 py-1 ${s.badge}`}>
          {s.label} impact
        </span>
        <span className="flex items-center gap-1">
          {conf === "HIGH" && <IconCheck className="w-4 h-4 text-green-500" />}
          {conf === "MEDIUM" && <IconTilde />}
          {conf === "LOW" && <IconWarning className="w-4 h-4 text-amber-500" />}
        </span>
      </div>

      {/* Collapsed state: truncated explanation */}
      {!isActive && (
        <p className={`text-[14px] leading-relaxed ${isLow ? "text-neutral-500 italic" : "text-neutral-700"}`}>
          {truncated}
        </p>
      )}

      {/* Expanded state */}
      <div className={`card-body ${isActive ? "open" : ""}`}>
        <div className="space-y-3">
          {/* Low confidence warning banner */}
          {isLow && (
            <div className="bg-amber-50 border border-dashed border-amber-300 px-3 py-2">
              <p className="text-[12px] text-amber-700">
                Low confidence — consider consulting a financial advisor about this clause
              </p>
            </div>
          )}

          {/* Full explanation */}
          <p className={`text-[14px] leading-relaxed ${isLow ? "text-neutral-500 italic" : "text-neutral-800"}`}>
            {ann.explanation}
          </p>

          {ann.impact_reason && (
            <p className="text-[13px] text-neutral-500 leading-relaxed">{ann.impact_reason}</p>
          )}

          {ann.estimated_impact && (
            <p className="text-[15px] font-semibold text-red-600">Potential impact: {ann.estimated_impact}</p>
          )}

          {/* Collapsible financial terms */}
          {ann.financial_terms && ann.financial_terms.length > 0 && (
            <div>
              <button
                onClick={(e) => { e.stopPropagation(); setTermsOpen(v => !v); }}
                className="text-[12px] font-medium text-brand-600 hover:text-brand-700 transition-colors flex items-center gap-1"
              >
                <svg className={`w-3 h-3 transition-transform ${termsOpen ? "rotate-90" : ""}`} fill="none" stroke="currentColor" strokeWidth={2} viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" d="M9 5l7 7-7 7"/>
                </svg>
                Terms explained ({ann.financial_terms.length})
              </button>
              {termsOpen && (
                <div className="mt-2 space-y-2 pl-4 border-l-2 border-brand-100">
                  {ann.financial_terms.map((ft, i) => (
                    <div key={i} className="text-[13px] leading-relaxed">
                      <span className="font-medium text-neutral-700">{ft.term}</span>
                      <span className="text-neutral-400"> — {ft.definition}</span>
                    </div>
                  ))}
                </div>
              )}
            </div>
          )}

          {ann.original_text && (
            <div className="text-[13px] text-neutral-400 italic border-l-2 border-neutral-200 pl-3 leading-relaxed">
              "{ann.original_text.length > 150 ? ann.original_text.slice(0, 150) + "..." : ann.original_text}"
            </div>
          )}

          {isLow && ann.confidence_note && (
            <p className="text-[13px] text-amber-600 italic leading-relaxed">{ann.confidence_note}</p>
          )}

          {/* Feedback + report row */}
          <div className="flex items-center justify-between pt-2 border-t border-neutral-100">
            <div className="flex items-center gap-2">
              <button
                onClick={(e) => handleFeedback("up", e)}
                className={`p-1.5 rounded transition-colors ${feedback === "up" ? "text-green-600 bg-green-50" : "text-neutral-400 hover:text-neutral-600"}`}
                title="Helpful"
              >
                <IconThumbUp className="w-3.5 h-3.5" filled={feedback === "up"} />
              </button>
              <button
                onClick={(e) => handleFeedback("down", e)}
                className={`p-1.5 rounded transition-colors ${feedback === "down" ? "text-red-500 bg-red-50" : "text-neutral-400 hover:text-neutral-600"}`}
                title="Not helpful"
              >
                <IconThumbDown className="w-3.5 h-3.5" filled={feedback === "down"} />
              </button>
            </div>
            <button
              onClick={(e) => { e.stopPropagation(); onReport(ann.id); }}
              className="flex items-center gap-1.5 text-[11px] text-neutral-400 hover:text-red-500 transition-colors"
              title="Report this annotation as inaccurate"
            >
              <IconFlag />
              Report inaccurate
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ─── Sidebar (35%) ───────────────────────────────────────────

function Sidebar({ annotations, active, onSelect, filter, setFilter, onReport, onFeedback }) {
  const filtered = useMemo(() => {
    let list = annotations || [];
    if (filter) list = list.filter(a => impactOf(a) === filter);
    return list;
  }, [annotations, filter]);

  const counts = useMemo(() => {
    const c = { HIGH: 0, MEDIUM: 0, LOW: 0 };
    (annotations || []).forEach(a => { const l = impactOf(a); if (c[l] !== undefined) c[l]++; });
    return c;
  }, [annotations]);

  return (
    <div className="h-full flex flex-col" style={{ background: "#FAFAFA" }}>
      {/* Header with filter pills */}
      <div className="px-5 py-4 border-b border-neutral-200 bg-white">
        <div className="flex items-center justify-between mb-3">
          <h2 className="text-[12px] font-semibold uppercase tracking-[0.15em] text-neutral-500">
            AI Annotations
          </h2>
          <span className="text-[12px] text-neutral-400">{filtered.length} items</span>
        </div>
        <div className="flex gap-1.5">
          <button
            onClick={() => setFilter(null)}
            className={`text-[11px] px-2.5 py-1 border transition-colors ${
              !filter ? "border-neutral-400 bg-neutral-100 font-medium text-neutral-800" : "border-neutral-200 text-neutral-500 hover:border-neutral-300"
            }`}
          >All</button>
          {[["HIGH", counts.HIGH, "bg-red-500"], ["MEDIUM", counts.MEDIUM, "bg-amber-500"], ["LOW", counts.LOW, "bg-blue-500"]].map(([level, n, dot]) => (
            <button
              key={level}
              onClick={() => setFilter(f => f === level ? null : level)}
              className={`flex items-center gap-1.5 text-[11px] px-2.5 py-1 border transition-colors ${
                filter === level ? "border-neutral-400 bg-neutral-100 font-medium text-neutral-800" : "border-neutral-200 text-neutral-500 hover:border-neutral-300"
              }`}
            >
              <span className={`w-1.5 h-1.5 rounded-full ${dot}`}></span>
              {n}
            </button>
          ))}
        </div>
      </div>

      {/* Cards */}
      <div className="flex-1 overflow-y-auto sidebar-scroll py-2">
        {filtered.length === 0 ? (
          <div className="p-8 text-center text-[14px] text-neutral-400">No annotations{filter ? " at this level" : ""}</div>
        ) : filtered.map(ann => (
          <AnnotationCard
            key={ann.id}
            ann={ann}
            isActive={active === ann.id}
            onClick={() => onSelect(ann.id)}
            onReport={onReport}
            onFeedback={onFeedback}
          />
        ))}
      </div>
    </div>
  );
}

// ─── Bottom: Hidden costs ────────────────────────────────────

function HiddenCostsSection({ costs, costAnns, active, onSelect, isMobile }) {
  if (!costs || costs.length === 0) return null;
  return (
    <div className={isMobile ? "py-5 px-4" : "py-8 px-8"}>
      <h3 className="text-[12px] font-semibold uppercase tracking-[0.15em] text-red-600 mb-4">Hidden Costs &amp; Risks</h3>
      <div className="grid grid-cols-1 gap-4 max-w-4xl">
        {costs.map((c, i) => {
          const ann = costAnns[i];
          return (
            <div
              key={i}
              onClick={() => ann && onSelect(ann.id)}
              className={`border border-neutral-200 bg-white cursor-pointer hover:border-neutral-300 transition-colors ${isMobile ? "p-4" : "p-5"} ${
                ann && active === ann.id ? "border-red-300 bg-red-50/30" : ""
              }`}
            >
              {c.original_text && (
                <blockquote className={`text-neutral-400 italic border-l-3 border-neutral-200 pl-3 mb-3 leading-relaxed ${isMobile ? "text-[12px]" : "text-[13px] pl-4"}`} style={{ borderLeftWidth: "3px" }}>
                  "{c.original_text.length > (isMobile ? 100 : 160) ? c.original_text.slice(0, isMobile ? 100 : 160) + "..." : c.original_text}"
                </blockquote>
              )}
              <p className="text-[14px] text-neutral-700 leading-relaxed mb-2">{c.what_it_means}</p>
              {c.estimated_impact && (
                <p className={`font-semibold text-red-600 ${isMobile ? "text-[14px]" : "text-[16px]"}`}>{c.estimated_impact}</p>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ─── Bottom: Questions ───────────────────────────────────────

function QuestionsSection({ questions, onScrollToClause, isMobile }) {
  if (!questions || questions.length === 0) return null;
  return (
    <div className={`bg-neutral-50 border-t border-neutral-100 ${isMobile ? "py-5 px-4" : "py-8 px-8"}`}>
      <h3 className="text-[12px] font-semibold uppercase tracking-[0.15em] text-brand-700 mb-4">Questions to Ask Before Signing</h3>
      <div className="space-y-4 max-w-4xl">
        {questions.map((q, i) => (
          <div key={i}>
            <p className={`font-medium text-neutral-800 leading-relaxed ${isMobile ? "text-[14px]" : "text-[16px]"}`}>{q.question}</p>
            <p className={`text-neutral-500 mt-1 leading-relaxed ${isMobile ? "text-[13px]" : "text-[14px]"}`}>{q.why_it_matters}</p>
            {q.related_clause && (
              <button
                onClick={() => onScrollToClause && onScrollToClause(q.related_clause)}
                className="text-[12px] text-brand-600 hover:text-brand-700 mt-1.5 transition-colors"
              >
                See {q.related_clause}
              </button>
            )}
          </div>
        ))}
      </div>
    </div>
  );
}

// ─── Compare feature: benchmark comparison ───────────────────

const BENCHMARKS = [
  { term: "Annual Management Fee",   field: "mgmt_fee",    typicalRange: "0.50% – 1.00%",     source: "industry average" },
  { term: "Early Termination Fee",   field: "term_fee",    typicalRange: "0% – 2%",            source: "industry average" },
  { term: "Per-Trade Fee",           field: "trade_fee",   typicalRange: "$0 – $9.99",         source: "major brokerages" },
  { term: "Credit Card APR",         field: "apr",         typicalRange: "19.99% – 22.99%",    source: "CFPB data" },
  { term: "Annual Card Fee",         field: "annual_fee",  typicalRange: "$0 – $120",          source: "Canadian market" },
  { term: "Foreign Transaction Fee", field: "fx_fee",      typicalRange: "2.5%",               source: "industry standard" },
  { term: "Late Payment Fee",        field: "late_fee",    typicalRange: "$25 – $29",          source: "CFPB data" },
];

function extractTermValues(annotations, hiddenCosts, overview) {
  const vals = {};
  const allText = [
    ...(annotations || []).map(a => (a.explanation || "") + " " + (a.original_text || "") + " " + (a.estimated_impact || "")),
    ...(hiddenCosts || []).map(c => (c.what_it_means || "") + " " + (c.estimated_impact || "") + " " + (c.original_text || "")),
  ].join(" ");

  // Management fee
  const mgmt = allText.match(/(?:management fee|annual fee).*?(\d+\.?\d*)%/i);
  if (mgmt) vals.mgmt_fee = mgmt[1] + "%";

  // Early termination
  const term = allText.match(/(?:early termination|penalty fee|termination.*penalty).*?(\d+\.?\d*)%/i);
  if (term) vals.term_fee = term[1] + "%";

  // Per trade fee
  const trade = allText.match(/\$(\d+\.?\d*)\s*(?:per trade|\/trade)/i);
  if (trade) vals.trade_fee = "$" + trade[1];

  // APR
  const apr = allText.match(/(?:APR|annual percentage rate).*?(\d+\.?\d*)%/i);
  if (apr) vals.apr = apr[1] + "%";

  // Annual card fee
  const annual = allText.match(/(?:annual fee|yearly fee|card fee).*?\$(\d+\.?\d*)/i);
  if (annual) vals.annual_fee = "$" + annual[1];

  // Foreign transaction
  const fx = allText.match(/(?:foreign transaction|currency conversion).*?(\d+\.?\d*)%/i);
  if (fx) vals.fx_fee = fx[1] + "%";

  // Late payment
  const late = allText.match(/(?:late payment|late fee).*?\$(\d+\.?\d*)/i);
  if (late) vals.late_fee = "$" + late[1];

  return vals;
}

function assessTerm(field, value, typicalRange) {
  if (!value) return null;
  const num = parseFloat(value.replace(/[$%,]/g, ""));
  if (isNaN(num)) return null;

  // Parse range
  const rangeMatch = typicalRange.match(/([\d.]+)(?:\s*[–\-]\s*([\d.]+))?/);
  if (!rangeMatch) return null;
  const lo = parseFloat(rangeMatch[1]);
  const hi = rangeMatch[2] ? parseFloat(rangeMatch[2]) : lo;

  if (num < lo) return { label: "Better than average", color: "text-green-700 bg-green-50" };
  if (num <= hi) return { label: "Typical", color: "text-neutral-600 bg-neutral-100" };
  return { label: "Worth asking about", color: "text-amber-700 bg-amber-50" };
}

function CompareView({ annotations, hiddenCosts, overview, isMobile }) {
  const values = useMemo(() => extractTermValues(annotations, hiddenCosts, overview), [annotations, hiddenCosts, overview]);

  const rows = BENCHMARKS.filter(b => values[b.field]).map(b => ({
    ...b,
    thisAgreement: values[b.field],
    assessment: assessTerm(b.field, values[b.field], b.typicalRange),
  }));

  if (rows.length === 0) {
    return (
      <div className={`flex-1 flex items-center justify-center ${isMobile ? "p-6" : "p-12"}`}>
        <div className="text-center max-w-md">
          <p className="text-[15px] text-neutral-500 mb-2">No comparable terms detected in this agreement.</p>
          <p className="text-[13px] text-neutral-400">The compare feature works best with credit card agreements, investment management contracts, and loan documents.</p>
        </div>
      </div>
    );
  }

  if (isMobile) {
    /* ── Mobile: card-based layout instead of table ── */
    return (
      <div className="flex-1 overflow-y-auto p-4">
        <div className="mb-5">
          <h2 className="text-[16px] font-semibold text-neutral-900 mb-1">How does this compare?</h2>
          <p className="text-[13px] text-neutral-500 leading-relaxed">Terms vs. industry benchmarks.</p>
        </div>

        <div className="space-y-3">
          {rows.map((row, i) => (
            <div key={i} className="border border-neutral-200 bg-white p-4">
              <p className="text-[13px] font-medium text-neutral-800 mb-2">{row.term}</p>
              <div className="flex items-center justify-between mb-1.5">
                <span className="text-[12px] text-neutral-500">This Agreement</span>
                <span className="text-[14px] font-semibold text-neutral-900">{row.thisAgreement}</span>
              </div>
              <div className="flex items-center justify-between mb-2">
                <span className="text-[12px] text-neutral-500">Typical Range</span>
                <span className="text-[13px] text-neutral-500">{row.typicalRange}</span>
              </div>
              {row.assessment && (
                <span className={`text-[11px] font-medium px-2.5 py-1 inline-block ${row.assessment.color}`}>
                  {row.assessment.label}
                </span>
              )}
            </div>
          ))}
        </div>

        <div className="mt-4 px-3 py-3 bg-neutral-50 border border-neutral-100">
          <p className="text-[11px] text-neutral-400 leading-relaxed">
            Benchmarks from CFPB and Canadian financial regulators. For informational purposes only.
          </p>
        </div>
      </div>
    );
  }

  return (
    <div className="flex-1 overflow-y-auto p-8">
      <div className="max-w-4xl mx-auto">
        <div className="mb-8">
          <h2 className="text-[18px] font-semibold text-neutral-900 mb-2">How does this agreement compare?</h2>
          <p className="text-[14px] text-neutral-500 leading-relaxed">We compared the terms in this agreement against common industry benchmarks.</p>
        </div>

        {/* Table */}
        <div className="border border-neutral-200 overflow-hidden">
          {/* Header */}
          <div className="grid grid-cols-4 bg-neutral-50 border-b border-neutral-200">
            <div className="px-5 py-3 text-[11px] font-semibold uppercase tracking-[0.15em] text-neutral-500">Term</div>
            <div className="px-5 py-3 text-[11px] font-semibold uppercase tracking-[0.15em] text-neutral-500">This Agreement</div>
            <div className="px-5 py-3 text-[11px] font-semibold uppercase tracking-[0.15em] text-neutral-500">Typical Range</div>
            <div className="px-5 py-3 text-[11px] font-semibold uppercase tracking-[0.15em] text-neutral-500">Assessment</div>
          </div>
          {/* Rows */}
          {rows.map((row, i) => (
            <div key={i} className={`grid grid-cols-4 items-center ${i < rows.length - 1 ? "border-b border-neutral-100" : ""}`}>
              <div className="px-5 py-4">
                <p className="text-[14px] font-medium text-neutral-800">{row.term}</p>
              </div>
              <div className="px-5 py-4">
                <p className="text-[15px] font-semibold text-neutral-900">{row.thisAgreement}</p>
              </div>
              <div className="px-5 py-4">
                <p className="text-[14px] text-neutral-500">{row.typicalRange}</p>
              </div>
              <div className="px-5 py-4">
                {row.assessment ? (
                  <span className={`text-[12px] font-medium px-3 py-1.5 inline-block ${row.assessment.color}`}>
                    {row.assessment.label}
                  </span>
                ) : (
                  <span className="text-[12px] text-neutral-400">—</span>
                )}
              </div>
            </div>
          ))}
        </div>

        {/* Disclaimer note */}
        <div className="mt-6 px-5 py-4 bg-neutral-50 border border-neutral-100">
          <p className="text-[12px] text-neutral-400 leading-relaxed">
            Benchmarks based on publicly available data from CFPB and Canadian financial regulators. Your individual circumstances may affect what's "good" for you. This comparison is for informational purposes only and does not constitute financial advice.
          </p>
        </div>
      </div>
    </div>
  );
}

// ═══════════════════════════════════════════════════════════════
//  LOADING VIEW
// ═══════════════════════════════════════════════════════════════

function LoadingView() {
  return (
    <div className="flex items-center justify-center h-screen bg-white">
      <div className="text-center landing-fade-in">
        <div className="animate-spin inline-block w-8 h-8 border-2 border-neutral-200 border-t-brand-600 rounded-full mb-6"></div>
        <p className="text-[17px] font-medium text-neutral-900">Analyzing your agreement</p>
        <p className="text-[14px] text-neutral-400 mt-1.5">This may take 15&ndash;30 seconds</p>
      </div>
    </div>
  );
}

// ═══════════════════════════════════════════════════════════════
//  APP
// ═══════════════════════════════════════════════════════════════

function App() {
  const [text, setText] = useState("");
  const [analysis, setAnalysis] = useState(null);
  const [annotations, setAnnotations] = useState([]);
  const [active, setActive] = useState(null);
  const [filter, setFilter] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [view, setView] = useState("input");
  const [showOriginal, setShowOriginal] = useState(false);
  const [activeTab, setActiveTab] = useState("analysis");

  // Mobile: switch between document and annotations panel
  const [mobilePanel, setMobilePanel] = useState("document"); // "document" | "annotations"
  const isMobile = useIsMobile();

  const [toast, setToast] = useState({ visible: false, fading: false, message: "" });
  const toastTimer = useRef(null);
  const mainScrollRef = useRef(null);

  // Resizable vertical split: mainRatio = fraction of available height for main content
  const [mainRatio, setMainRatio] = useState(0.75);
  const containerRef = useRef(null);
  const ratioAtDragStart = useRef(0.75);

  // Resizable horizontal split: colRatio = fraction of width for left (document) panel
  const [colRatio, setColRatio] = useState(0.65);
  const colRatioAtDragStart = useRef(0.65);
  const splitRowRef = useRef(null);

  // On mouse down on the horizontal (row-resize) handle
  const onHandleMouseDown = useCallback((e) => {
    e.preventDefault();
    ratioAtDragStart.current = mainRatio;
    const startY = e.clientY;
    const containerH = containerRef.current?.offsetHeight || 1;
    const onMouseMove = (ev) => {
      const delta = ev.clientY - startY;
      const newRatio = ratioAtDragStart.current + (delta / containerH);
      const minBottom = 100 / containerH;
      const clamped = Math.max(0.5, Math.min(1 - minBottom, newRatio));
      setMainRatio(clamped);
    };
    const onMouseUp = () => {
      document.removeEventListener("mousemove", onMouseMove);
      document.removeEventListener("mouseup", onMouseUp);
      document.body.style.cursor = "";
      document.body.style.userSelect = "";
    };
    document.body.style.cursor = "row-resize";
    document.body.style.userSelect = "none";
    document.addEventListener("mousemove", onMouseMove);
    document.addEventListener("mouseup", onMouseUp);
  }, [mainRatio]);

  // On mouse down on the vertical (col-resize) handle
  const onColHandleMouseDown = useCallback((e) => {
    e.preventDefault();
    colRatioAtDragStart.current = colRatio;
    const startX = e.clientX;
    const rowW = splitRowRef.current?.offsetWidth || 1;
    const onMouseMove = (ev) => {
      const delta = ev.clientX - startX;
      const newRatio = colRatioAtDragStart.current + (delta / rowW);
      const clamped = Math.max(0.4, Math.min(0.75, newRatio));
      setColRatio(clamped);
    };
    const onMouseUp = () => {
      document.removeEventListener("mousemove", onMouseMove);
      document.removeEventListener("mouseup", onMouseUp);
      document.body.style.cursor = "";
      document.body.style.userSelect = "";
    };
    document.body.style.cursor = "col-resize";
    document.body.style.userSelect = "none";
    document.addEventListener("mousemove", onMouseMove);
    document.addEventListener("mouseup", onMouseUp);
  }, [colRatio]);

  const showToast = useCallback((message) => {
    if (toastTimer.current) clearTimeout(toastTimer.current);
    setToast({ visible: true, fading: false, message });
    toastTimer.current = setTimeout(() => {
      setToast(t => ({ ...t, fading: true }));
      setTimeout(() => setToast({ visible: false, fading: false, message: "" }), 200);
    }, 2500);
  }, []);

  const handleReport = useCallback((annotationId) => {
    console.log(`[ClearTerms] Annotation reported as inaccurate: ${annotationId}`, {
      annotationId,
      timestamp: new Date().toISOString(),
      documentType: analysis?.overview?.type || "unknown",
    });
    showToast("Thank you — this helps improve accuracy");
  }, [analysis, showToast]);

  const handleFeedback = useCallback((annotationId, type) => {
    console.log(`[ClearTerms] Annotation feedback: ${type}`, {
      annotationId,
      feedback: type,
      timestamp: new Date().toISOString(),
      documentType: analysis?.overview?.type || "unknown",
    });
    showToast("Thanks — your feedback helps improve accuracy");
  }, [analysis, showToast]);

  const confStats = useMemo(() => {
    const total = (annotations || []).length;
    const high = (annotations || []).filter(a => confidenceOf(a) === "HIGH").length;
    const low = (annotations || []).filter(a => confidenceOf(a) === "LOW").length;
    return { total, high, low, lowPct: total > 0 ? low / total : 0 };
  }, [annotations]);

  window.__clearBack = () => { setView("input"); setAnalysis(null); setAnnotations([]); setActive(null); setFilter(null); setError(null); setShowOriginal(false); setActiveTab("analysis"); setMainRatio(0.75); setColRatio(0.65); setMobilePanel("document"); };

  const handleAnalyze = async (inputText) => {
    setText(inputText);
    setView("loading");
    setLoading(true);
    setError(null);
    setAnalysis(null);
    setAnnotations([]);
    setActive(null);
    setFilter(null);
    setShowOriginal(false);
    setActiveTab("analysis");
    setMainRatio(0.75);
    setColRatio(0.65);
    try {
      const result = await analyzeText(inputText);
      setAnalysis(result);
      setAnnotations(result.annotations || []);
      setView("results");
    } catch (e) {
      setError(e.message);
      setView("input");
    } finally {
      setLoading(false);
    }
  };

  const handleTestMock = () => {
    setView("loading");
    setLoading(true);
    setError(null);
    // Use hardcoded demo data — no API call needed
    setTimeout(() => {
      setText(DEMO_DATA.text);
      setAnalysis(DEMO_DATA);
      setAnnotations(DEMO_DATA.annotations || []);
      setView("results");
      setLoading(false);
    }, 600);
  };

  const toggle = (id) => setActive(prev => prev === id ? null : id);

  const scrollDocToTop = () => {
    if (mainScrollRef.current) {
      mainScrollRef.current.scrollTo({ top: 0, behavior: "smooth" });
    }
  };

  // ── Input ──
  if (view === "input") {
    return (
      <div>
        <InputView onAnalyze={handleAnalyze} analyzing={loading} onTestMock={handleTestMock} />
        {error && (
          <div className="fixed bottom-6 left-1/2 -translate-x-1/2 px-5 py-2.5 bg-red-600 text-white text-[14px] z-50">
            {error}
          </div>
        )}
      </div>
    );
  }

  // ── Loading ──
  if (view === "loading") return <LoadingView />;

  // ── Results ──
  const costAnns = (annotations || []).filter(a => a.section === "HIDDEN_COSTS");
  const hasBottomSections = !showOriginal && (analysis?.hidden_costs?.length > 0 || analysis?.questions?.length > 0);

  /* ── Mobile results layout ── */
  if (isMobile) {
    return (
      <div className="flex flex-col h-screen bg-white">
        <NavBar activeTab={activeTab} setActiveTab={setActiveTab} hasCompare={true} isMobile={true} />

        <SummaryCard
          overview={analysis?.overview}
          annotations={annotations}
          confStats={confStats}
          showOriginal={showOriginal}
          setShowOriginal={setShowOriginal}
          isMobile={true}
        />

        {activeTab === "compare" ? (
          <CompareView annotations={annotations} hiddenCosts={analysis?.hidden_costs} overview={analysis?.overview} isMobile={true} />
        ) : (
          <React.Fragment>
            {/* Mobile panel tabs — switch between Document / Annotations */}
            {!showOriginal && (
              <div className="flex border-b border-neutral-200 bg-white flex-shrink-0">
                <button
                  onClick={() => setMobilePanel("document")}
                  className={`flex-1 py-2.5 text-[13px] font-medium text-center transition-colors ${
                    mobilePanel === "document" ? "text-brand-700 border-b-2 border-brand-600" : "text-neutral-500"
                  }`}
                >Document</button>
                <button
                  onClick={() => setMobilePanel("annotations")}
                  className={`flex-1 py-2.5 text-[13px] font-medium text-center transition-colors ${
                    mobilePanel === "annotations" ? "text-brand-700 border-b-2 border-brand-600" : "text-neutral-500"
                  }`}
                >
                  Annotations ({(annotations || []).length})
                </button>
              </div>
            )}

            {/* Mobile panel content — full height */}
            <div className="flex-1 overflow-y-auto" ref={mainScrollRef}>
              {showOriginal || mobilePanel === "document" ? (
                <React.Fragment>
                  <DocumentPanel text={text} annotations={annotations} active={active} onSelect={(id) => { toggle(id); if (!showOriginal) setMobilePanel("annotations"); }} filter={filter} showOriginal={showOriginal} isMobile={true} />
                </React.Fragment>
              ) : (
                <React.Fragment>
                  <Sidebar annotations={annotations} active={active} onSelect={(id) => { toggle(id); }} filter={filter} setFilter={setFilter} onReport={handleReport} onFeedback={handleFeedback} />
                  {/* Bottom sections inline below annotations */}
                  <HiddenCostsSection costs={analysis?.hidden_costs} costAnns={costAnns} active={active} onSelect={toggle} isMobile={true} />
                  <QuestionsSection questions={analysis?.questions} onScrollToClause={scrollDocToTop} isMobile={true} />
                </React.Fragment>
              )}
            </div>
          </React.Fragment>
        )}

        {/* Disclaimer — always visible */}
        <div className="disclaimer-bar" style={isMobile ? { fontSize: "11px", padding: "8px 16px" } : {}}>
          AI annotations are for reference only — the original terms remain authoritative.
        </div>

        <Toast message={toast.message} visible={toast.visible} fading={toast.fading} />
      </div>
    );
  }

  /* ── Desktop results layout ── */
  return (
    <div className="flex flex-col h-screen bg-white">
      <NavBar activeTab={activeTab} setActiveTab={setActiveTab} hasCompare={true} isMobile={false} />

      <SummaryCard
        overview={analysis?.overview}
        annotations={annotations}
        confStats={confStats}
        showOriginal={showOriginal}
        setShowOriginal={setShowOriginal}
        isMobile={false}
      />

      {activeTab === "compare" ? (
        <CompareView annotations={annotations} hiddenCosts={analysis?.hidden_costs} overview={analysis?.overview} isMobile={false} />
      ) : (
        <React.Fragment>
          {/* Resizable container for main + bottom */}
          <div className="flex-1 flex flex-col overflow-hidden" ref={containerRef}>
            {/* Main: 65/35 split — takes mainRatio of container */}
            <div className="flex overflow-hidden" style={{ height: hasBottomSections ? `${mainRatio * 100}%` : "100%" }} ref={splitRowRef}>
              {/* Left: original document (PRIMARY) */}
              <div className="overflow-hidden" style={{ width: showOriginal ? "100%" : `${colRatio * 100}%` }}>
                <DocumentPanel text={text} annotations={annotations} active={active} onSelect={toggle} filter={filter} showOriginal={showOriginal} isMobile={false} />
              </div>
              {/* Vertical drag handle — thin line, Cursor IDE style */}
              {!showOriginal && (
                <div
                  onMouseDown={onColHandleMouseDown}
                  className="flex-shrink-0 cursor-col-resize select-none transition-all duration-150"
                  style={{ width: 1, background: '#E5E7EB' }}
                  title="Drag to resize panels"
                  onMouseEnter={e => { e.currentTarget.style.width = '3px'; e.currentTarget.style.background = '#D1D5DB'; }}
                  onMouseLeave={e => { e.currentTarget.style.width = '1px'; e.currentTarget.style.background = '#E5E7EB'; }}
                />
              )}
              {/* Right: AI annotations (SECONDARY) */}
              {!showOriginal && (
                <div className="overflow-hidden" style={{ width: `${(1 - colRatio) * 100}%` }}>
                  <Sidebar annotations={annotations} active={active} onSelect={toggle} filter={filter} setFilter={setFilter} onReport={handleReport} onFeedback={handleFeedback} />
                </div>
              )}
            </div>

            {/* Drag handle + bottom sections */}
            {hasBottomSections && (
              <React.Fragment>
                {/* Drag handle — thin line, Cursor IDE style */}
                <div
                  onMouseDown={onHandleMouseDown}
                  className="flex-shrink-0 cursor-row-resize select-none transition-all duration-150"
                  style={{ height: 1, background: '#E5E7EB' }}
                  title="Drag to resize"
                  onMouseEnter={e => { e.currentTarget.style.height = '3px'; e.currentTarget.style.background = '#D1D5DB'; }}
                  onMouseLeave={e => { e.currentTarget.style.height = '1px'; e.currentTarget.style.background = '#E5E7EB'; }}
                />

                {/* Bottom sections — scrollable within allocated space */}
                <div className="overflow-y-auto flex-1 min-h-[100px]" ref={mainScrollRef}>
                  <HiddenCostsSection costs={analysis?.hidden_costs} costAnns={costAnns} active={active} onSelect={toggle} isMobile={false} />
                  <QuestionsSection questions={analysis?.questions} onScrollToClause={scrollDocToTop} isMobile={false} />
                </div>
              </React.Fragment>
            )}
          </div>
        </React.Fragment>
      )}

      {/* Disclaimer — always visible */}
      <div className="disclaimer-bar">
        ClearTerms helps you understand financial documents. It does not provide legal or financial advice. AI annotations are for reference only — the original terms remain authoritative.
      </div>

      <Toast message={toast.message} visible={toast.visible} fading={toast.fading} />
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
