// Live app entry — talks to real OPRT API instead of mock data

const { useState, useEffect } = React;

function adaptInstance(row, i = 0) {
  const hues = [162, 245, 295, 75, 20, 205, 25, 330];
  const h = hues[i % hues.length];
  const initials = (row.display_name || row.name || row.agent_id || "?")
    .split(" ").slice(0, 2).map(w => w[0]).join("").toUpperCase();
  return {
    id: row.agent_id || row.id,
    uuid: row.id,
    name: row.display_name || row.name,
    contact: row.contact,
    email: row.email,
    industry: row.industry,
    telegram: row.telegram_bot_username || "—",
    status: row.status,
    createdAt: (row.created_at || "").slice(0, 10),
    plan: row.plan,
    skills: row.skills || [],
    skillDetails: row.skillDetails || [],
    tokensIn: Number(row.tokens_in ?? 0),
    tokensOut: Number(row.tokens_out ?? 0),
    cost: Number(row.cost_eur ?? 0),
    messages: Number(row.messages ?? 0),
    apiProvider: row.provider,
    model: row.model,
    spark: row.spark || Array(16).fill(0).map((_, i) => 20 + Math.sin(i / 2) * 10 + Math.random() * 10),
    logoBg: `oklch(0.55 0.15 ${h})`,
    logoBg2: `oklch(0.65 0.14 ${h})`,
    initials,
  };
}

function LiveApp() {
  const [route, setRoute] = useState(() => localStorage.getItem("oprt.route") || "dashboard");
  const [instanceId, setInstanceId] = useState(() => localStorage.getItem("oprt.instanceId") || null);
  const [theme, setTheme] = useState(() => localStorage.getItem("oprt.theme") || "dark");
  const [instances, setInstances] = useState([]);
  const [skills, setSkills] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [editMode, setEditMode] = useState(false);
  const [showSettings, setShowSettings] = useState(false);

  useEffect(() => {
    document.documentElement.classList.toggle("light", theme === "light");
    localStorage.setItem("oprt.theme", theme);
  }, [theme]);
  useEffect(() => { localStorage.setItem("oprt.route", route); }, [route]);
  useEffect(() => { if (instanceId) localStorage.setItem("oprt.instanceId", instanceId); }, [instanceId]);

  const loadData = async () => {
    setLoading(true); setError(null);
    try {
      const [ins, sk] = await Promise.all([
        OprtAPI.listInstances(),
        OprtAPI.listSkills(),
      ]);
      const adapted = (ins || []).map(adaptInstance);
      setInstances(adapted);
      setSkills(sk || []);
      window.APP_DATA = {
        INSTANCES: adapted,
        SKILLS: (sk || []).map(s => s.name),
      };
    } catch (e) {
      setError(e.message || String(e));
      window.APP_DATA = window.APP_DATA || { INSTANCES: [], SKILLS: [] };
    } finally { setLoading(false); }
  };

  useEffect(() => { loadData(); }, []);

  useEffect(() => {
    const onMsg = (e) => {
      if (!e.data) return;
      if (e.data.type === "__activate_edit_mode") setEditMode(true);
      if (e.data.type === "__deactivate_edit_mode") setEditMode(false);
    };
    window.addEventListener("message", onMsg);
    window.parent.postMessage({ type: "__edit_mode_available" }, "*");
    return () => window.removeEventListener("message", onMsg);
  }, []);

  const [detailInstance, setDetailInstance] = useState(null);
  const [detailLoading, setDetailLoading] = useState(false);

  const onNav = (r) => { setRoute(r); if (r !== "instance") { setInstanceId(null); setDetailInstance(null); } };
  const openInstance = async (id) => {
    setInstanceId(id); setRoute("instance"); setDetailLoading(true);
    try {
      const listInst = instances.find(i => i.id === id || i.uuid === id);
      const uuid = listInst ? listInst.uuid : id;
      const detail = await OprtAPI.getInstance(uuid);
      const adapted = adaptInstance(detail, instances.findIndex(i => i.uuid === uuid));
      setDetailInstance(adapted);
    } catch (e) {
      setDetailInstance(instances.find(i => i.id === id || i.uuid === id) || null);
    } finally { setDetailLoading(false); }
  };
  const currentInstance = detailInstance || instances.find(i => i.id === instanceId || i.uuid === instanceId);

  let crumbs = [{ label: "OPRT.AI", go: "dashboard" }];
  let view = null;

  if (loading) {
    view = <div className="content full"><div className="panel"><div className="panel-body dim" style={{ padding: 40, textAlign: "center" }}>Lade Daten von <span className="mono">{OprtConfig.get().base}</span>…</div></div></div>;
  } else if (error) {
    view = <ErrorView error={error} onRetry={loadData} onOpenSettings={() => setShowSettings(true)} />;
  } else {
    switch (route) {
      case "dashboard":
      case "instances":
        crumbs.push({ label: "Dashboard" });
        view = <Dashboard instances={instances} onOpenInstance={openInstance} onNav={onNav}/>;
        break;
      case "instance":
        crumbs.push({ label: "Instances", go: "dashboard" }, { label: currentInstance ? currentInstance.name : "—" });
        view = <InstanceDetail instance={currentInstance} onNav={onNav} allSkills={skills} onReload={loadData}/>;
        break;
      case "launch":
        crumbs.push({ label: "Launch new instance" });
        view = <LiveLaunchForm onNav={onNav} onDone={loadData} skills={skills}/>;
        break;
      case "keys":
        crumbs.push({ label: "API keys" });
        view = <KeysView instances={instances} onOpenInstance={openInstance}/>;
        break;
      case "metrics":
        crumbs.push({ label: "Metrics" });
        view = <MetricsView instances={instances}/>;
        break;
      case "skills":
        crumbs.push({ label: "Skills library" });
        view = <SkillsView instances={instances}/>;
        break;
      case "billing":
        crumbs.push({ label: "Billing" });
        view = <BillingView instances={instances}/>;
        break;
      default:
        view = <Dashboard instances={instances} onOpenInstance={openInstance} onNav={onNav}/>;
    }
  }

  const topRight = (
    <div className="row gap-6">
      <button className="btn sm" onClick={loadData} title="Reload"><Icon name="refresh" size={14}/></button>
      <button className="btn sm" onClick={() => setShowSettings(true)} title="API settings"><Icon name="settings" size={14}/></button>
      <button className="btn sm" onClick={() => setTheme(theme === "light" ? "dark" : "light")} title="Toggle theme">
        <Icon name={theme === "light" ? "moon" : "sun"} size={14}/>
      </button>
    </div>
  );

  return (
    <div className="app" data-screen-label={route}>
      <Sidebar route={route} onNav={onNav} counts={{ instances: instances.length, skills: skills.length }}/>
      <div className="main">
        <Topbar crumbs={crumbs} onNav={onNav} right={topRight}/>
        {view}
      </div>
      {showSettings && <SettingsModal onClose={() => setShowSettings(false)} onSaved={loadData}/>}
      {editMode && <TweaksPanel theme={theme} setTheme={setTheme}/>}
    </div>
  );
}

