#!/usr/bin/env node
import "dotenv/config";
import blessed from "blessed";
import contrib from "blessed-contrib";
import { EventEmitter } from "events";
import { terminalCompat } from "./terminal-compat.js";
import { SessionMonitor } from "./components/session-monitor.js";
import { TaskBoard } from "./components/task-board.js";
import { FrameVisualizer } from "./components/frame-visualizer.js";
import { SubagentFleet } from "./components/subagent-fleet.js";
import { PRTracker } from "./components/pr-tracker.js";
import { AnalyticsPanel } from "./components/analytics-panel.js";
import { DataService } from "./services/data-service.js";
import { WebSocketClient } from "./services/websocket-client.js";
function getEnv(key, defaultValue) {
  const value = process.env[key];
  if (value === void 0) {
    if (defaultValue !== void 0) return defaultValue;
    throw new Error(`Environment variable ${key} is required`);
  }
  return value;
}
function getOptionalEnv(key) {
  return process.env[key];
}
terminalCompat.configureEnvironment();
class StackMemoryTUI extends EventEmitter {
  screen;
  grid;
  components;
  dataService;
  wsClient;
  config;
  refreshInterval = null;
  constructor(config = {}) {
    super();
    this.config = {
      refreshInterval: 1e3,
      wsUrl: "ws://localhost:8080",
      theme: "dark",
      ...config
    };
    this.components = /* @__PURE__ */ new Map();
    this.dataService = new DataService();
    this.wsClient = new WebSocketClient(this.config.wsUrl);
    this.screen = this.createScreen();
    this.grid = this.createGrid();
    this.initializeComponents();
    this.setupEventHandlers();
  }
  createScreen() {
    const blessedConfig = terminalCompat.getBlessedConfig();
    const screen = blessed.screen({
      ...blessedConfig,
      autoPadding: true
    });
    const header = blessed.box({
      parent: screen,
      top: 0,
      left: 0,
      width: "100%",
      height: 3,
      content: "{center}\u{1F680} StackMemory TUI Dashboard v1.0.0 | [u]pdate status | [c]laude task | [s]ync | [q]uit{/center}",
      tags: true,
      style: {
        fg: "white",
        bg: "blue",
        bold: true
      }
    });
    return screen;
  }
  createGrid() {
    const grid = new contrib.grid({
      rows: 12,
      cols: 12,
      screen: this.screen
    });
    return grid;
  }
  initializeComponents() {
    const sessionMonitor = new SessionMonitor(
      this.grid.set(0, 0, 4, 6, blessed.box, {
        label: "\u{1F4CA} Sessions",
        border: { type: "line" },
        style: { border: { fg: "cyan" } }
      })
    );
    this.components.set("sessions", sessionMonitor);
    const taskBoard = new TaskBoard(
      this.grid.set(0, 6, 4, 6, blessed.box, {
        label: "\u{1F4CB} Linear Tasks",
        border: { type: "line" },
        style: { border: { fg: "green" } }
      })
    );
    this.components.set("tasks", taskBoard);
    const frameContainer = this.grid.set(4, 0, 4, 6, blessed.box, {
      label: "\u{1F5C2}\uFE0F Frame Storage",
      border: { type: "line" },
      style: { border: { fg: "yellow" } }
    });
    const frameTree = contrib.tree({
      parent: frameContainer,
      top: 0,
      left: 0,
      width: "100%-2",
      height: "100%-2",
      style: {
        text: "green",
        selected: {
          bg: "yellow",
          fg: "black"
        }
      },
      template: {
        lines: true
      },
      label: ""
    });
    const frameViz = new FrameVisualizer(frameTree);
    this.components.set("frames", frameViz);
    const subagentFleet = new SubagentFleet(
      this.grid.set(4, 6, 4, 6, blessed.box, {
        label: "\u{1F916} Subagent Fleet",
        border: { type: "line" },
        style: { border: { fg: "magenta" } }
      })
    );
    this.components.set("subagents", subagentFleet);
    const prTracker = new PRTracker(
      this.grid.set(8, 0, 2, 6, blessed.list, {
        label: "\u{1F500} PR/Issues",
        border: { type: "line" },
        style: { border: { fg: "red" } },
        scrollable: true,
        mouse: true
      })
    );
    this.components.set("prs", prTracker);
    const analytics = new AnalyticsPanel(
      this.grid.set(8, 6, 2, 6, contrib.line, {
        label: "\u{1F4C8} Analytics",
        border: { type: "line" },
        style: {
          border: { fg: "white" },
          line: "yellow",
          text: "green",
          baseline: "black"
        },
        showLegend: true,
        wholeNumbersOnly: false
      })
    );
    this.components.set("analytics", analytics);
    const statusBar = blessed.box({
      parent: this.screen,
      bottom: 0,
      left: 0,
      width: "100%",
      height: 2,
      tags: true,
      style: {
        fg: "white",
        bg: "black"
      }
    });
    this.components.set("status", statusBar);
    this.updateStatusBar("Ready");
  }
  setupEventHandlers() {
    this.screen.key(["q", "C-c"], () => {
      this.cleanup();
      process.exit(0);
    });
    this.screen.key(["r", "C-r"], () => {
      this.refresh();
    });
    this.screen.key(["tab"], () => {
      this.focusNext();
    });
    this.screen.key(["S-tab"], () => {
      this.focusPrevious();
    });
    this.screen.key(["1"], () => this.showView("sessions"));
    this.screen.key(["2"], () => this.showView("tasks"));
    this.screen.key(["3"], () => this.showView("frames"));
    this.screen.key(["4"], () => this.showView("subagents"));
    this.screen.key(["5"], () => this.showView("prs"));
    this.screen.key(["6"], () => this.showView("analytics"));
    this.wsClient.on("session:update", (data) => {
      this.components.get("sessions")?.update(data);
    });
    this.wsClient.on("task:update", (data) => {
      this.components.get("tasks")?.update(data);
    });
    this.wsClient.on("frame:update", (data) => {
      this.components.get("frames")?.update(data);
    });
    this.wsClient.on("agent:status", (data) => {
      this.components.get("subagents")?.update(data);
    });
    this.wsClient.on("pr:update", (data) => {
      this.components.get("prs")?.update(data);
    });
    this.dataService.on("data:ready", () => {
      this.updateAll();
    });
    this.dataService.on("error", (error) => {
      this.showError(error.message);
    });
  }
  async updateAll() {
    try {
      const [sessions, tasks, frames, agents, prs, issues, analytics] = await Promise.all([
        this.dataService.getSessions(),
        this.dataService.getTasks(),
        this.dataService.getFrames(),
        this.dataService.getAgents(),
        this.dataService.getPRs(),
        this.dataService.getIssues(),
        this.dataService.getAnalytics()
      ]);
      this.components.get("sessions")?.update(sessions);
      this.components.get("tasks")?.update(tasks);
      this.components.get("frames")?.update(frames);
      this.components.get("subagents")?.update(agents);
      this.components.get("prs")?.update({ prs, issues });
      this.components.get("analytics")?.update(analytics);
      this.updateStatusBar(`Last updated: ${(/* @__PURE__ */ new Date()).toLocaleTimeString()}`);
      this.screen.render();
    } catch (error) {
      this.showError(`Update failed: ${error.message}`);
    }
  }
  refresh() {
    this.updateStatusBar("Refreshing...");
    this.updateAll();
  }
  focusNext() {
    const components = Array.from(this.components.values());
    const currentIndex = components.findIndex((c) => c.hasFocus?.());
    const nextIndex = (currentIndex + 1) % components.length;
    components[nextIndex]?.focus?.();
    this.screen.render();
  }
  focusPrevious() {
    const components = Array.from(this.components.values());
    const currentIndex = components.findIndex((c) => c.hasFocus?.());
    const prevIndex = currentIndex <= 0 ? components.length - 1 : currentIndex - 1;
    components[prevIndex]?.focus?.();
    this.screen.render();
  }
  showView(viewName) {
    const component = this.components.get(viewName);
    if (component) {
      component.focus?.();
      component.show?.();
      this.updateStatusBar(`Viewing: ${viewName}`);
      this.screen.render();
    }
  }
  updateStatusBar(message) {
    const statusBar = this.components.get("status");
    if (statusBar) {
      const shortcuts = "{yellow-fg}[q]{/} Quit | {yellow-fg}[r]{/} Refresh | {yellow-fg}[Tab]{/} Navigate | {yellow-fg}[1-6]{/} Views";
      statusBar.setContent(`{bold}${message}{/} | ${shortcuts}`);
      this.screen.render();
    }
  }
  showError(message) {
    const msg = blessed.message({
      parent: this.screen,
      border: "line",
      height: "shrink",
      width: "half",
      top: "center",
      left: "center",
      label: "{red-fg}Error{/}",
      tags: true,
      hidden: true
    });
    msg.display(message, () => {
      msg.destroy();
      this.screen.render();
    });
  }
  async start() {
    try {
      const termInfo = terminalCompat.getTerminalInfo();
      const warnings = terminalCompat.getWarnings();
      if (warnings.length > 0) {
        console.log("\u26A0\uFE0F  Terminal Compatibility Warnings:");
        warnings.forEach((w) => console.log(`   \u2022 ${w}`));
        console.log("");
        await new Promise((resolve) => setTimeout(resolve, 2e3));
      }
      if (process.env["DEBUG"] || process.env["TUI_DEBUG"]) {
        console.log("\u{1F50D} Terminal Capabilities:");
        console.log(`   ${terminalCompat.getCapabilitiesString()}`);
        console.log("");
        await new Promise((resolve) => setTimeout(resolve, 1e3));
      }
      try {
        await this.wsClient.connect();
      } catch (wsError) {
        console.log("\u26A0\uFE0F  Running in offline mode (no WebSocket connection)");
      }
      await this.dataService.initialize();
      if (this.config.refreshInterval > 0) {
        this.refreshInterval = setInterval(() => {
          this.updateAll().catch((error) => {
            if (process.env["DEBUG"]) {
              console.error("Update error:", error);
            }
          });
        }, this.config.refreshInterval);
      }
      await this.updateAll();
      this.screen.render();
    } catch (error) {
      console.error("\n\u274C TUI startup error:", error);
      if (error instanceof Error) {
        console.error("Error details:", error.message);
        if (process.env["DEBUG"]) {
          console.error("Stack trace:", error.stack);
        }
      }
      throw error;
    }
  }
  cleanup() {
    if (this.refreshInterval) {
      clearInterval(this.refreshInterval);
    }
    this.wsClient.disconnect();
    this.dataService.cleanup();
  }
}
const isMainModule = typeof process !== "undefined" && process.argv && process.argv[1] && (import.meta.url === `file://${process.argv[1]}` || process.argv[1].endsWith("/index.js"));
if (isMainModule) {
  if (!terminalCompat.isCompatible()) {
    console.error("\u274C Terminal is not compatible with TUI mode");
    console.error(
      "   Please use the dashboard command instead: stackmemory dashboard --watch"
    );
    process.exit(1);
  }
  process.on("uncaughtException", (error) => {
    console.error("\n\u274C TUI Error:", error.message || error);
    console.error("Error type:", error.constructor.name);
    if (error.stack) {
      console.error("Stack trace:", error.stack);
    }
    console.error(
      "\n\u{1F4A1} Try the simpler dashboard instead: stackmemory dashboard --watch"
    );
    process.exit(1);
  });
  process.on("unhandledRejection", (reason, promise) => {
    console.error("\n\u274C Unhandled promise rejection at:", promise);
    console.error("Reason:", reason);
    if (reason instanceof Error) {
      console.error("Stack trace:", reason.stack);
    }
    console.error(
      "\n\u{1F4A1} Try the simpler dashboard instead: stackmemory dashboard --watch"
    );
    process.exit(1);
  });
  let tui;
  try {
    tui = new StackMemoryTUI({
      refreshInterval: 2e3,
      wsUrl: process.env["STACKMEMORY_WS_URL"] || "ws://localhost:8080"
    });
  } catch (constructorError) {
    console.error(
      "\n\u274C Failed to create TUI:",
      constructorError.message || constructorError
    );
    if (constructorError.stack) {
      console.error("Stack trace:", constructorError.stack);
    }
    console.error(
      "\n\u{1F4A1} Try the simpler dashboard instead: stackmemory dashboard --watch"
    );
    process.exit(1);
  }
  tui.start().catch((error) => {
    console.error("\n\u274C Failed to start TUI:", error.message || error);
    if (error.stack) {
      console.error("Stack trace:", error.stack);
    }
    console.error(
      "\n\u{1F4A1} Try the simpler dashboard instead: stackmemory dashboard --watch"
    );
    process.exit(1);
  });
  process.on("SIGINT", () => {
    tui.cleanup();
    process.exit(0);
  });
}
export {
  StackMemoryTUI
};
//# sourceMappingURL=index.js.map
