// Reports, Bulk Upload, Team

function ReportsPage() {
  const hub = window.useClearCast();
  const [tab, setTab] = React.useState("reports");
  const [platform, setPlatform] = React.useState("all");
  const [status, setStatus] = React.useState("all");
  const [type, setType] = React.useState("all");
  const [reportBusy, setReportBusy] = React.useState("");
  const filters = { platform, status, type };
  const posts = (hub.data.posts || []).filter((post) => {
    if (platform !== "all" && !(post.platforms || []).includes(platform)) return false;
    if (status !== "all" && post.status !== status) return false;
    if (type !== "all" && post.contentType !== type) return false;
    return true;
  });
  const reports = hub.data.reports || [];
  const metrics = hub.data.metrics || {};
  const publishAttempts = posts.flatMap((post) => post.publishAttempts || []);
  const approvalEvents = posts.flatMap((post) => post.approvalHistory || []);
  const openInbox = (hub.data.inbox || []).filter((message) => !message.archived && message.status !== "done").length;
  const repliedInbox = (hub.data.inbox || []).filter((message) => (message.replies || []).length > 0 || message.status === "replied").length;
  const readyChannels = (hub.data.integrations || []).filter((item) => item.publishReady).length;
  const connectedChannels = (hub.data.integrations || []).filter((item) => item.connected).length;
  const activeTasks = window.buildTaskItems ? window.buildTaskItems(hub.data).filter((task) => !task.hidden).length : 0;
  const ops = {
    scheduled: posts.filter((post) => post.status === "scheduled").length,
    pending: posts.filter((post) => ["needs_approval", "changes_requested"].includes(post.status)).length,
    published: posts.filter((post) => post.status === "published").length,
    failed: posts.filter((post) => ["failed", "blocked"].includes(post.status)).length,
    publishAttempts: publishAttempts.length,
    publishSucceeded: publishAttempts.filter((attempt) => attempt.status === "published").length,
    publishFailed: publishAttempts.filter((attempt) => attempt.status === "failed").length,
    approvalEvents: approvalEvents.length,
    approvalApproved: approvalEvents.filter((event) => event.action === "approved").length,
    openInbox,
    repliedInbox,
    readyChannels,
    connectedChannels,
    activeTasks
  };
  const byPlatform = posts.reduce((acc, post) => {
    (post.platforms || []).forEach((id) => acc[id] = (acc[id] || 0) + 1);
    return acc;
  }, {});
  const createReport = async (template) => {
    if (reportBusy) return;
    setReportBusy(`save-${template.name}`);
    try {
      await hub.actions.createReport({
        name: `${template.name} - ${new Date().toLocaleDateString()}`,
        type: template.name,
        filters
      });
    } finally {
      setReportBusy("");
    }
  };
  const exportCsv = () => {
    if (reportBusy) return;
    setReportBusy("export");
    hub.actions.exportReports(filters);
    window.setTimeout(() => setReportBusy(""), 1400);
  };

  const templates = [
    { name: "Performance Overview", desc: "Reach, engagement, follower growth", icon: "Bar", clr: "var(--accent)" },
    { name: "Content Deep Dive", desc: "Top posts, content type breakdown", icon: "Image", clr: "#a78bfa" },
    { name: "Audience Insights", desc: "Demographics, locations, interests", icon: "Users", clr: "#3b82f6" },
    { name: "Channel Comparison", desc: "Cross-platform side-by-side", icon: "Plug", clr: "#ec4899" },
  ];

  return (
    <div className="page mobile-reports-page">
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 18 }}>
        <div style={{ display: "flex", gap: 10 }}>
          <div className="tabs">
            <button className={`tab ${tab === "reports" ? "active" : ""}`} onClick={() => setTab("reports")}>My reports</button>
            <button className={`tab ${tab === "builder" ? "active" : ""}`} onClick={() => setTab("builder")}>Builder</button>
            <button className={`tab ${tab === "preview" ? "active" : ""}`} onClick={() => setTab("preview")}>PDF preview</button>
            <button className={`tab ${tab === "templates" ? "active" : ""}`} onClick={() => setTab("templates")}>Templates</button>
          </div>
        </div>
        <div style={{ display: "flex", gap: 10 }}>
          <button onClick={() => setTab("builder")} className="btn"><Icon.Filter width="14" height="14" /> Filter</button>
          <button onClick={() => window.print()} className="btn"><Icon.File width="14" height="14" /> Print PDF</button>
          <button onClick={exportCsv} disabled={!!reportBusy} className="btn btn-primary"><Icon.Download width="14" height="14" /> {reportBusy === "export" ? "Exporting..." : "Export CSV"}</button>
        </div>
      </div>

      <div className="card" style={{ marginBottom: 16 }}>
        <div className="card-h"><h3>Report builder</h3><span className="sub">{posts.length} posts matched</span></div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 12 }}>
          <div>
            <label className="field-label">Platform</label>
            <select className="input" value={platform} onChange={(event) => setPlatform(event.target.value)}>
              <option value="all">All platforms</option>
              {Object.keys(Platforms).slice(0, 7).map((id) => <option key={id} value={id}>{Platforms[id].name}</option>)}
            </select>
          </div>
          <div>
            <label className="field-label">Status</label>
            <select className="input" value={status} onChange={(event) => setStatus(event.target.value)}>
              <option value="all">All statuses</option>
              <option value="needs_approval">Needs approval</option>
              <option value="scheduled">Scheduled</option>
              <option value="rejected">Rejected</option>
              <option value="changes_requested">Changes requested</option>
            </select>
          </div>
          <div>
            <label className="field-label">Content type</label>
            <select className="input" value={type} onChange={(event) => setType(event.target.value)}>
              <option value="all">All types</option>
              <option value="feed">Feed</option>
              <option value="reel">Reel</option>
              <option value="story">Story</option>
              <option value="short">Short</option>
            </select>
          </div>
          <div style={{ display: "flex", alignItems: "end", gap: 8 }}>
            <button className="btn btn-primary" disabled={!!reportBusy} onClick={() => createReport({ name: "Custom Performance" })}>{reportBusy === "save-Custom Performance" ? "Saving..." : "Save report"}</button>
          </div>
        </div>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "repeat(5, 1fr)", gap: 12, marginBottom: 16 }}>
        {[
          ["Scheduled", ops.scheduled, "var(--accent)"],
          ["Pending approval", ops.pending, "var(--warn)"],
          ["Published", ops.published, "var(--accent)"],
          ["Publish failures", ops.failed + ops.publishFailed, ops.failed || ops.publishFailed ? "var(--danger)" : "var(--text)"],
          ["Active tasks", ops.activeTasks, ops.activeTasks ? "var(--warn)" : "var(--accent)"]
        ].map(([label, value, color]) => (
          <div key={label} className="card" style={{ padding: 14 }}>
            <div className="muted" style={{ fontSize: 11.5 }}>{label}</div>
            <div style={{ marginTop: 5, fontSize: 22, fontWeight: 720, color }}>{value}</div>
          </div>
        ))}
      </div>

      {(tab === "templates" || tab === "reports") && <div style={{ marginBottom: 20 }}>
        <div style={{ fontSize: 11, color: "var(--text-3)", fontWeight: 600, letterSpacing: "0.04em", textTransform: "uppercase", marginBottom: 10 }}>Start from a template</div>
        <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 12 }}>
          {templates.map(t => {
            const Ico = Icon[t.icon];
            return (
              <button key={t.name} disabled={!!reportBusy} onClick={() => createReport(t)} className="card" style={{ padding: 14, textAlign: "left", display: "flex", alignItems: "center", gap: 12, opacity: reportBusy && reportBusy !== `save-${t.name}` ? 0.55 : 1 }}>
                <div style={{ width: 36, height: 36, borderRadius: 8, background: "var(--elev)", display: "grid", placeItems: "center", color: t.clr }}>
                  <Ico width="18" height="18" />
                </div>
                <div style={{ flex: 1, lineHeight: 1.25 }}>
                  <div style={{ fontSize: 13, fontWeight: 600 }}>{reportBusy === `save-${t.name}` ? "Saving..." : t.name}</div>
                  <div style={{ fontSize: 11.5, color: "var(--text-3)" }}>{t.desc}</div>
                </div>
                <Icon.ChevronRight width="14" height="14" style={{ color: "var(--text-3)" }}/>
              </button>
            );
          })}
        </div>
      </div>}

      {tab === "preview" && (
        <div className="report-preview">
          <div className="report-page">
            <div className="report-head">
              <div>
                <div className="brand-name">ClearCast Report</div>
                <h1>Performance Summary</h1>
                <p>Generated {new Date().toLocaleString()}</p>
              </div>
              <div className="brand-mark">CC</div>
            </div>
            <div className="report-kpis">
              <div><span>Reach</span><b>{(metrics.reach || 0).toLocaleString()}</b></div>
              <div><span>Impressions</span><b>{(metrics.impressions || 0).toLocaleString()}</b></div>
              <div><span>Engagement</span><b>{(metrics.engagement || 0).toLocaleString()}</b></div>
              <div><span>Matched posts</span><b>{posts.length}</b></div>
            </div>
            <h2>Operational Health</h2>
            <div className="report-kpis">
              <div><span>Scheduled</span><b>{ops.scheduled}</b></div>
              <div><span>Pending approval</span><b>{ops.pending}</b></div>
              <div><span>Publish success</span><b>{ops.publishAttempts ? Math.round((ops.publishSucceeded / ops.publishAttempts) * 100) : 0}%</b></div>
              <div><span>Inbox response</span><b>{(hub.data.inbox || []).length ? Math.round((ops.repliedInbox / (hub.data.inbox || []).length) * 100) : 0}%</b></div>
            </div>
            <div className="report-kpis">
              <div><span>Publish attempts</span><b>{ops.publishAttempts}</b></div>
              <div><span>Publish failures</span><b>{ops.publishFailed}</b></div>
              <div><span>Open inbox</span><b>{ops.openInbox}</b></div>
              <div><span>Ready channels</span><b>{ops.readyChannels} / {ops.connectedChannels}</b></div>
            </div>
            <h2>Channel Mix</h2>
            <div className="report-bars">
              {Object.entries(byPlatform).map(([id, count]) => (
                <div key={id}><span>{Platforms[id]?.name || id}</span><strong style={{ width: `${Math.max(8, count * 12)}%` }} /> <b>{count}</b></div>
              ))}
            </div>
            <h2>Top Posts</h2>
            <table className="report-table">
              <thead><tr><th>Date</th><th>Type</th><th>Status</th><th>Attempts</th><th>Caption</th></tr></thead>
              <tbody>{posts.slice(0, 8).map((post) => <tr key={post.id}><td>{post.date}</td><td>{post.contentType}</td><td>{post.status}</td><td>{(post.publishAttempts || []).length}</td><td>{post.caption}</td></tr>)}</tbody>
            </table>
          </div>
        </div>
      )}

      {tab !== "preview" && <div className="card" style={{ padding: 0 }}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "16px 20px", borderBottom: "1px solid var(--border)" }}>
          <div style={{ fontSize: 14, fontWeight: 600 }}>All reports <span style={{ color: "var(--text-3)", fontWeight: 400, marginLeft: 4 }}>({reports.length})</span></div>
          <div style={{ position: "relative", width: 280 }}>
            <Icon.Search width="14" height="14" style={{ position: "absolute", left: 12, top: "50%", transform: "translateY(-50%)", color: "var(--text-3)" }}/>
            <input className="input" placeholder="Search reports" style={{ paddingLeft: 32, fontSize: 12.5 }}/>
          </div>
        </div>
        <table className="tbl">
          <thead>
            <tr>
              <th style={{ width: 36 }}></th>
              <th>Name</th>
              <th>Type</th>
              <th>Date range</th>
              <th>Schedule</th>
              <th>Owner</th>
              <th>Status</th>
              <th style={{ width: 60 }}></th>
            </tr>
          </thead>
          <tbody>
            {reports.map((r, i) => {
              const Ico = Icon[r.icon] || Icon.File;
              return (
                <tr key={i}>
                  <td>
                    <div style={{ width: 32, height: 32, borderRadius: 7, background: "var(--elev)", display: "grid", placeItems: "center", color: r.clr }}>
                      <Ico width="15" height="15" />
                    </div>
                  </td>
                  <td><span style={{ fontWeight: 500 }}>{r.name}</span></td>
                  <td className="muted">{r.type}</td>
                  <td className="muted">{r.range || "Current filters"}</td>
                  <td><span className="pill" style={{ padding: "2px 8px", fontSize: 11 }}>{r.schedule || "Manual"}</span></td>
                  <td className="muted">{r.owner || "Emma"}</td>
                  <td>
                    {r.status === "ready"
                      ? <span className="pill green"><span className="pill-dot"/>Ready</span>
                      : <span className="pill info"><span className="pill-dot"/>Generating…</span>}
                  </td>
                  <td>
                    <div style={{ display: "flex", gap: 4 }}>
                      <button onClick={() => hub.actions.exportReports(r.filters || filters)} className="btn btn-ghost" style={{ padding: 4 }} title="Download"><Icon.Download width="14" height="14" /></button>
                      <button className="btn btn-ghost" onClick={() => setTab("preview")} style={{ padding: 4 }} title="Open report preview"><Icon.Dots width="14" height="14" /></button>
                    </div>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>}
    </div>
  );
}

function BulkUploadPage() {
  const hub = window.useClearCast();
  const sampleCsv = [
    "date,time,platforms,contentType,caption,media",
    "2026-05-18,09:30,instagram+facebook+linkedin,feed,Summer launch is almost here,summer-hero-01.jpg",
    "2026-05-20,19:00,tiktok+youtube,short,Pack with me for the weekend,pack-vlog.mp4",
    "2026-05-21,11:00,linkedin,feed,Hiring update: we are growing the design team,",
    "2026-05-22,14:00,instagram,feed,,",
    "2026-05-24,08:00,pinterest,feed,Coastal summer mood board,moodboard-04.jpg"
  ].join("\n");

  const [step, setStep] = React.useState(1);
  const [csv, setCsv] = React.useState(sampleCsv);
  const [fileName, setFileName] = React.useState("sample-clearcast-schedule.csv");
  const [validation, setValidation] = React.useState(null);
  const [issuesOnly, setIssuesOnly] = React.useState(false);
  const [validating, setValidating] = React.useState(false);
  const [importing, setImporting] = React.useState(false);
  const approvalRequired = hub.data.workspace?.publishingRules?.approvalRequired !== false;
  const routeLabel = approvalRequired ? "Approvals" : "Calendar";
  const routeDescription = approvalRequired ? "Valid CSV rows will be imported as approval requests." : "Valid CSV rows will be scheduled directly.";

  const rows = validation?.rows || [];
  const validCount = validation?.validRows?.length || 0;
  const issueCount = validation?.invalidRows?.length || 0;
  const scheduledCount = validation?.validRows?.filter((row) => row.post?.status === "scheduled").length || 0;
  const approvalCount = validation?.validRows?.filter((row) => row.post?.status === "needs_approval").length || 0;
  const visibleRows = issuesOnly ? rows.filter((row) => !row.ok) : rows;
  const channels = new Set(rows.flatMap((row) => row.post?.platforms || [])).size;
  const dates = rows.map((row) => row.post?.date).filter(Boolean).sort();
  const firstDate = dates[0] || "—";
  const lastDate = dates[dates.length - 1] || "—";

  const validate = async () => {
    if (validating || importing) return;
    try {
      setValidating(true);
      const result = await hub.actions.bulkValidate(csv);
      setValidation(result);
      setStep(result.rows?.length ? 2 : 1);
    } catch (error) {
      console.error(error);
      hub.toast("Could not validate CSV");
    } finally {
      setValidating(false);
    }
  };

  const importRows = async () => {
    if (importing || validating) return;
    if (!validCount) {
      hub.toast("No valid rows to import");
      return;
    }
    try {
      setImporting(true);
      await hub.actions.bulkImport(csv);
      setStep(3);
    } catch (error) {
      console.error(error);
      hub.toast("Could not import CSV");
    } finally {
      setImporting(false);
    }
  };

  const loadFile = async (event) => {
    const file = event.target.files?.[0];
    if (!file) return;
    setFileName(file.name);
    setCsv(await file.text());
    setValidation(null);
    setStep(1);
  };

  const downloadTemplate = () => {
    const blob = new Blob([sampleCsv], { type: "text/csv" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = "clearcast-bulk-template.csv";
    a.click();
    URL.revokeObjectURL(url);
    hub.toast("CSV template downloaded");
  };

  const rowWhen = (row) => `${row.post?.date || "Invalid date"} · ${row.post?.time || "Invalid time"}`;

  return (
    <div className="page mobile-bulk-page">
      <div className="card" style={{ padding: "18px 24px", marginBottom: 18 }}>
        <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          {[
            { n: 1, t: "Upload file", d: "CSV text or upload" },
            { n: 2, t: "Review posts", d: "Validate rows" },
            { n: 3, t: "Schedule", d: "Import valid rows" },
          ].map((s, i, arr) => (
            <React.Fragment key={s.n}>
              <div style={{ display: "flex", alignItems: "center", gap: 12, opacity: step >= s.n ? 1 : 0.5 }}>
                <div style={{
                  width: 32, height: 32, borderRadius: 999,
                  background: step > s.n ? "var(--accent)" : step === s.n ? "var(--accent-soft)" : "var(--elev)",
                  color: step > s.n ? "#06120d" : step === s.n ? "var(--accent-2)" : "var(--text-3)",
                  display: "grid", placeItems: "center",
                  fontWeight: 700, fontSize: 13,
                  border: step === s.n ? "1.5px solid var(--accent)" : "1px solid var(--border)",
                }}>
                  {step > s.n ? <Icon.Check width="14" height="14" /> : s.n}
                </div>
                <div style={{ lineHeight: 1.25 }}>
                  <div style={{ fontSize: 13, fontWeight: 600 }}>{s.t}</div>
                  <div style={{ fontSize: 11.5, color: "var(--text-3)" }}>{s.d}</div>
                </div>
              </div>
              {i < arr.length - 1 && <div style={{ flex: 1, height: 1, background: "var(--border)", margin: "0 16px" }}/>}
            </React.Fragment>
          ))}
        </div>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "minmax(0, 1fr) 320px", gap: 16 }}>
        <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
          <div className="card" style={{ padding: 16, display: "flex", alignItems: "center", gap: 14 }}>
            <div style={{ width: 44, height: 44, borderRadius: 8, background: "var(--elev)", display: "grid", placeItems: "center", color: "var(--accent-2)" }}>
              <Icon.File width="20" height="20" />
            </div>
            <div style={{ flex: 1, lineHeight: 1.3 }}>
              <div style={{ fontSize: 13.5, fontWeight: 600 }}>{fileName}</div>
              <div style={{ fontSize: 12, color: "var(--text-3)" }}>Required: date, time, platforms, contentType, caption. Optional: media.</div>
            </div>
            {validation && (issueCount
              ? <span className="pill warn"><span className="pill-dot"/>{issueCount} issues</span>
              : <span className="pill green"><span className="pill-dot"/>Ready</span>
            )}
            <span className={`pill ${approvalRequired ? "warn" : "green"}`}>{approvalRequired ? "Routes to approvals" : "Schedules directly"}</span>
            <label className="btn btn-sm">
              Upload CSV
              <input type="file" accept=".csv,text/csv" onChange={loadFile} style={{ display: "none" }} />
            </label>
          </div>

          <div className="card" style={{ padding: 16 }}>
            <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16, marginBottom: 10 }}>
              <div>
                <div style={{ fontSize: 14, fontWeight: 600 }}>CSV input</div>
                  <div style={{ fontSize: 12, color: "var(--text-3)" }}>Paste CSV text or upload a file, then validate before importing. {routeDescription}</div>
              </div>
              <div style={{ display: "flex", gap: 8 }}>
                <button className="btn btn-sm" onClick={() => { setCsv(sampleCsv); setFileName("sample-clearcast-schedule.csv"); setValidation(null); setStep(1); }}>Use sample</button>
                <button className="btn btn-sm" onClick={downloadTemplate}>Download template</button>
                <button className="btn btn-primary" disabled={validating || importing} onClick={validate}>{validating ? "Validating..." : "Validate CSV"}</button>
              </div>
            </div>
            <textarea
              className="textarea bulk-csv-input"
              value={csv}
              onChange={(event) => {
                setCsv(event.target.value);
                setValidation(null);
                setStep(1);
              }}
              spellCheck="false"
            />
          </div>

          <div className="card" style={{ padding: 0 }}>
            <div style={{ padding: "14px 20px", borderBottom: "1px solid var(--border)", display: "flex", justifyContent: "space-between", alignItems: "center" }}>
              <div style={{ fontSize: 14, fontWeight: 600 }}>Review posts {validation && <span style={{ color: "var(--text-3)", fontWeight: 400 }}>({rows.length})</span>}</div>
              <div style={{ display: "flex", gap: 8 }}>
                <button className={`btn btn-sm ${issuesOnly ? "btn-primary" : ""}`} onClick={() => setIssuesOnly(!issuesOnly)}><Icon.Filter width="12" height="12" /> Show issues only</button>
                <button className="btn btn-sm" onClick={() => {
                  setCsv(csv.replace(/,feed,,/g, ",feed,Imported caption needs review,"));
                  setValidation(null);
                  setStep(1);
                  hub.toast("Blank captions filled with review placeholders");
                }}>Auto-fix captions</button>
              </div>
            </div>
            {validation ? (
              <table className="tbl">
                <thead>
                  <tr>
                    <th style={{ width: 36 }}></th>
                    <th>Row</th>
                    <th>Scheduled for</th>
                    <th>Platforms</th>
                    <th>Caption</th>
                    <th>Route</th>
                    <th>Media</th>
                  </tr>
                </thead>
                <tbody>
                  {visibleRows.map((row) => (
                    <tr key={row.rowNumber} style={{ background: row.ok ? "transparent" : "rgba(239, 68, 68, 0.04)" }}>
                      <td>
                        {row.ok
                          ? <div style={{ width: 18, height: 18, borderRadius: 999, background: "var(--accent-soft)", color: "var(--accent-2)", display: "grid", placeItems: "center" }}><Icon.Check width="11" height="11" /></div>
                          : <div style={{ width: 18, height: 18, borderRadius: 999, background: "var(--danger-soft)", color: "var(--danger)", display: "grid", placeItems: "center", fontWeight: 700, fontSize: 11 }}>!</div>}
                      </td>
                      <td className="muted" style={{ fontSize: 12.5 }}>{row.rowNumber}</td>
                      <td className="muted" style={{ fontSize: 12.5 }}>{rowWhen(row)}</td>
                      <td>
                        <div style={{ display: "flex", gap: 4 }}>
                          {(row.post?.platforms || []).map(p => <PlatformIcon key={p} id={p} size={18} />)}
                        </div>
                      </td>
                      <td style={{ maxWidth: 360 }}>
                        <div style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", fontSize: 12.5 }}>
                          {row.post?.caption || <span style={{ color: "var(--danger)" }}>—</span>}
                        </div>
                        {!!row.errors?.length && <div style={{ fontSize: 11, color: "var(--danger)", marginTop: 2 }}>{row.errors.join("; ")}</div>}
                      </td>
                      <td>
                        <span className={`pill ${row.post?.status === "scheduled" ? "green" : "warn"}`} style={{ fontSize: 11, padding: "3px 7px" }}>
                          {row.post?.status === "scheduled" ? "Calendar" : "Approvals"}
                        </span>
                      </td>
                      <td className="muted" style={{ fontSize: 12.5 }}>{row.raw?.media || "—"}</td>
                    </tr>
                  ))}
                  {!visibleRows.length && <tr><td colSpan="7" className="muted" style={{ padding: 24, textAlign: "center" }}>No rows match this view.</td></tr>}
                </tbody>
              </table>
            ) : (
              <div className="bulk-empty-state">
                <Icon.File width="24" height="24" />
                <div>Validate the CSV to preview imported posts.</div>
              </div>
            )}
          </div>

          <div style={{ display: "flex", justifyContent: "space-between" }}>
            <button className="btn" onClick={() => { setValidation(null); setStep(1); }}>Back</button>
            <button className="btn btn-primary" disabled={!validCount || importing || validating} onClick={importRows}>
              {importing ? "Importing..." : `Import ${validCount || 0} valid rows to ${routeLabel}`}
            </button>
          </div>
        </div>

        <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
          <div className="card">
            <div className="card-h"><h3>Summary</h3></div>
            <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
              <div style={{ display: "flex", justifyContent: "space-between" }}><span className="muted">Total rows</span><b>{rows.length}</b></div>
              <div style={{ display: "flex", justifyContent: "space-between" }}><span className="muted">Ready to schedule</span><b style={{ color: "var(--accent-2)" }}>{validCount}</b></div>
              <div style={{ display: "flex", justifyContent: "space-between" }}><span className="muted">Issues</span><b style={{ color: "var(--danger)" }}>{issueCount}</b></div>
              <div style={{ display: "flex", justifyContent: "space-between" }}><span className="muted">Route</span><b>{routeLabel}</b></div>
              <div style={{ display: "flex", justifyContent: "space-between" }}><span className="muted">To approvals</span><b style={{ color: approvalCount ? "var(--warn)" : "var(--text)" }}>{approvalCount}</b></div>
              <div style={{ display: "flex", justifyContent: "space-between" }}><span className="muted">To calendar</span><b style={{ color: scheduledCount ? "var(--accent-2)" : "var(--text)" }}>{scheduledCount}</b></div>
              <div style={{ display: "flex", justifyContent: "space-between" }}><span className="muted">Channels affected</span><b>{channels}</b></div>
              <div style={{ display: "flex", justifyContent: "space-between" }}><span className="muted">Time span</span><b>{firstDate === "—" ? "—" : `${firstDate} – ${lastDate}`}</b></div>
            </div>
          </div>

          <div className="card">
            <div className="card-h"><h3>Field mapping</h3></div>
            <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
              {[
                ["date", "Date"],
                ["time", "Time"],
                ["platforms", "Platforms"],
                ["contentType", "Content type"],
                ["caption", "Caption"],
                ["media", "Media"],
              ].map(([f, m]) => (
                <div key={f} style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 12.5 }}>
                  <code style={{ background: "var(--bg-2)", padding: "2px 6px", borderRadius: 4, fontSize: 11, fontFamily: "ui-monospace, monospace" }}>{f}</code>
                  <Icon.ChevronRight width="12" height="12" style={{ color: "var(--text-3)" }}/>
                  <span>{m}</span>
                </div>
              ))}
            </div>
            <button className="btn btn-ghost btn-sm" style={{ marginTop: 10, padding: "4px 0" }} onClick={validate}>Re-check mapping</button>
          </div>

          <div className="card" style={{ background: "var(--accent-softer)", borderColor: "rgba(20,184,138,0.18)" }}>
            <div style={{ display: "flex", gap: 10 }}>
              <Icon.Sparkles width="16" height="16" style={{ color: "var(--accent-2)", flexShrink: 0, marginTop: 2 }}/>
              <div>
                <div style={{ fontSize: 13, fontWeight: 600, color: "var(--accent-2)" }}>Validation rules</div>
                <div style={{ fontSize: 12, color: "var(--text-2)", marginTop: 4 }}>Dates use YYYY-MM-DD. Times use HH:MM. Platforms can be joined with +, |, or ;.</div>
                <button className="btn btn-sm" style={{ marginTop: 8 }} onClick={() => { validate(); hub.toast(`Using ${hub.data.workspace?.timezone || "workspace timezone"} for validation`); }}>Apply workspace timezone</button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