function ErrorView({ error, onRetry, onOpenSettings }) {
  const { base } = OprtConfig.get();
  return (
    <div className="content full">
      <div className="panel" style={{ borderColor: "oklch(from var(--rose) l c h / 0.4)" }}>
        <div className="panel-head"><h3 style={{ color: "var(--rose)" }}>Verbindung zur API fehlgeschlagen</h3></div>
        <div className="panel-body col" style={{ gap: 12 }}>
          <div className="dim">Endpoint: <span className="mono">{base}</span></div>
          <div className="secret"><span className="val" style={{ color: "var(--rose)" }}>{error}</span></div>
          <div className="dim" style={{ fontSize: 12 }}>
            Prüfe: API erreichbar? Bearer-Token gesetzt? CORS erlaubt <span className="mono">{window.location.origin}</span>?
          </div>
          <div className="row gap-6">
            <button className="btn primary" onClick={onRetry}><Icon name="refresh" size={13}/> Erneut versuchen</button>
            <button className="btn" onClick={onOpenSettings}><Icon name="settings" size={13}/> API-Einstellungen</button>
          </div>
        </div>
      </div>
    </div>
  );
}

function SettingsModal({ onClose, onSaved }) {
  const cfg = OprtConfig.get();
  const [base, setBase] = useState(cfg.base);
  const [token, setToken] = useState(cfg.token);
  const [showTok, setShowTok] = useState(false);
  const [testing, setTesting] = useState(false);
  const [testResult, setTestResult] = useState(null);

  const save = () => { OprtConfig.set({ base, token }); onClose(); onSaved(); };
  const test = async () => {
    setTesting(true); setTestResult(null);
    OprtConfig.set({ base, token });
    try {
      const r = await OprtAPI.health();
      setTestResult(r ? "ok" : "fail");
    } catch (e) { setTestResult("fail: " + e.message); }
    finally { setTesting(false); }
  };

  return (
    <div style={{
      position: "fixed", inset: 0, background: "oklch(0 0 0 / 0.5)",
      display: "grid", placeItems: "center", zIndex: 100,
    }} onClick={onClose}>
      <div className="panel" style={{ width: 540, maxWidth: "90vw" }} onClick={(e) => e.stopPropagation()}>
        <div className="panel-head">
          <h3>API-Verbindung</h3>
          <button className="btn sm ghost right" onClick={onClose}><Icon name="x" size={14}/></button>
        </div>
        <div className="panel-body col" style={{ gap: 14 }}>
          <div className="form-row">
            <label className="label">API-Endpoint</label>
            <input className="input mono" value={base} onChange={(e) => setBase(e.target.value)} placeholder="https://launch.quinn.chat"/>
            <div className="hint">Die Basis-URL deiner OPRT Launch Board API.</div>
          </div>
          <div className="form-row">
            <label className="label">Bearer Token</label>
            <div className="secret">
              <input className="grow mono" style={{ background: "transparent", border: 0, outline: 0, color: "var(--text)" }}
                type={showTok ? "text" : "password"} value={token} onChange={(e) => setToken(e.target.value)}/>
              <button className="btn sm ghost" onClick={() => setShowTok(!showTok)}><Icon name={showTok ? "eye-off" : "eye"} size={13}/></button>
            </div>
            <div className="hint">Aus <span className="mono">agency_user_tokens</span>. Dev-Token initial: <span className="mono">dev-token-please-change</span>.</div>
          </div>
          {testResult && (
            <div className={"banner " + (testResult === "ok" ? "ok" : "")} style={testResult !== "ok" ? { background: "oklch(from var(--rose) l c h / 0.08)", borderColor: "oklch(from var(--rose) l c h / 0.3)" } : {}}>
              <Icon name={testResult === "ok" ? "check" : "alert"} size={13}/>
              <span>{testResult === "ok" ? "Verbindung ok!" : "Fehler: " + testResult}</span>
            </div>
          )}
          <div className="row gap-6">
            <button className="btn" onClick={test} disabled={testing}>{testing ? "Teste…" : "Verbindung testen"}</button>
            <button className="btn primary right" onClick={save}><Icon name="check" size={13}/> Speichern</button>
          </div>
        </div>
      </div>
    </div>
  );
}

