// ---------- Apps directory — integrations for studio workspaces ----------

const AppsPage = ({ onOpenMobileMenu }) => {
  const [category, setCategory] = React.useState("All");
  const [query, setQuery] = React.useState("");
  const [appsState, setAppsState] = React.useState(HD.apps);
  const [focused, setFocused] = React.useState(null); // app id for connect modal

  const filtered = appsState.filter(a =>
    (category === "All" || a.category === category) &&
    (!query || a.name.toLowerCase().includes(query.toLowerCase()) || a.tagline.toLowerCase().includes(query.toLowerCase()))
  );
  const connected = appsState.filter(a => a.status === "connected" || a.status === "needs-attention");
  const connectedCount = appsState.filter(a => a.status === "connected").length;
  const needsAttention = appsState.filter(a => a.status === "needs-attention").length;

  const toggleConnect = (id, asConnected) => {
    setAppsState(prev => prev.map(a => a.id === id
      ? { ...a, status: asConnected ? "connected" : "available", account: asConnected ? (a.account || "Connected just now") : null, lastSync: asConnected ? "Just now" : null }
      : a
    ));
    const app = appsState.find(a => a.id === id);
    if (asConnected) {
      window.ToastEvents.emit({ kind: "success", title: `${app.name} connected`, body: "Auth handshake complete — events will start flowing within a minute." });
    } else {
      window.ToastEvents.emit({ kind: "info", title: `${app.name} disconnected`, body: "Existing data is preserved; reconnect any time." });
    }
  };

  return (
    <div>
      <Topbar
        eyebrow="WORKSPACE"
        title="Apps & integrations"
        onOpenMobileMenu={onOpenMobileMenu}
        actions={
          <>
            <Button variant="ghost" size="md" icon={<window.Icon.Code size={13} />} onClick={() => window.ToastEvents.emit({ kind: "info", title: "Developer keys", body: "API tokens & webhook signing coming in Phase 2." })}>API keys</Button>
            <Button variant="primary" size="md" icon={<window.Icon.Plus size={13} />} onClick={() => window.ToastEvents.emit({ kind: "info", title: "Request an app", body: "Tell us what you need — most requests ship within a quarter." })}>Request an app</Button>
          </>
        }
      />

      <div style={{ padding: "24px 32px 60px", display: "flex", flexDirection: "column", gap: 28 }}>
        {/* Hero strip — what apps do */}
        <Card style={{ padding: 0, overflow: "hidden", position: "relative" }}>
          <div style={{
            position: "absolute", inset: 0,
            background: "radial-gradient(circle at 100% 0%, rgba(29,78,216,0.10), transparent 55%)",
            pointerEvents: "none",
          }} />
          <div style={{ position: "relative", padding: 24, display: "grid", gridTemplateColumns: "minmax(0,1.4fr) minmax(0,1fr)", gap: 32, alignItems: "center" }} className="md-stack">
            <div>
              <div className="micro" style={{ color: "var(--harbor-2)", marginBottom: 10 }}>WINTERHILL MEDIA · APPS</div>
              <h2 className="serif" style={{ fontSize: 34, fontWeight: 500, letterSpacing: "-0.02em", margin: 0, lineHeight: 1.1 }}>
                Connect the rest of your studio.<br />
                <span style={{ fontStyle: "italic", color: "var(--warm-gray)" }}>Keep everything in HarborDock.</span>
              </h2>
              <p style={{ fontSize: 13.5, color: "var(--warm-gray)", marginTop: 14, lineHeight: 1.6, maxWidth: 520 }}>
                Bring drafts in from your NLE, mirror client folders from Drive,
                pipe approvals into Slack, and trigger Stripe invoices on final delivery —
                without leaving the dock.
              </p>
              <div style={{ display: "flex", gap: 24, marginTop: 22 }}>
                <AppMetric label="Connected" value={connectedCount} tone="harbor" />
                <AppMetric label="Available" value={appsState.length - connected.length} tone="neutral" />
                <AppMetric label="Needs attention" value={needsAttention} tone="amber" />
              </div>
            </div>
            <div className="md-hide">
              <AppHeroDiagram apps={appsState.filter(a => a.featured)} />
            </div>
          </div>
        </Card>

        {/* Filter row */}
        <div style={{ display: "flex", alignItems: "center", gap: 12, flexWrap: "wrap" }}>
          <div style={{
            display: "inline-flex", alignItems: "center", gap: 8,
            background: "rgba(255,255,255,0.03)", border: "1px solid rgba(255,255,255,0.06)",
            borderRadius: 8, padding: "8px 12px", flex: "1 1 280px", minWidth: 0,
          }}>
            <window.Icon.Search size={13} color="var(--warm-gray)" />
            <input
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              placeholder="Search apps…"
              style={{
                flex: 1, background: "transparent", border: "none", outline: "none",
                color: "var(--white)", fontSize: 13, fontFamily: "var(--sans)",
              }}
            />
          </div>
          <div style={{ display: "flex", gap: 6, overflowX: "auto", paddingBottom: 2, scrollbarWidth: "none" }}>
            {HD.appCategories.map(cat => (
              <button
                key={cat}
                onClick={() => setCategory(cat)}
                style={{
                  padding: "7px 12px", borderRadius: 99, whiteSpace: "nowrap",
                  background: category === cat ? "rgba(29,78,216,0.14)" : "transparent",
                  border: category === cat ? "1px solid rgba(29,78,216,0.32)" : "1px solid rgba(255,255,255,0.08)",
                  color: category === cat ? "#9CC1FF" : "var(--warm-gray)",
                  fontSize: 12, fontFamily: "var(--sans)", fontWeight: 500, cursor: "pointer",
                  transition: "all 120ms ease",
                }}
              >
                {cat}
              </button>
            ))}
          </div>
        </div>

        {/* Connected section */}
        {connected.length > 0 && category === "All" && !query && (
          <section>
            <SectionHeader eyebrow="CONNECTED" title="Live integrations" dense
              action={<Button variant="ghost" size="sm" icon={<window.Icon.Refresh size={12} />}>Sync all</Button>}
            />
            <div className="md-2col sm-1col" style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 16 }}>
              {connected.map(a => (
                <ConnectedAppCard key={a.id} app={a} onOpen={() => setFocused(a.id)} onDisconnect={() => toggleConnect(a.id, false)} />
              ))}
            </div>
          </section>
        )}

        {/* Directory */}
        <section>
          <SectionHeader
            eyebrow={category === "All" ? "DIRECTORY" : category.toUpperCase()}
            title={category === "All" ? "All apps" : category}
            dense
          />
          {filtered.length === 0 ? (
            <EmptyState
              iconName="Apps"
              title={`No apps match "${query}"`}
              body="Try a different keyword, or tell us what you need — we'll ship it."
              action={<Button variant="ghost" size="md" icon={<window.Icon.Plus size={13} />} onClick={() => setQuery("")}>Clear search</Button>}
            />
          ) : (
            <div className="md-2col sm-1col" style={{ display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 16 }}>
              {filtered.map(a => (
                <AppCard
                  key={a.id}
                  app={a}
                  onOpen={() => setFocused(a.id)}
                  onConnect={() => toggleConnect(a.id, true)}
                />
              ))}
            </div>
          )}
        </section>

        {/* Activity feed */}
        <section>
          <SectionHeader eyebrow="EVENT LOG" title="Recent app activity" dense />
          <Card style={{ padding: 0 }}>
            {HD.appActivity.map((a, i, arr) => {
              const tone = STATUS_TONES[a.accent];
              const IconComp = window.Icon[a.icon] || window.Icon.Apps;
              return (
                <div key={a.id} style={{
                  display: "flex", alignItems: "center", gap: 14,
                  padding: "14px 20px",
                  borderBottom: i === arr.length - 1 ? "none" : "1px solid rgba(255,255,255,0.04)",
                }}>
                  <div style={{
                    width: 34, height: 34, borderRadius: 8,
                    background: tone.bg, border: `1px solid ${tone.bd}`, color: tone.fg,
                    display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0,
                  }}><IconComp size={14} /></div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13, color: "var(--white)" }}>
                      <span style={{ fontWeight: 500 }}>{a.app}</span>
                      <span style={{ color: "var(--warm-gray)" }}> — {a.action}</span>
                    </div>
                  </div>
                  <div style={{ fontSize: 11, color: "var(--warm-gray)", flexShrink: 0 }}>{a.at}</div>
                </div>
              );
            })}
          </Card>
        </section>

        {/* Developer / API panel */}
        <Card style={{ padding: 0, overflow: "hidden" }}>
          <div style={{ padding: "20px 24px", display: "grid", gridTemplateColumns: "1fr auto", gap: 20, alignItems: "center" }} className="md-stack">
            <div>
              <div className="micro" style={{ color: "var(--warm-gray)", marginBottom: 6 }}>BUILDING SOMETHING CUSTOM?</div>
              <div className="serif" style={{ fontSize: 22, fontWeight: 500, letterSpacing: "-0.01em", color: "var(--white)" }}>
                Webhooks, REST API, and a public events stream.
              </div>
              <p style={{ fontSize: 13, color: "var(--warm-gray)", marginTop: 8, lineHeight: 1.55, maxWidth: 560 }}>
                Every upload, comment, approval, and delivery emits a signed event you can POST anywhere.
                Pair it with Zapier for low-code, or roll your own.
              </p>
            </div>
            <div style={{ display: "flex", gap: 8 }}>
              <Button variant="ghost" size="md" icon={<window.Icon.Code size={13} />}>Read the docs</Button>
              <Button variant="primary" size="md" icon={<window.Icon.Plus size={13} />}>New webhook</Button>
            </div>
          </div>
        </Card>
      </div>

      {focused && (
        <AppDetailModal
          app={appsState.find(a => a.id === focused)}
          onClose={() => setFocused(null)}
          onToggle={(asConnected) => { toggleConnect(focused, asConnected); setFocused(null); }}
        />
      )}
    </div>
  );
};

