// ============================================
// Reliq — All Scans
// ============================================

const ALL_SCANS = [
  // Website scan (platform expansion) — renders alongside mobile scans.
  // `kind:"website"` plus the multi-dimension scores surface the new scan type.
  { id:"scn_web1", app:"acme.com", letters:"A", grad:"linear-gradient(135deg,#00D4AA,#5B9DFF)",
    version:"—", build:"—", bundle:"https://acme.com", primaryRisk:"Agent readiness",
    stores:[], score:81, verdict:"pass",
    kind:"website", targetUrl:"https://acme.com",
    overallScore:81, releaseScore:70, securityScore:100, agentScore:78, apiScore:67, docsScore:80, vendorScore:62, mcpScore:58, privacyScore:54,
    crit:0, warn:3, info:2, date:"2026-06-20 09:00", duration:"4s", source:"manual" },
  { id:"scn_2k8x", app:"Roamly",       letters:"R", grad:"linear-gradient(135deg,#5B9DFF,#A78BFA)",
    version:"1.4.0", build:"142", bundle:"com.roamly.app", primaryRisk:"Privacy",
    stores:["play","app"], score:78, verdict:"needs_fixes",
    crit:1, warn:4, info:3, date:"2026-05-22 14:32", duration:"2m 14s", source:"github" },
  { id:"scn_2k8r", app:"Roamly",       letters:"R", grad:"linear-gradient(135deg,#5B9DFF,#A78BFA)",
    version:"1.4.0", build:"141", bundle:"com.roamly.app", primaryRisk:"Privacy",
    stores:["play","app"], score:74, verdict:"needs_fixes",
    crit:1, warn:6, info:2, date:"2026-05-22 12:18", duration:"2m 09s", source:"ci" },
  { id:"scn_2k8w", app:"QuickInvoice",  letters:"Q", grad:"linear-gradient(135deg,#F59E0B,#EF4444)",
    version:"2.1.3", build:"87",  bundle:"com.quickinvoice.android", primaryRisk:"Permissions",
    stores:["play"], score:41, verdict:"will_reject",
    crit:3, warn:8, info:2, date:"2026-05-22 11:14", duration:"1m 58s", source:"manual" },
  { id:"scn_2k8v", app:"MoodBoard AI",  letters:"M", grad:"linear-gradient(135deg,#A78BFA,#EF4444)",
    version:"0.9.2", build:"28",  bundle:"com.moodboard.ai", primaryRisk:"Privacy Manifest",
    stores:["play","app"], score:64, verdict:"needs_fixes",
    crit:1, warn:5, info:3, date:"2026-05-22 09:45", duration:"2m 31s", source:"github" },
  { id:"scn_2k8u", app:"TidalFlow",     letters:"T", grad:"linear-gradient(135deg,#00D4AA,#5B9DFF)",
    version:"3.0.1", build:"201", bundle:"com.tidalflow.app", primaryRisk:"Store Listing",
    stores:["app"], score:88, verdict:"pass",
    crit:0, warn:2, info:1, date:"2026-05-21 16:42", duration:"1m 44s", source:"api" },
  { id:"scn_2k8t", app:"Pocket Coach",  letters:"P", grad:"linear-gradient(135deg,#5B9DFF,#00D4AA)",
    version:"1.0.0", build:"12",  bundle:"com.pocket.coach", primaryRisk:"Content Policy",
    stores:["play","app"], score:76, verdict:"likely_pass",
    crit:0, warn:3, info:2, date:"2026-05-21 09:11", duration:"2m 08s", source:"manual" },
  { id:"scn_2k8s", app:"Brewline",      letters:"B", grad:"linear-gradient(135deg,#F59E0B,#A78BFA)",
    version:"4.2.1", build:"312", bundle:"com.brewline.app", primaryRisk:"Security",
    stores:["play"], score:95, verdict:"pass",
    crit:0, warn:0, info:1, date:"2026-05-20 14:20", duration:"1m 52s", source:"ci" },
  { id:"scn_2k8q", app:"QuickInvoice",  letters:"Q", grad:"linear-gradient(135deg,#F59E0B,#EF4444)",
    version:"2.0.8", build:"80",  bundle:"com.quickinvoice.android", primaryRisk:"Permissions",
    stores:["play"], score:68, verdict:"needs_fixes",
    crit:1, warn:4, info:2, date:"2026-05-18 17:30", duration:"1m 55s", source:"manual" },
  { id:"scn_2k8p", app:"MoodBoard AI",  letters:"M", grad:"linear-gradient(135deg,#A78BFA,#EF4444)",
    version:"0.9.1", build:"25",  bundle:"com.moodboard.ai", primaryRisk:"Privacy Manifest",
    stores:["play","app"], score:58, verdict:"will_reject",
    crit:2, warn:7, info:1, date:"2026-05-17 10:05", duration:"2m 44s", source:"github" },
  { id:"scn_2k8o", app:"TidalFlow",     letters:"T", grad:"linear-gradient(135deg,#00D4AA,#5B9DFF)",
    version:"2.9.8", build:"196", bundle:"com.tidalflow.app", primaryRisk:"Store Listing",
    stores:["app"], score:81, verdict:"likely_pass",
    crit:0, warn:3, info:0, date:"2026-05-15 09:22", duration:"1m 41s", source:"api" },
];