function LiveLaunchForm({ onNav, onDone, skills }) {
  const skillNames = skills.map(s => s.name);
  const [state, setState] = useState({
    companyName: "", agentId: "", contact: "", email: "", industry: "",
    plan: "Growth", telegramToken: "",
    provider: "openai", apiKey: "", model: "gpt-4.1",
    skills: new Set(skillNames),
  });
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState(null);
  const [slugEdited, setSlugEdited] = useState(false);

  const set = (k, v) => setState(s => ({ ...s, [k]: v }));
  const onCompany = (v) => setState(s => ({ ...s, companyName: v, agentId: slugEdited ? s.agentId : v.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") }));
  const toggleSkill = (skill) => setState(s => { const n = new Set(s.skills); n.has(skill) ? n.delete(skill) : n.add(skill); return { ...s, skills: n }; });

  const submit = async () => {
    setSubmitting(true); setError(null);
    try {
      const body = { ...state, skills: [...state.skills] };
      const r = await OprtAPI.createInstance(body);
      onDone && onDone();
      onNav("instance");
      setTimeout(() => { localStorage.setItem("oprt.instanceId", r.instanceId); location.reload(); }, 200);
    } catch (e) {
      setError(e.message);
      setSubmitting(false);
    }
  };

  const valid = state.companyName && state.agentId && state.contact && state.email && state.telegramToken && state.apiKey;

  return (
    <div className="content full" style={{ maxWidth: 880 }}>
      <div className="page-head">
        <div>
          <h1 className="page-title">Launch new instance</h1>
          <p className="page-sub">Provisioniert eine neue OpenClaw-Instanz über <span className="mono">POST /api/instances</span></p>
        </div>
        <button className="btn ghost" onClick={() => onNav("dashboard")}><Icon name="x" size={14}/> Abbrechen</button>
      </div>

      {error && (
        <div className="banner" style={{ background: "oklch(from var(--rose) l c h / 0.08)", borderColor: "oklch(from var(--rose) l c h / 0.3)" }}>
          <Icon name="alert" size={14} color="var(--rose)"/> <span>{error}</span>
        </div>
      )}

      <div className="panel">
        <div className="panel-body" style={{ padding: 24 }}>
          <div className="form-grid">
            <div>
              <div className="section-title">Kunde</div>
              <div className="form-row two">
                <div className="form-row"><label className="label">Firmenname *</label><input className="input" value={state.companyName} onChange={(e) => onCompany(e.target.value)}/></div>
                <div className="form-row"><label className="label">Agent ID *</label><input className="input mono" value={state.agentId} onChange={(e) => { setSlugEdited(true); set("agentId", e.target.value); }}/></div>
              </div>
              <div className="form-row two" style={{ marginTop: 14 }}>
                <div className="form-row"><label className="label">Kontakt *</label><input className="input" value={state.contact} onChange={(e) => set("contact", e.target.value)}/></div>
                <div className="form-row"><label className="label">E-Mail *</label><input className="input" type="email" value={state.email} onChange={(e) => set("email", e.target.value)}/></div>
              </div>
              <div className="form-row two" style={{ marginTop: 14 }}>
                <div className="form-row"><label className="label">Branche</label><input className="input" value={state.industry} onChange={(e) => set("industry", e.target.value)}/></div>
                <div className="form-row"><label className="label">Plan</label><select className="select" value={state.plan} onChange={(e) => set("plan", e.target.value)}><option>Trial</option><option>Starter</option><option>Growth</option><option>Enterprise</option></select></div>
              </div>
            </div>

            <div>
              <div className="section-title">Telegram</div>
              <div className="form-row"><label className="label">Bot-Token *</label><input className="input mono" placeholder="123456789:ABCdef…" value={state.telegramToken} onChange={(e) => set("telegramToken", e.target.value)}/></div>
            </div>

            <div>
              <div className="section-title">Modell &amp; API-Key</div>
              <div className="form-row"><label className="label">Provider</label>
                <div className="segmented" style={{ gridTemplateColumns: "1fr 1fr", maxWidth: 280 }}>
                  <div className={"seg " + (state.provider === "openai" ? "on" : "")} onClick={() => set("provider", "openai")}>OpenAI</div>
                  <div className={"seg " + (state.provider === "anthropic" ? "on" : "")} onClick={() => set("provider", "anthropic")}>Anthropic</div>
                </div>
              </div>
              <div className="form-row two" style={{ marginTop: 14 }}>
                <div className="form-row"><label className="label">API Key *</label><input className="input mono" type="password" value={state.apiKey} onChange={(e) => set("apiKey", e.target.value)}/></div>
                <div className="form-row"><label className="label">Modell</label><select className="select" value={state.model} onChange={(e) => set("model", e.target.value)}>
                  {state.provider === "openai" ? (<><option>gpt-4.1</option><option>gpt-4.1-mini</option><option>o3-mini</option></>) : (<><option>claude-sonnet-4.5</option><option>claude-haiku-4.5</option><option>claude-opus-4.1</option></>)}
                </select></div>
              </div>
            </div>

            <div>
              <div className="row" style={{ justifyContent: "space-between", marginBottom: 10, borderBottom: "1px solid var(--border)", paddingBottom: 8 }}>
                <div className="section-title" style={{ border: 0, margin: 0, padding: 0 }}>Skills · {state.skills.size}/{skillNames.length}</div>
                <div className="row gap-6" style={{ fontSize: 12 }}>
                  <a style={{ color: "var(--brand)", cursor: "pointer" }} onClick={() => set("skills", new Set(skillNames))}>Alle</a>
                  <span className="dim">·</span>
                  <a style={{ color: "var(--brand)", cursor: "pointer" }} onClick={() => set("skills", new Set())}>Keine</a>
                </div>
              </div>
              <div className="checkbox-grid">
                {skillNames.map((s) => {
                  const on = state.skills.has(s);
                  return <label key={s} className={"check " + (on ? "on" : "")}><input type="checkbox" checked={on} onChange={() => toggleSkill(s)}/><span>{s}</span></label>;
                })}
              </div>
            </div>

            <div className="row" style={{ gap: 10, borderTop: "1px solid var(--border)", paddingTop: 18 }}>
              <button className="btn primary" disabled={!valid || submitting} onClick={submit} style={{ opacity: (valid && !submitting) ? 1 : 0.5 }}>
                <Icon name="rocket" size={14}/> {submitting ? "Provisioniere…" : "Instanz starten"}
              </button>
              <button className="btn" onClick={() => onNav("dashboard")}>Abbrechen</button>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

function TweaksPanel({ theme, setTheme }) {
  return (
    <div className="tweaks-panel">
      <h4>Tweaks</h4>
      <div><div className="label" style={{ marginBottom: 6 }}>Theme</div>
        <div className="segmented">
          <div className={"seg " + (theme === "dark" ? "on" : "")} onClick={() => setTheme("dark")}><Icon name="moon" size={12} style={{ verticalAlign: "-2px", marginRight: 4 }}/>Dark</div>
          <div className={"seg " + (theme === "light" ? "on" : "")} onClick={() => setTheme("light")}><Icon name="sun" size={12} style={{ verticalAlign: "-2px", marginRight: 4 }}/>Light</div>
        </div>
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<LiveApp/>);