const AppMetric = ({ label, value, tone }) => {
  const t = STATUS_TONES[tone];
  return (
    <div>
      <div className="micro" style={{ color: "var(--warm-gray)", marginBottom: 6 }}>{label}</div>
      <div className="serif" style={{ fontSize: 32, fontWeight: 500, letterSpacing: "-0.02em", lineHeight: 1, color: t.fg }}>{value}</div>
    </div>
  );
};

const AppHeroDiagram = ({ apps }) => {
  // Visual: HarborDock anchor in the center with app icons orbiting
  const featured = apps.slice(0, 6);
  return (
    <div style={{
      position: "relative", height: 220,
      display: "flex", alignItems: "center", justifyContent: "center",
    }}>
      {/* concentric rings */}
      <svg width="100%" height="100%" viewBox="0 0 320 220" preserveAspectRatio="xMidYMid meet" style={{ position: "absolute", inset: 0 }}>
        <circle cx="160" cy="110" r="60" stroke="rgba(255,255,255,0.05)" fill="none" />
        <circle cx="160" cy="110" r="92" stroke="rgba(255,255,255,0.04)" fill="none" strokeDasharray="2 4" />
      </svg>
      <div style={{
        position: "relative",
        width: 64, height: 64, borderRadius: 16,
        background: "var(--charcoal)",
        border: "1px solid rgba(255,255,255,0.10)",
        display: "flex", alignItems: "center", justifyContent: "center",
        boxShadow: "0 8px 32px -8px rgba(29,78,216,0.25)",
      }}>
        <HDMark size={48} />
      </div>
      {featured.map((a, i) => {
        const total = featured.length;
        const angle = (i / total) * Math.PI * 2 - Math.PI / 2;
        const r = 92;
        const x = Math.cos(angle) * r;
        const y = Math.sin(angle) * r;
        const tone = STATUS_TONES[a.accent];
        const IconComp = window.Icon[a.icon] || window.Icon.Apps;
        return (
          <div key={a.id} style={{
            position: "absolute", left: `calc(50% + ${x}px)`, top: `calc(50% + ${y}px)`,
            transform: "translate(-50%, -50%)",
            width: 40, height: 40, borderRadius: 10,
            background: "var(--charcoal)", border: `1px solid ${tone.bd}`, color: tone.fg,
            display: "flex", alignItems: "center", justifyContent: "center",
            boxShadow: "0 4px 12px -4px rgba(0,0,0,0.4)",
          }}><IconComp size={18} /></div>
        );
      })}
    </div>
  );
};