function TeamPage() {
  const hub = window.useClearCast();
  const [tab, setTab] = React.useState("members");
  const [search, setSearch] = React.useState("");
  const [selectedRole, setSelectedRole] = React.useState("owner");
  const [invite, setInvite] = React.useState({ email: "", role: "Creator", channels: ["instagram"] });
  const [seatLimit, setSeatLimit] = React.useState(15);
  const [teamBusy, setTeamBusy] = React.useState("");
  const members = hub.data.teamMembers || [];
  const roles = hub.data.teamRoles || [];
  const invites = hub.data.teamInvites || [];
  const audit = hub.data.auditLog || [];
  const catalog = hub.data.permissionCatalog || [];
  const permissions = new Set(hub.data.currentPermissions || []);
  const canManage = permissions.has("manage_team");
  const channels = Object.keys(Platforms).slice(0, 7);
  const currentUser = hub.data.workspace?.user || members[0] || {};
  const filteredMembers = members.filter((member) => `${member.name} ${member.email} ${member.role}`.toLowerCase().includes(search.toLowerCase()));
  const roleCounts = roles.reduce((acc, role) => {
    acc[role.name] = members.filter((member) => member.role === role.name).length;
    return acc;
  }, {});
  const roleColors = { Owner: "var(--accent)", Admin: "#14b8a6", Manager: "#3b82f6", Creator: "#a78bfa", Reviewer: "#f59e0b", Client: "var(--text-3)" };
  const initials = (name) => String(name || "CC").split(" ").map((word) => word[0]).join("").slice(0, 2).toUpperCase();
  const toggleInviteChannel = (channel) => {
    setInvite((current) => {
      const exists = current.channels.includes(channel);
      const next = exists ? current.channels.filter((item) => item !== channel) : [...current.channels, channel];
      return { ...current, channels: next.length ? next : [channel] };
    });
  };
  const sendInvite = async () => {
    if (teamBusy) return;
    if (!invite.email.trim()) {
      hub.toast("Enter an email address");
      return;
    }
    setTeamBusy("invite");
    try {
      await hub.actions.inviteMember(invite);
      setInvite({ email: "", role: "Creator", channels: ["instagram"] });
      setTab("invites");
    } finally {
      setTeamBusy("");
    }
  };
  const toggleRolePermission = async (role, permission) => {
    if (teamBusy) return;
    setTeamBusy(`role-${role.id}-${permission}`);
    const active = role.permissions || [];
    const next = active.includes(permission)
      ? active.filter((item) => item !== permission)
      : [...active, permission];
    try {
      await hub.actions.updateRole(role.id, next);
    } finally {
      setTeamBusy("");
    }
  };
  const updateMemberChannel = async (member, channel) => {
    if (teamBusy) return;
    setTeamBusy(`channel-${member.id}-${channel}`);
    const active = member.channels || [];
    const next = active.includes(channel)
      ? active.filter((item) => item !== channel)
      : [...active, channel];
    try {
      await hub.actions.updateMember(member.id, { channels: next.length ? next : [channel] });
    } finally {
      setTeamBusy("");
    }
  };
  const updateMember = async (id, payload, busyKey) => {
    if (teamBusy) return;
    setTeamBusy(busyKey || `member-${id}`);
    try {
      await hub.actions.updateMember(id, payload);
    } finally {
      setTeamBusy("");
    }
  };
  const switchUser = async (id) => {
    if (teamBusy) return;
    setTeamBusy(`view-${id}`);
    try {
      await hub.actions.switchUser(id);
    } finally {
      setTeamBusy("");
    }
  };

  return (
    <div className="page mobile-team-page">
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 18 }}>
        <div className="tabs">
          {["members", "roles", "audit log", "invites"].map(t => (
            <button key={t} className={`tab ${tab === t ? "active" : ""}`} onClick={() => setTab(t)}>
              {t[0].toUpperCase() + t.slice(1)}
              {t === "invites" && invites.filter((item) => item.status === "pending").length > 0 && <span style={{ color: "var(--warn)", marginLeft: 4 }}>{invites.filter((item) => item.status === "pending").length}</span>}
            </button>
          ))}
        </div>
        <button className="btn btn-primary" disabled={!canManage} onClick={() => setTab("invites")} title={canManage ? "Invite member" : "Requires Manage team permission"}><Icon.Plus width="14" height="14" /> Invite member</button>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "minmax(0, 1fr) 280px", gap: 16 }}>
        <div>
          {tab === "members" && <div className="card" style={{ padding: 0 }}>
            <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "14px 20px", borderBottom: "1px solid var(--border)" }}>
              <div style={{ display: "flex", gap: 14, alignItems: "center" }}>
                <div style={{ fontSize: 14, fontWeight: 600 }}>{members.length} members</div>
                <div className="muted" style={{ fontSize: 12.5 }}>· {members.filter((item) => item.status === "active").length} active seats</div>
              </div>
              <div style={{ position: "relative", width: 240 }}>
                <Icon.Search width="14" height="14" style={{ position: "absolute", left: 10, top: "50%", transform: "translateY(-50%)", color: "var(--text-3)" }}/>
                <input className="input" value={search} onChange={(event) => setSearch(event.target.value)} placeholder="Search members" style={{ paddingLeft: 32, fontSize: 12.5 }}/>
              </div>
            </div>
            <table className="tbl">
              <thead>
                <tr>
                  <th>Name</th>
                  <th>Role</th>
                  <th>Status</th>
                  <th>Channels</th>
                  <th>Last active</th>
                  <th style={{ width: 190 }}>Actions</th>
                </tr>
              </thead>
              <tbody>
                {filteredMembers.map((m) => (
                  <tr key={m.id}>
                    <td>
                      <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                        <div className="avatar sz-32" style={{ color: "white" }}>{initials(m.name)}</div>
                        <div style={{ lineHeight: 1.25 }}>
                          <div style={{ fontWeight: 500 }}>{m.name}</div>
                          <div style={{ fontSize: 11.5, color: "var(--text-3)" }}>{m.email}</div>
                        </div>
                      </div>
                    </td>
                    <td>
                      <select className="input" disabled={!canManage || m.role === "Owner" || !!teamBusy} value={m.role} onChange={(event) => updateMember(m.id, { role: event.target.value }, `role-${m.id}`)} style={{ minWidth: 128, height: 34 }}>
                        {roles.map((role) => <option key={role.id} value={role.name}>{role.name}</option>)}
                      </select>
                    </td>
                    <td><span className={`pill ${m.status === "active" ? "green" : "warn"}`}>{m.status}</span></td>
                    <td>
                      <div style={{ display: "flex", gap: 4, flexWrap: "wrap", maxWidth: 210 }}>
                        {channels.map((channel) => (
                          <button key={channel} disabled={!canManage || m.role === "Owner" || !!teamBusy} onClick={() => updateMemberChannel(m, channel)} className={`pf ${Platforms[channel].cls}`} title={Platforms[channel].name} style={{ width: 24, height: 24, opacity: (m.channels || []).includes(channel) ? 1 : 0.22, border: "none", color: "white", cursor: canManage && !teamBusy ? "pointer" : "not-allowed" }}>
                            {Platforms[channel].letter}
                          </button>
                        ))}
                      </div>
                    </td>
                    <td className="muted" style={{ fontSize: 12.5 }}>
                      {m.lastActive === "Online now" ? <span style={{ display: "inline-flex", alignItems: "center", gap: 5 }}><span style={{ width: 6, height: 6, borderRadius: 999, background: "var(--accent)" }}/>Online now</span> : m.lastActive}
                    </td>
                    <td>
                      <div style={{ display: "flex", gap: 6 }}>
                        <button className="btn btn-sm" disabled={!!teamBusy} onClick={() => switchUser(m.id)}>{teamBusy === `view-${m.id}` ? "Switching..." : "View as"}</button>
                        <button className="btn btn-ghost btn-sm" disabled={!canManage || m.role === "Owner" || !!teamBusy} onClick={() => updateMember(m.id, { status: m.status === "active" ? "disabled" : "active" }, `status-${m.id}`)}>{teamBusy === `status-${m.id}` ? "Saving..." : m.status === "active" ? "Disable" : "Enable"}</button>
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>}

          {tab === "roles" && <div className="card" style={{ padding: 0 }}>
            <div style={{ padding: "16px 20px", borderBottom: "1px solid var(--border)" }}>
              <div style={{ fontSize: 14, fontWeight: 600 }}>Role permissions</div>
              <div className="muted" style={{ fontSize: 12.5, marginTop: 3 }}>Changes here immediately affect the workflow gates across posts, approvals, inbox, reports, media, links, integrations, and settings.</div>
            </div>
            <div style={{ display: "grid", gridTemplateColumns: "240px minmax(0, 1fr)", minHeight: 420 }}>
              <div style={{ borderRight: "1px solid var(--border)", padding: 14 }}>
                {roles.map((role) => (
                  <button key={role.id} onClick={() => setSelectedRole(role.id)} className={`btn ${selectedRole === role.id ? "btn-primary" : ""}`} style={{ width: "100%", justifyContent: "space-between", marginBottom: 8 }}>
                    <span>{role.name}</span><span className="pill">{roleCounts[role.name] || 0}</span>
                  </button>
                ))}
              </div>
              <div style={{ padding: 18 }}>
                {roles.filter((role) => role.id === selectedRole).map((role) => (
                  <div key={role.id}>
                    <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", gap: 16, marginBottom: 14 }}>
                      <div>
                        <h3 style={{ margin: 0 }}>{role.name}</h3>
                        <div className="muted" style={{ fontSize: 12.5, marginTop: 4 }}>{role.description}</div>
                      </div>
                      <span className="pill green">{(role.permissions || []).length} permissions</span>
                    </div>
                    <div style={{ display: "grid", gridTemplateColumns: "repeat(2, minmax(0, 1fr))", gap: 10 }}>
                      {catalog.map((permission) => {
                        const checked = (role.permissions || []).includes(permission.id);
                        const locked = role.id === "owner" || !canManage;
                        return (
                          <label key={permission.id} className="card" style={{ display: "flex", alignItems: "center", gap: 10, padding: 12, cursor: locked ? "default" : "pointer" }}>
                            <input type="checkbox" checked={checked} disabled={locked || !!teamBusy} onChange={() => toggleRolePermission(role, permission.id)} />
                            <div style={{ lineHeight: 1.25 }}>
                              <div style={{ fontSize: 12.5, fontWeight: 600 }}>{permission.label}</div>
                              <div className="muted" style={{ fontSize: 11 }}>{permission.area}</div>
                            </div>
                          </label>
                        );
                      })}
                    </div>
                  </div>
                ))}
              </div>
            </div>
          </div>}

          {tab === "audit log" && <div className="card" style={{ padding: 0 }}>
            <div style={{ padding: "16px 20px", borderBottom: "1px solid var(--border)" }}>
              <div style={{ fontSize: 14, fontWeight: 600 }}>Audit history</div>
              <div className="muted" style={{ fontSize: 12.5, marginTop: 3 }}>Permission, invite, publishing, approval, and inbox changes are recorded here.</div>
            </div>
            <table className="tbl">
              <thead><tr><th>Actor</th><th>Action</th><th>Details</th><th>Time</th></tr></thead>
              <tbody>
                {audit.length === 0 && <tr><td colSpan="4" className="muted">No audit events yet.</td></tr>}
                {audit.map((event) => (
                  <tr key={event.id}>
                    <td><b>{event.actor}</b><div className="muted" style={{ fontSize: 11 }}>{event.role}</div></td>
                    <td>{event.action}</td>
                    <td className="muted">{event.details}</td>
                    <td className="muted">{new Date(event.createdAt).toLocaleString()}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>}

          {tab === "invites" && <div className="card">
            <div className="card-h"><h3>Invite teammate</h3><span className="sub">{canManage ? "Active" : "Requires team permission"}</span></div>
            <div style={{ display: "grid", gridTemplateColumns: "minmax(0, 1.2fr) 160px", gap: 12, marginBottom: 12 }}>
              <input className="input" disabled={!canManage || !!teamBusy} value={invite.email} onChange={(event) => setInvite({ ...invite, email: event.target.value })} placeholder="teammate@company.com" />
              <select className="input" disabled={!canManage || !!teamBusy} value={invite.role} onChange={(event) => setInvite({ ...invite, role: event.target.value })}>
                {roles.filter((role) => role.id !== "owner").map((role) => <option key={role.id} value={role.name}>{role.name}</option>)}
              </select>
            </div>
            <div style={{ display: "flex", gap: 6, flexWrap: "wrap", marginBottom: 14 }}>
              {channels.map((channel) => (
                <button key={channel} disabled={!canManage || !!teamBusy} onClick={() => toggleInviteChannel(channel)} className={`btn btn-sm ${invite.channels.includes(channel) ? "btn-primary" : ""}`}>
                  <PlatformIcon id={channel} size={16} /> {Platforms[channel].name}
                </button>
              ))}
            </div>
            <button className="btn btn-primary" disabled={!canManage || !!teamBusy} onClick={sendInvite}><Icon.Mail width="14" height="14" /> {teamBusy === "invite" ? "Sending..." : "Send invite"}</button>
            <div style={{ marginTop: 18, borderTop: "1px solid var(--border)", paddingTop: 12 }}>
              {invites.map((item) => (
                <div key={item.id} style={{ display: "grid", gridTemplateColumns: "minmax(0, 1fr) 110px 90px", gap: 10, alignItems: "center", padding: "10px 0", borderBottom: "1px solid var(--border)" }}>
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontWeight: 600, fontSize: 13 }}>{item.email}</div>
                    <div className="muted" style={{ fontSize: 11.5 }}>Invited by {item.invitedBy} · {new Date(item.sentAt).toLocaleDateString()}</div>
                  </div>
                  <span className="pill">{item.role}</span>
                  <button className="btn btn-sm" disabled={!canManage || !!teamBusy} onClick={async () => {
                    if (teamBusy) return;
                    setTeamBusy(`resend-${item.id}`);
                    try {
                      await hub.actions.resendInvite(item.id);
                    } finally {
                      setTeamBusy("");
                    }
                  }}><Icon.Refresh width="12" height="12" /> {teamBusy === `resend-${item.id}` ? "Sending..." : "Resend"}</button>
                </div>
              ))}
            </div>
          </div>}
        </div>

        <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
          <div className="card">
            <div className="card-h"><h3>Active tester</h3><span className="pill green">{currentUser.role}</span></div>
            <div style={{ display: "flex", gap: 10, alignItems: "center", marginBottom: 10 }}>
              <div className="avatar sz-32" style={{ color: "white" }}>{initials(currentUser.name)}</div>
              <div style={{ minWidth: 0 }}>
                <div style={{ fontSize: 13, fontWeight: 600 }}>{currentUser.name}</div>
                <div className="muted" style={{ fontSize: 11.5 }}>{currentUser.email}</div>
              </div>
            </div>
            <select className="input" disabled={!!teamBusy} value={currentUser.id || ""} onChange={(event) => switchUser(event.target.value)}>
              {members.map((member) => <option key={member.id} value={member.id}>{member.name} · {member.role}</option>)}
            </select>
            <div style={{ marginTop: 10, display: "flex", gap: 6, flexWrap: "wrap" }}>
              {(hub.data.currentPermissions || []).slice(0, 6).map((permission) => <span key={permission} className="pill green">{permission.replaceAll("_", " ")}</span>)}
              {(hub.data.currentPermissions || []).length > 6 && <span className="pill">+{(hub.data.currentPermissions || []).length - 6}</span>}
            </div>
          </div>

          <div className="card">
            <div className="card-h"><h3>Roles</h3><button className="sub" onClick={() => setTab("roles")} style={{ color: "var(--accent-2)", background: "none", border: 0, cursor: "pointer", font: "inherit" }}>Manage</button></div>
            <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
              {roles.map(r => (
                <div key={r.name} style={{ display: "flex", alignItems: "flex-start", gap: 10 }}>
                  <div style={{ width: 8, height: 8, borderRadius: 999, background: roleColors[r.name] || "var(--text-3)", marginTop: 6, flexShrink: 0 }}/>
                  <div style={{ flex: 1, lineHeight: 1.3 }}>
                    <div style={{ fontSize: 12.5, fontWeight: 600 }}>{r.name}</div>
                    <div style={{ fontSize: 11.5, color: "var(--text-3)" }}>{r.description}</div>
                  </div>
                  <span style={{ fontSize: 11.5, color: "var(--text-3)" }}>{roleCounts[r.name] || 0}</span>
                </div>
              ))}
            </div>
          </div>

          <div className="card">
            <div className="card-h"><h3>Plan</h3></div>
            <div style={{ fontSize: 13 }}>Team — <b>{members.length + invites.length} of {seatLimit} seats</b></div>
            <div style={{ marginTop: 8, height: 6, background: "var(--bg-2)", borderRadius: 3, overflow: "hidden" }}>
              <div style={{ width: `${Math.min(100, ((members.length + invites.length) / seatLimit) * 100)}%`, height: "100%", background: "var(--accent)" }}/>
            </div>
            <button className="btn btn-sm" onClick={() => { setSeatLimit((value) => value + 5); hub.toast("Added 5 local demo seats"); }} style={{ marginTop: 12, width: "100%", justifyContent: "center" }}>Add more seats</button>
          </div>
        </div>
      </div>
    </div>
  );
}

window.ReportsPage = ReportsPage;
window.BulkUploadPage = BulkUploadPage;
window.TeamPage = TeamPage;
