// App root: state, theme, filter popover, drawer wiring, Tweaks.
// Adapted to render off live data from /state + /events.

const TWEAKS_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accentHue": 264,
  "density": "medium",
  "showActiveHint": true,
  "columnTone": "subtle"
}/*EDITMODE-END*/;

function useLiveData() {
  const [, force] = React.useReducer((x) => x + 1, 0);
  React.useEffect(() => {
    const cb = () => force();
    window.addEventListener("cstl:update", cb);
    return () => window.removeEventListener("cstl:update", cb);
  }, []);
}

function App() {
  useLiveData();

  const [theme, setTheme] = React.useState(() => localStorage.getItem("theme") || "light");
  React.useEffect(() => {
    document.documentElement.setAttribute("data-theme", theme);
    localStorage.setItem("theme", theme);
  }, [theme]);

  const [projectId, setProjectId] = React.useState(null);
  const projects = window.PROJECTS || [];
  React.useEffect(() => {
    if (!projectId && projects.length > 0) {
      setProjectId(window.CURRENT_PROJECT_ID || projects[0].id);
    }
  }, [projects.length, projectId]);

  const project = projects.find((p) => p.id === projectId) || projects[0] || {
    id: "_empty", name: "(no projects yet)", icon: "·", tasks: [], visibility: "private", shareSlug: "",
  };

  const [openTask, setOpenTask] = React.useState(null);
  const [openAgent, setOpenAgent] = React.useState(null);
  const [configureAgent, setConfigureAgent] = React.useState(null);
  const [shareProject, setShareProject] = React.useState(null);
  const [filter, setFilter] = React.useState({ assignee: null, needsDecisionOnly: false, activeOnly: false });
  const [filterOpen, setFilterOpen] = React.useState(false);
  const [mobileNavOpen, setMobileNavOpen] = React.useState(false);
  React.useEffect(() => {
    document.body.classList.toggle("mobile-nav-open", mobileNavOpen);
    return () => document.body.classList.remove("mobile-nav-open");
  }, [mobileNavOpen]);

  const tweaks = window.useTweaks ? window.useTweaks(TWEAKS_DEFAULTS) : [TWEAKS_DEFAULTS, () => {}];
  const [tw, setTw] = tweaks;

  React.useEffect(() => {
    const root = document.documentElement;
    if (tw.accentHue != null) {
      root.style.setProperty("--accent", `oklch(${theme === "dark" ? "72%" : "58%"} 0.16 ${tw.accentHue})`);
      root.style.setProperty("--accent-soft", `oklch(${theme === "dark" ? "28%" : "96%"} ${theme === "dark" ? "0.07" : "0.02"} ${tw.accentHue})`);
      root.style.setProperty("--accent-text", `oklch(${theme === "dark" ? "80%" : "46%"} ${theme === "dark" ? "0.14" : "0.16"} ${tw.accentHue})`);
    }
  }, [tw.accentHue, theme]);

  const handleOpenTask = (taskId, pid) => {
    const targetPid = pid || project.id;
    if (pid && pid !== projectId) setProjectId(pid);
    setOpenTask({ projectId: targetPid, taskId });
  };

  const drawerProject = openTask ? (window.PROJECTS || []).find((p) => p.id === openTask.projectId) : null;
  const drawerTask = openTask && drawerProject ? drawerProject.tasks.find((t) => t.id === openTask.taskId) : null;

  const assigneeIds = Array.from(new Set((project.tasks || []).map((t) => t.assignee).filter(Boolean)));
  const needsCount = (project.tasks || []).filter((t) => t.needs_decision).length;

  const filterCount =
    (filter.assignee ? 1 : 0) +
    (filter.needsDecisionOnly ? 1 : 0) +
    (filter.activeOnly ? 1 : 0);

  return (
    <div className={"app" + (mobileNavOpen ? " nav-open" : "")}>
      <div
        className={"sidebar-scrim" + (mobileNavOpen ? " open" : "")}
        onClick={() => setMobileNavOpen(false)}
      />

      <window.Sidebar
        projects={window.PROJECTS || []}
        currentProjectId={projectId}
        onSelectProject={(id) => { setProjectId(id); setOpenTask(null); setMobileNavOpen(false); }}
        activity={window.ACTIVITY || []}
        onOpenTask={(pid, tid) => { handleOpenTask(tid, pid); setMobileNavOpen(false); }}
        onOpenAgent={(id) => { setOpenAgent(id); setMobileNavOpen(false); }}
        theme={theme}
        onToggleTheme={() => setTheme(theme === "light" ? "dark" : "light")}
        mobileOpen={mobileNavOpen}
        onCloseMobile={() => setMobileNavOpen(false)}
      />

      <div className="main">
        <div className="topbar" style={{ position: "relative" }}>
          <button
            className="icon-btn nav-toggle"
            onClick={() => setMobileNavOpen((v) => !v)}
            aria-label="Open navigation"
            title="Menu"
          >
            <window.Icon.Menu />
          </button>

          <div className="crumbs">
            <span>Workspace</span>
            <span className="crumb-sep">/</span>
            <span className="current">{project.name}</span>
            {project.visibility === "public" && (
              <span className="share-pill" title="Public — anyone with the link can view"><span className="dot" />Public</span>
            )}
          </div>

          <div className="topbar-search">
            <window.Icon.Search />
            <input placeholder={`Search ${project.name}…`} />
            <kbd>⌘K</kbd>
          </div>

          <div className="topbar-spacer" />

          <button
            className={"filter-pill" + (filterCount > 0 ? " active" : "")}
            onClick={() => setFilterOpen((v) => !v)}
          >
            <window.Icon.Filter />
            Filter{filterCount > 0 ? ` · ${filterCount}` : ""}
          </button>

          <button
            className="filter-pill"
            onClick={() => setFilter((f) => ({ ...f, needsDecisionOnly: !f.needsDecisionOnly }))}
            style={filter.needsDecisionOnly ? { color: "var(--warn-text)", borderColor: "oklch(from var(--warn) l c h / 0.4)", background: "var(--warn-soft)" } : {}}
          >
            <span style={{ width: 6, height: 6, borderRadius: "50%", background: "var(--warn)", display: "inline-block" }} />
            Needs me
            {needsCount > 0 && <span className="needs-count">{needsCount}</span>}
          </button>

          {project.id !== "_empty" && (
            <button
              className="filter-pill"
              onClick={() => setShareProject(project)}
              title="Share project"
            >
              Share
            </button>
          )}

          <button
            className="icon-btn"
            onClick={() => setTheme(theme === "light" ? "dark" : "light")}
            title="Toggle theme"
          >
            {theme === "light" ? <window.Icon.Moon /> : <window.Icon.Sun />}
          </button>

          {filterOpen && (
            <div className="filter-pop" onMouseLeave={() => setFilterOpen(false)}>
              <div
                className={"filter-pop-row" + (filter.activeOnly ? " on" : "")}
                onClick={() => setFilter((f) => ({ ...f, activeOnly: !f.activeOnly }))}
              >
                <span style={{ width: 7, height: 7, borderRadius: "50%", background: "var(--good)", display: "inline-block" }} />
                <span>Active agents only</span>
                <span className="check">✓</span>
              </div>
              <div style={{ height: 1, background: "var(--border)", margin: "4px 0" }} />
              <div style={{ padding: "6px 10px 4px", fontSize: 10.5, textTransform: "uppercase", letterSpacing: "0.06em", color: "var(--text-faint)" }}>
                Assignee
              </div>
              <div
                className={"filter-pop-row" + (filter.assignee === null ? " on" : "")}
                onClick={() => setFilter((f) => ({ ...f, assignee: null }))}
              >
                <span style={{ width: 18 }} />
                <span>Anyone</span>
                <span className="check">✓</span>
              </div>
              {assigneeIds.map((id) => {
                const a = (window.AGENTS || {})[id];
                if (!a) return null;
                return (
                  <div
                    key={id}
                    className={"filter-pop-row" + (filter.assignee === id ? " on" : "")}
                    onClick={() => setFilter((f) => ({ ...f, assignee: id }))}
                  >
                    <window.Avatar who={id} size={18} />
                    <span>{a.name}</span>
                    <span className="check">✓</span>
                  </div>
                );
              })}
            </div>
          )}
        </div>

        <window.Board
          project={project}
          filter={filter}
          onOpenTask={(tid) => handleOpenTask(tid)}
          onConfirmDecision={async (task, choiceIdx) => {
            const opts = task.decision_options || [];
            const value = (choiceIdx != null && opts[choiceIdx]) || opts[0] || "yes";
            if (task.decision_request_id) {
              await window.api.respondInput(task.decision_request_id, { approved: true, value });
            }
          }}
        />
      </div>

      <window.TaskDrawer
        task={drawerTask}
        project={drawerProject}
        onClose={() => setOpenTask(null)}
        onOpenAgent={(id) => setOpenAgent(id)}
      />

      <window.AgentProfile
        agentId={openAgent}
        onClose={() => setOpenAgent(null)}
        onOpenTask={(pid, tid) => { setOpenAgent(null); handleOpenTask(tid, pid); }}
        onConfigure={(id) => { setOpenAgent(null); setConfigureAgent(id); }}
      />

      <window.AgentConfigure
        agentId={configureAgent}
        onClose={() => setConfigureAgent(null)}
      />

      <window.ShareModal
        project={shareProject}
        onClose={() => setShareProject(null)}
        onChange={() => {}}
      />

      {window.DialogHost && <window.DialogHost />}

      {window.TweaksPanel && (
        <window.TweaksPanel title="Tweaks">
          <window.TweakSection title="Theme">
            <window.TweakRadio
              label="Mode"
              value={theme}
              options={[{ value: "light", label: "Light" }, { value: "dark", label: "Dark" }]}
              onChange={setTheme}
            />
            <window.TweakSlider
              label="Accent hue"
              min={0} max={360} step={1}
              value={tw.accentHue}
              onChange={(v) => setTw({ accentHue: v })}
              format={(v) => `${v}°`}
            />
          </window.TweakSection>
          <window.TweakSection title="Filters">
            <window.TweakToggle
              label="Active agents only"
              value={filter.activeOnly}
              onChange={(v) => setFilter((f) => ({ ...f, activeOnly: v }))}
            />
            <window.TweakToggle
              label="Needs human only"
              value={filter.needsDecisionOnly}
              onChange={(v) => setFilter((f) => ({ ...f, needsDecisionOnly: v }))}
            />
          </window.TweakSection>
        </window.TweaksPanel>
      )}
    </div>
  );
}

function ensureRender() {
  if (!window.Board || !window.Sidebar || !window.TaskDrawer || !window.AgentProfile || !window.AgentConfigure || !window.ShareModal) {
    setTimeout(ensureRender, 30);
    return;
  }
  const root = ReactDOM.createRoot(document.getElementById("root"));
  root.render(<App />);
}
ensureRender();