const UNIQUE_APPS = [...new Set(ALL_SCANS.map(s => s.app))];

const SOURCE_META = {
  github: { label:"GitHub", icon:"github" },
  ci:     { label:"CI/CD",  icon:"refresh" },
  manual: { label:"Manual", icon:"upload" },
  api:    { label:"API",    icon:"code" },
};

const AllScans = ({ go }) => {
  const [search, setSearch]               = React.useState("");
  const [filterApp, setFilterApp]         = React.useState("all");
  const [filterStore, setFilterStore]     = React.useState("all");
  const [filterVerdict, setFilterVerdict] = React.useState("all");
  const [filterSeverity, setFilterSeverity] = React.useState("all");
  const [filterDate, setFilterDate]       = React.useState("all");
  const [filterSource, setFilterSource]   = React.useState("all");
  const [filterScore, setFilterScore]     = React.useState("all");
  // Column sort — key: "app"|"score"|"date"|"crit", dir: "asc"|"desc"
  const [sortKey, setSortKey]             = React.useState("date");
  const [sortDir, setSortDir]             = React.useState("desc");

  const [copiedId, setCopiedId]           = React.useState(null);

  // Feature gates — null-safe: default true so UI works in preview contexts
  const canShare  = window.reliqGates ? window.reliqGates.canShareReport()  : true;
  const canExport = window.reliqGates ? window.reliqGates.canExportReport() : true;
  const canRescan = window.reliqGates ? window.reliqGates.canRescan()       : true;

  const shareLink = (id, e) => {
    e.stopPropagation();
    if (!canShare) {
      window.reliqGatePrompt?.show({ title:"Share link requires Starter plan", description:"Upgrade to share scan results with a public link.", planRequired:"starter", go });
      return;
    }
    setCopiedId(id);
    setTimeout(() => setCopiedId(null), 2000);
    window.reliqToast?.success("Share link copied to clipboard");
  };

  const handleExport = (e) => {
    e && e.stopPropagation();
    if (!canExport) {
      window.reliqGatePrompt?.show({ title:"Export requires Starter plan", description:"Upgrade to export scan tables as CSV.", planRequired:"starter", go });
      return;
    }
    exportCSV();
  };

  const handleRescan = (id, e) => {
    e.stopPropagation();
    if (!canRescan) {
      window.reliqGatePrompt?.show({ title:"Re-scan requires Starter plan", description:"Upgrade to re-run scans on updated builds.", planRequired:"starter", go });
      return;
    }
    go("/scan/new");
  };

  const cycleSort = (key) => {
    if (sortKey === key) setSortDir(d => d === "asc" ? "desc" : "asc");
    else { setSortKey(key); setSortDir("desc"); }
  };
  const SortIcon = ({ col }) => {
    if (sortKey !== col) return <span style={{color:"var(--fg-3)",marginLeft:4,fontSize:10}}>↕</span>;
    return <span style={{color:"var(--teal)",marginLeft:4,fontSize:10}}>{sortDir==="asc"?"↑":"↓"}</span>;
  };

  const filtered = ALL_SCANS.filter(s => {
    if (search && !s.app.toLowerCase().includes(search.toLowerCase()) &&
        !s.bundle.toLowerCase().includes(search.toLowerCase()) &&
        !s.id.toLowerCase().includes(search.toLowerCase()) &&
        !s.version.toLowerCase().includes(search.toLowerCase()) &&
        !s.build.includes(search)) return false;
    if (filterApp !== "all" && s.app !== filterApp) return false;
    if (filterStore !== "all" && !s.stores.includes(filterStore)) return false;
    if (filterVerdict !== "all" && s.verdict !== filterVerdict) return false;
    if (filterSeverity === "critical" && s.crit === 0) return false;
    if (filterSeverity === "warning" && s.warn === 0) return false;
    if (filterDate === "7d" && s.date < "2026-05-16") return false;
    if (filterDate === "30d" && s.date < "2026-04-23") return false;
    if (filterDate === "today" && !s.date.startsWith("2026-05-23")) return false;
    if (filterSource !== "all" && s.source !== filterSource) return false;
    if (filterScore === "high" && s.score < 80) return false;
    if (filterScore === "medium" && (s.score < 60 || s.score >= 80)) return false;
    if (filterScore === "low" && s.score >= 60) return false;
    return true;
  }).sort((a, b) => {
    let av, bv;
    if (sortKey === "score")  { av = a.score;  bv = b.score; }
    else if (sortKey === "app") { av = a.app.toLowerCase(); bv = b.app.toLowerCase(); }
    else if (sortKey === "crit") { av = a.crit;  bv = b.crit; }
    else { av = a.date; bv = b.date; } // default: date
    if (av < bv) return sortDir === "asc" ? -1 : 1;
    if (av > bv) return sortDir === "asc" ? 1 : -1;
    return 0;
  });

  const exportCSV = () => {
    const headers = ["Scan ID","App","Bundle","Version","Build","Stores","Verdict","Score","Critical","Warnings","Info","Source","Date","Duration"];
    const rows = filtered.map(s => [
      s.id, s.app, s.bundle, `v${s.version}`, `build ${s.build}`,
      s.stores.map(st => st === "play" ? "Google Play" : "Apple App Store").join(" + "),
      s.verdict, s.score, s.crit, s.warn, s.info,
      SOURCE_META[s.source]?.label || s.source,
      s.date, s.duration
    ]);
    const csv = [headers, ...rows].map(r => r.map(v => `"${v}"`).join(",")).join("\n");
    const blob = new Blob([csv], { type:"text/csv" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url; a.download = "reliq-scans.csv"; a.click();
    URL.revokeObjectURL(url);
  };

  const clearFilters = () => {
    setSearch(""); setFilterApp("all"); setFilterStore("all");
    setFilterVerdict("all"); setFilterSeverity("all"); setFilterDate("all");
    setFilterSource("all"); setFilterScore("all");
  };

  const hasFilters = search || filterApp !== "all" || filterStore !== "all" ||
    filterVerdict !== "all" || filterSeverity !== "all" || filterDate !== "all" ||
    filterSource !== "all" || filterScore !== "all";

  const selStyle = {
    background:"var(--bg-1)", border:"1px solid var(--line-2)",
    borderRadius:"var(--r-sm)", padding:"0 10px",
    height:34, boxSizing:"border-box",
    fontSize:13, color:"var(--fg-0)", outline:"none", cursor:"pointer",
    flexShrink:0
  };

  return (
    <AuthLayout
      route="scans"
      go={go}
      crumbs={["Workspace", "All Scans"]}
      actions={
        <button className="btn btn-primary btn-sm" onClick={() => go("/scan/new")}>
          <Icon name="plus" size={13} /> New Scan
        </button>
      }
    >
          <div className="page-head">
            <div>
              <h1 className="page-title">All Scans</h1>
              <p className="page-sub">Scan history across every app, build, and target store.</p>
            </div>
            <button className="btn btn-sm" onClick={handleExport}>
              <Icon name="download" size={13} /> Export table
            </button>
          </div>

          {/* Filter bar — single row */}
          <div style={{display:"flex", gap:8, marginBottom:20, flexWrap:"nowrap", alignItems:"center", overflowX:"auto"}}>
            <div style={{position:"relative", flex:"1 1 auto", minWidth:140}}>
              <Icon name="search" size={14} style={{position:"absolute", left:10, top:"50%", transform:"translateY(-50%)", color:"var(--fg-3)", pointerEvents:"none"}} />
              <input
                value={search} onChange={e => setSearch(e.target.value)}
                placeholder="Search app, build, scan ID…"
                style={{width:"100%", height:34, boxSizing:"border-box",
                  background:"var(--bg-1)", border:"1px solid var(--line-2)", borderRadius:"var(--r-sm)",
                  padding:"0 12px 0 34px", fontSize:13, color:"var(--fg-0)", outline:"none"}}
              />
            </div>
            <select value={filterApp} onChange={e => setFilterApp(e.target.value)} style={selStyle}>
              <option value="all">All apps</option>
              {UNIQUE_APPS.map(a => <option key={a} value={a}>{a}</option>)}
            </select>
            <select value={filterStore} onChange={e => setFilterStore(e.target.value)} style={selStyle}>
              <option value="all">All stores</option>
              <option value="play">Google Play</option>
              <option value="app">Apple App Store</option>
            </select>
            <select value={filterVerdict} onChange={e => setFilterVerdict(e.target.value)} style={selStyle}>
              <option value="all">All verdicts</option>
              <option value="pass">Pass</option>
              <option value="likely_pass">Likely Pass</option>
              <option value="needs_fixes">Needs Fixes</option>
              <option value="will_reject">Will Reject</option>
            </select>
            <select value={filterSeverity} onChange={e => setFilterSeverity(e.target.value)} style={selStyle}>
              <option value="all">All severities</option>
              <option value="critical">Has critical</option>
              <option value="warning">Has warning</option>
            </select>
            <select value={filterDate} onChange={e => setFilterDate(e.target.value)} style={selStyle}>
              <option value="all">Any date</option>
              <option value="today">Today</option>
              <option value="7d">Last 7 days</option>
              <option value="30d">Last 30 days</option>
            </select>
            <select value={filterSource} onChange={e => setFilterSource(e.target.value)} style={selStyle}>
              <option value="all">All sources</option>
              <option value="github">GitHub Action</option>
              <option value="ci">CI/CD</option>
              <option value="manual">Manual upload</option>
              <option value="api">API</option>
            </select>
            <select value={filterScore} onChange={e => setFilterScore(e.target.value)} style={selStyle}>
              <option value="all">Any score</option>
              <option value="high">High (≥80)</option>
              <option value="medium">Medium (60–79)</option>
              <option value="low">Low (&lt;60)</option>
            </select>
            {hasFilters && (
              <button className="btn btn-sm btn-ghost" onClick={clearFilters}>
                <Icon name="x" size={12} /> Clear
              </button>
            )}
          </div>

          <div className="card">
            {filtered.length === 0 ? (
              <div style={{padding:"60px 32px", textAlign:"center", color:"var(--fg-3)"}}>
                <Icon name="search" size={24} />
                <div style={{fontFamily:"var(--font-display)", fontSize:16, fontWeight:600, marginTop:12}}>No scans match</div>
                <div style={{fontSize:13, marginTop:6}}>Try adjusting your filters.</div>
              </div>
            ) : (
              <div className="tbl-scroll">
              <table className="tbl">
                <thead>
                  <tr>
                    <th style={{cursor:"pointer",userSelect:"none"}} onClick={() => cycleSort("app")}>
                      App <SortIcon col="app" />
                    </th>
                    <th>Version / Build</th>
                    <th>Stores</th>
                    <th>Verdict</th>
                    <th style={{textAlign:"right",cursor:"pointer",userSelect:"none"}} onClick={() => cycleSort("score")}>
                      Score <SortIcon col="score" />
                    </th>
                    <th style={{cursor:"pointer",userSelect:"none"}} onClick={() => cycleSort("crit")}>
                      Issues <SortIcon col="crit" />
                    </th>
                    <th>Source</th>
                    <th style={{cursor:"pointer",userSelect:"none"}} onClick={() => cycleSort("date")}>
                      Date <SortIcon col="date" />
                    </th>
                    <th style={{textAlign:"right"}}>Actions</th>
                  </tr>
                </thead>
                <tbody>
                  {filtered.map(s => {
                    const src = SOURCE_META[s.source] || { label: s.source, icon:"code" };
                    return (
                      <tr key={s.id} onClick={() => go("/scan/" + s.id)} style={{cursor:"pointer"}}>
                        <td>
                          <div style={{display:"flex", alignItems:"center", gap:12}}>
                            <AppIcon letters={s.letters} size={32} gradient={s.grad} />
                            <div>
                              <div style={{display:"flex", alignItems:"center", gap:8}}>
                                <span style={{fontWeight:500, fontSize:13.5}}>{s.app}</span>
                                {s.kind === "website" && s.agentScore != null && s.agentScore >= 75 && (s.crit ?? 0) === 0 && (
                                  <span title="Agent readiness ≥ 75 with no critical issues — easy for AI agents to understand and use" style={{
                                    fontFamily:"var(--font-mono)", fontSize:9.5, fontWeight:600, letterSpacing:"0.04em",
                                    padding:"1px 6px", borderRadius:4, color:"var(--teal)", background:"var(--teal-bg)",
                                    border:"1px solid rgba(0,212,170,0.25)", textTransform:"uppercase",
                                  }}>Agent-ready</span>
                                )}
                              </div>
                              <div className="mono" style={{fontSize:11, color:"var(--fg-3)"}}>{s.bundle}</div>
                              {s.kind === "website" && s.releaseScore != null && (
                                <div className="mono" style={{fontSize:10, color:"var(--fg-3)", marginTop:2}}>
                                  Release {s.releaseScore} · Security {s.securityScore}
                                  {s.agentScore != null && <> · Agent {s.agentScore}</>}
                                  {s.apiScore != null && <> · API {s.apiScore}</>}
                                  {s.docsScore != null && <> · Docs {s.docsScore}</>}
                                  {s.vendorScore != null && <> · Vendor {s.vendorScore}</>}
                                  {s.mcpScore != null && <> · MCP {s.mcpScore}</>}
                                  {s.privacyScore != null && <> · Compliance {s.privacyScore}</>}
                                </div>
                              )}
                            </div>
                          </div>
                        </td>
                        <td>
                          <div className="mono" style={{fontSize:12.5}}>v{s.version}</div>
                          <div className="mono" style={{fontSize:11, color:"var(--fg-3)"}}>build {s.build}</div>
                        </td>
                        <td>
                          <div style={{display:"flex", gap:4, flexWrap:"wrap"}}>
                            {s.stores.map(st => <StoreChip key={st} store={st} iconOnly={true} />)}
                          </div>
                        </td>
                        <td><VerdictPill verdict={s.verdict} /></td>
                        <td style={{textAlign:"right"}}>
                          <span className="mono" style={{fontSize:15, fontWeight:600,
                            color:s.score>=85?"var(--teal)":s.score>=60?"var(--amber)":"var(--red)"}}>
                            {s.score}
                          </span>
                          <span className="mono" style={{color:"var(--fg-3)", fontSize:11}}>/100</span>
                        </td>
                        <td>
                          <div className="mono" style={{fontSize:12, display:"flex", gap:8, whiteSpace:"nowrap"}}>
                            <span style={{color:"var(--red)"}}>C {s.crit}</span>
                            <span style={{color:"var(--amber)"}}>W {s.warn}</span>
                            <span style={{color:"var(--blue)"}}>I {s.info}</span>
                          </div>
                        </td>
                        <td>
                          <div style={{display:"flex", alignItems:"center", gap:6}}>
                            <Icon name={src.icon} size={12} style={{color:"var(--fg-3)", flexShrink:0}} />
                            <span className="mono" style={{fontSize:11.5, color:"var(--fg-2)"}}>{src.label}</span>
                          </div>
                        </td>
                        <td>
                          <div className="mono" style={{fontSize:12, color:"var(--fg-2)"}}>{s.date}</div>
                          <div className="mono" style={{fontSize:11, color:"var(--fg-3)"}}>{s.duration}</div>
                        </td>
                        <td style={{textAlign:"right"}}>
                          <div style={{display:"flex", gap:4, justifyContent:"flex-end"}}
                               onClick={e => e.stopPropagation()}>
                            <button className="btn btn-sm btn-ghost" title="Open scan"
                              onClick={() => go("/scan/" + s.id)}>
                              <Icon name="external-link" size={12} />
                            </button>
                            <button className="btn btn-sm btn-ghost"
                              title={canRescan ? "Re-scan" : "Re-scan (upgrade required)"}
                              onClick={e => handleRescan(s.id, e)}>
                              <Icon name="refresh" size={12} />
                            </button>
                            <button className="btn btn-sm btn-ghost"
                              title={canExport ? "Export CSV" : "Export (upgrade required)"}
                              onClick={e => { e.stopPropagation(); handleExport(e); }}>
                              <Icon name="download" size={12} />
                            </button>
                            <button className="btn btn-sm btn-ghost"
                              title={copiedId === s.id ? "Copied!" : canShare ? "Copy share link" : "Share (upgrade required)"}
                              onClick={e => shareLink(s.id, e)}>
                              <Icon name={copiedId === s.id ? "check" : "link"} size={12} />
                            </button>
                          </div>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
              </div>
            )}
          </div>

          <div style={{display:"flex", alignItems:"center", justifyContent:"space-between", marginTop:14}}>
            <div className="mono" style={{fontSize:12, color:"var(--fg-3)"}}>
              Showing {filtered.length} of {ALL_SCANS.length} scans
            </div>
            <div style={{display:"flex", gap:6}}>
              <button className="btn btn-sm btn-ghost" disabled>← Previous</button>
              <button className="btn btn-sm btn-ghost" disabled>Next →</button>
            </div>
          </div>
    </AuthLayout>
  );
};

Object.assign(window, { AllScans, ALL_SCANS });