const AppCard = ({ app, onOpen, onConnect }) => {
  const tone = STATUS_TONES[app.accent || "neutral"];
  const IconComp = window.Icon[app.icon] || window.Icon.Apps;
  const isConnected = app.status === "connected" || app.status === "needs-attention";
  return (
    <Card hover style={{ padding: 18, display: "flex", flexDirection: "column", gap: 14 }}>
      <div style={{ display: "flex", alignItems: "flex-start", gap: 12 }}>
        <div style={{
          width: 44, height: 44, borderRadius: 10,
          background: tone.bg, border: `1px solid ${tone.bd}`, color: tone.fg,
          display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0,
        }}><IconComp size={20} /></div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <div style={{ fontSize: 14, fontWeight: 600, color: "var(--white)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{app.name}</div>
            {app.status === "needs-attention" && <StatusBadge tone="amber" label="Reauth" size="sm" />}
            {app.syncing && (
              <span title="Syncing" style={{
                display: "inline-flex", alignItems: "center", gap: 4,
                fontSize: 10, color: "var(--harbor-2)",
              }}>
                <span style={{ width: 5, height: 5, borderRadius: 99, background: "var(--harbor-2)" }} className="hd-pulse" />
                live
              </span>
            )}
          </div>
          <div className="micro" style={{ color: "var(--warm-gray)", marginTop: 4 }}>{app.category.toUpperCase()}</div>
        </div>
      </div>
      <p style={{ fontSize: 12.5, color: "var(--warm-gray)", lineHeight: 1.55, margin: 0, minHeight: 36 }}>{app.tagline}</p>
      <Divider />
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8 }}>
        <div style={{ fontSize: 11, color: "var(--warm-gray)", minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", flex: 1 }}>
          {isConnected ? (app.account || "Connected") : "Not connected"}
        </div>
        {isConnected ? (
          <Button variant="ghost" size="sm" onClick={onOpen}>Manage</Button>
        ) : (
          <Button variant="secondary" size="sm" icon={<window.Icon.Plus size={11} />} onClick={onConnect}>Connect</Button>
        )}
      </div>
    </Card>
  );
};

const ConnectedAppCard = ({ app, onOpen, onDisconnect }) => {
  const tone = STATUS_TONES[app.accent || "neutral"];
  const IconComp = window.Icon[app.icon] || window.Icon.Apps;
  return (
    <Card style={{ padding: 0, overflow: "hidden" }}>
      <div style={{
        padding: 16, display: "flex", alignItems: "center", gap: 12,
        borderBottom: "1px solid rgba(255,255,255,0.04)",
      }}>
        <div style={{
          width: 38, height: 38, borderRadius: 9,
          background: tone.bg, border: `1px solid ${tone.bd}`, color: tone.fg,
          display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0,
        }}><IconComp size={17} /></div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 13.5, fontWeight: 600, color: "var(--white)" }}>{app.name}</div>
          <div style={{ fontSize: 11.5, color: "var(--warm-gray)", marginTop: 2, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{app.account}</div>
        </div>
        {app.status === "needs-attention"
          ? <StatusBadge tone="amber" label="Reauth" size="sm" />
          : <StatusBadge tone="green" label="Live" size="sm" />}
      </div>
      <div style={{ padding: "12px 16px", display: "flex", justifyContent: "space-between", alignItems: "center" }}>
        <div style={{ fontSize: 11, color: "var(--warm-gray)" }}>Synced {app.lastSync}</div>
        <div style={{ display: "flex", gap: 6 }}>
          <window.IconButton iconName="Refresh" label="Sync now" />
          <window.IconButton iconName="Settings" label="Configure" onClick={onOpen} />
          <window.IconButton iconName="Trash" label="Disconnect" onClick={onDisconnect} />
        </div>
      </div>
    </Card>
  );
};

const AppDetailModal = ({ app, onClose, onToggle }) => {
  if (!app) return null;
  const tone = STATUS_TONES[app.accent || "neutral"];
  const IconComp = window.Icon[app.icon] || window.Icon.Apps;
  const isConnected = app.status === "connected" || app.status === "needs-attention";

  const exampleScopes = {
    "Storage":      ["Read folder contents", "Mirror new files into intake", "Write back delivery archives"],
    "Review":       ["Read comments + state", "Write timecoded replies", "Trigger draft sync"],
    "Communication":["Post into chosen channel", "DM mentioned reviewers", "Read read-receipts for replies"],
    "NLE":          ["Receive renders via local agent", "Tag exports with project ID", "Open project in editor"],
    "Productivity": ["Read project docs", "Sync briefs both ways", "Read-only calendar push"],
    "Billing":      ["Create invoices on delivery", "Read invoice status", "Send paid receipts to studio"],
    "Capture":      ["Receive recorded clips", "Attach as comments", "Read clip thumbnails"],
    "Automation":   ["Subscribe to webhook events", "Trigger on uploads, approvals, deliveries", "Sign payloads with HMAC"],
  }[app.category] || ["Read public data", "Write events back"];

  return (
    <Modal
      onClose={onClose}
      title={app.name}
      eyebrow={app.category.toUpperCase()}
      maxWidth={580}
      footer={isConnected ? (
        <>
          <Button variant="ghost" size="md" onClick={onClose}>Close</Button>
          <Button variant="ghost" size="md" icon={<window.Icon.Refresh size={12} />}>Re-authorize</Button>
          <Button variant="secondary" size="md" icon={<window.Icon.Trash size={12} />} onClick={() => onToggle(false)}>Disconnect</Button>
        </>
      ) : (
        <>
          <Button variant="ghost" size="md" onClick={onClose}>Cancel</Button>
          <Button variant="primary" size="md" icon={<window.Icon.Zap size={13} />} onClick={() => onToggle(true)}>Connect {app.name}</Button>
        </>
      )}
    >
      <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
        <div style={{ display: "flex", alignItems: "flex-start", gap: 14 }}>
          <div style={{
            width: 58, height: 58, borderRadius: 13,
            background: tone.bg, border: `1px solid ${tone.bd}`, color: tone.fg,
            display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0,
          }}><IconComp size={26} /></div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 13.5, color: "var(--white)", lineHeight: 1.55 }}>{app.tagline}</div>
            {isConnected && app.account && (
              <div style={{ fontSize: 11.5, color: "var(--warm-gray)", marginTop: 8 }}>Connected as <span style={{ color: "var(--white)" }}>{app.account}</span> · Synced {app.lastSync}</div>
            )}
          </div>
        </div>

        <div>
          <div className="micro" style={{ color: "var(--warm-gray)", marginBottom: 10 }}>PERMISSIONS WE'LL ASK FOR</div>
          <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
            {exampleScopes.map((s, i) => (
              <div key={i} style={{
                display: "flex", alignItems: "center", gap: 10,
                padding: "10px 12px", background: "rgba(255,255,255,0.025)",
                border: "1px solid rgba(255,255,255,0.06)", borderRadius: 8,
              }}>
                <window.Icon.Shield size={13} color="var(--harbor-2)" />
                <span style={{ fontSize: 12.5, color: "var(--white)" }}>{s}</span>
              </div>
            ))}
          </div>
        </div>

        {isConnected && (
          <div>
            <div className="micro" style={{ color: "var(--warm-gray)", marginBottom: 10 }}>SCOPE</div>
            <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
              <ToggleRow label="Sync on draft upload"     defaultOn />
              <ToggleRow label="Sync on approval"          defaultOn />
              <ToggleRow label="Notify primary reviewer"   defaultOn={false} />
              <ToggleRow label="Auto-archive on delivery" defaultOn={false} />
            </div>
          </div>
        )}
      </div>
    </Modal>
  );
};

const ToggleRow = ({ label, defaultOn }) => {
  const [on, setOn] = React.useState(defaultOn);
  return (
    <button
      onClick={() => setOn(o => !o)}
      style={{
        display: "flex", alignItems: "center", justifyContent: "space-between",
        padding: "10px 12px", borderRadius: 8, cursor: "pointer",
        background: "rgba(255,255,255,0.025)", border: "1px solid rgba(255,255,255,0.06)",
        color: "var(--white)", fontFamily: "var(--sans)", width: "100%",
      }}
    >
      <span style={{ fontSize: 12.5 }}>{label}</span>
      <span style={{
        width: 32, height: 18, borderRadius: 99,
        background: on ? "var(--harbor)" : "rgba(255,255,255,0.10)",
        position: "relative", transition: "background 160ms ease",
      }}>
        <span style={{
          position: "absolute", top: 2, left: on ? 16 : 2,
          width: 14, height: 14, borderRadius: 99, background: "white",
          transition: "left 160ms ease",
        }} />
      </span>
    </button>
  );
};

window.AppsPage = AppsPage;
