#!/usr/bin/env node

// src/hub/renderer.ts
import chalk from "chalk";
var ROLE_COLORS = [
  chalk.cyan,
  chalk.magenta,
  chalk.yellow,
  chalk.green,
  chalk.blue,
  chalk.red,
  chalk.rgb(255, 165, 0),
  // orange
  chalk.rgb(148, 103, 189)
  // purple
];
var colorMap = /* @__PURE__ */ new Map();
function assignRoleColors(roles) {
  colorMap.clear();
  roles.forEach((role, i) => {
    if (role.color && chalk[role.color]) {
      colorMap.set(role.id, chalk[role.color]);
    } else {
      colorMap.set(role.id, ROLE_COLORS[i % ROLE_COLORS.length]);
    }
  });
}
function renderHubBanner(topic, roles, maxRounds, contextFiles) {
  console.log();
  console.log(chalk.bold.white("  \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
  console.log(chalk.bold.white("  \u2551") + chalk.bold.cyan("  \u{1F3DB}\uFE0F  AI-CLI Multi-Agent Hub \u2014 Discussion Mode              ") + chalk.bold.white("\u2551"));
  console.log(chalk.bold.white("  \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
  console.log(chalk.bold.white("  \u2551") + chalk.dim(`  Topic: ${truncate(topic, 52)}`.padEnd(62)) + chalk.bold.white("\u2551"));
  console.log(chalk.bold.white("  \u2551") + chalk.dim(`  Rounds: up to ${maxRounds}`.padEnd(62)) + chalk.bold.white("\u2551"));
  if (contextFiles && contextFiles.length > 0) {
    console.log(chalk.bold.white("  \u2551") + chalk.dim(`  Context: ${contextFiles.join(", ")}`.padEnd(62)) + chalk.bold.white("\u2551"));
  }
  console.log(chalk.bold.white("  \u2551") + chalk.dim("  Participants:".padEnd(62)) + chalk.bold.white("\u2551"));
  for (const role of roles) {
    const color = colorMap.get(role.id) ?? chalk.white;
    const backend = role.provider ? chalk.dim(` \xB7 ${role.provider}${role.model ? `:${role.model}` : ""}`) : "";
    const line = `    ${color("\u25CF")} ${color.bold(role.name)} ${chalk.dim(`(${role.id})`)}${backend}`;
    console.log(chalk.bold.white("  \u2551") + line + " ".repeat(Math.max(0, 62 - stripAnsi(line).length)) + chalk.bold.white("\u2551"));
  }
  console.log(chalk.bold.white("  \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563"));
  console.log(chalk.bold.white("  \u2551") + chalk.dim("  Press Ctrl+C to interrupt and generate summary".padEnd(62)) + chalk.bold.white("\u2551"));
  console.log(chalk.bold.white("  \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
  console.log();
}
function renderRoundHeader(round, maxRounds) {
  console.log(chalk.dim(`  \u2500\u2500 Round ${round}/${maxRounds} ${"\u2500".repeat(48)}`));
  console.log();
}
var streamingRoleId = null;
var streamingBuffer = "";
function renderAgentSpeaking(roleName, roleId) {
  const color = colorMap.get(roleId) ?? chalk.white;
  process.stdout.write(chalk.dim("  \u{1F4AD} ") + color.bold(roleName) + chalk.dim(" is thinking..."));
}
function clearSpeakingLine() {
  process.stdout.write("\r\x1B[2K");
}
function renderAgentStreamStart(roleName, roleId) {
  clearSpeakingLine();
  const color = colorMap.get(roleId) ?? chalk.white;
  console.log(color.bold(`  \u250C\u2500 ${roleName} `) + chalk.dim(`(${roleId})`));
  process.stdout.write(color("  \u2502 "));
  streamingRoleId = roleId;
  streamingBuffer = "";
}
function renderAgentToken(roleId, token) {
  const color = colorMap.get(roleId) ?? chalk.white;
  const parts = token.split("\n");
  for (let i = 0; i < parts.length; i++) {
    if (i > 0) {
      process.stdout.write("\n" + color("  \u2502 "));
    }
    process.stdout.write(parts[i]);
  }
  streamingBuffer += token;
}
function renderAgentStreamEnd(roleId) {
  const color = colorMap.get(roleId) ?? chalk.white;
  console.log();
  console.log(color("  \u2514" + "\u2500".repeat(60)));
  console.log();
  streamingRoleId = null;
  streamingBuffer = "";
}
function renderAgentMessage(msg) {
  const color = colorMap.get(msg.speaker) ?? chalk.white;
  if (msg.passed) {
    console.log(chalk.dim(`  ${msg.speakerName}: [PASS \u2014 nothing to add]`));
    console.log();
    return;
  }
  if (streamingRoleId === msg.speaker && streamingBuffer) {
    renderAgentStreamEnd(msg.speaker);
    return;
  }
  console.log(color.bold(`  \u250C\u2500 ${msg.speakerName} `) + chalk.dim(`(${msg.speaker})`));
  const lines = msg.content.split("\n");
  for (const line of lines) {
    console.log(color("  \u2502 ") + line);
  }
  console.log(color("  \u2514" + "\u2500".repeat(60)));
  console.log();
}
function renderConsensus() {
  console.log();
  console.log(chalk.green.bold("  \u2713 All agents passed \u2014 consensus reached."));
  console.log();
}
function renderMaxRounds(maxRounds) {
  console.log();
  console.log(chalk.yellow(`  \u26A0 Maximum rounds (${maxRounds}) reached.`));
  console.log();
}
function renderUserInterrupt() {
  console.log();
  console.log(chalk.yellow("  \u26A0 Discussion interrupted by user."));
  console.log();
}
function renderSummary(summary) {
  console.log(chalk.bold.white("  \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"));
  console.log(chalk.bold.white("  \u2551") + chalk.bold.green("  \u{1F4CB} Discussion Summary                                     ") + chalk.bold.white("\u2551"));
  console.log(chalk.bold.white("  \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"));
  console.log();
  for (const line of summary.split("\n")) {
    console.log("  " + line);
  }
  console.log();
}
var currentSpeaker = null;
var streamHeaderPrinted = false;
function renderHubEvent(event) {
  switch (event.type) {
    case "round_start":
      renderRoundHeader(event.round, event.maxRounds);
      break;
    case "agent_speaking":
      currentSpeaker = { roleId: event.roleId, roleName: event.roleName };
      streamHeaderPrinted = false;
      renderAgentSpeaking(event.roleName, event.roleId);
      break;
    case "agent_token":
      if (!streamHeaderPrinted) {
        const roleName = currentSpeaker?.roleName ?? event.roleId;
        renderAgentStreamStart(roleName, event.roleId);
        streamHeaderPrinted = true;
      }
      renderAgentToken(event.roleId, event.token);
      break;
    case "agent_spoke":
      if (streamHeaderPrinted) {
        renderAgentStreamEnd(event.roleId);
        streamHeaderPrinted = false;
      } else {
        clearSpeakingLine();
        renderAgentMessage(event.message);
      }
      break;
    case "agent_passed":
      clearSpeakingLine();
      streamHeaderPrinted = false;
      break;
    case "converge_vote":
      console.log(chalk.dim(`  \u{1F5F3}  Convergence vote: ${event.converged}/${event.total} agent(s) marked [CONVERGED]`));
      break;
    case "human_steer":
      console.log(chalk.cyan(`  \u{1F9ED} You steered: ${truncate(event.message, 80)}`));
      console.log();
      break;
    case "discussion_end":
      if (event.reason === "consensus") renderConsensus();
      else if (event.reason === "vote_converged") console.log(chalk.bold.green("\n  \u2713 Converged by vote (2/3 majority).\n"));
      else if (event.reason === "max_rounds") renderMaxRounds(event.maxRounds ?? 0);
      else if (event.reason === "human_stop") console.log(chalk.bold.yellow("\n  \u23F9  Stopped by you \u2014 generating summary.\n"));
      else renderUserInterrupt();
      break;
    case "summary":
      renderSummary(event.content);
      break;
    case "error":
      console.log(chalk.red(`  \u2717 Error${event.roleId ? ` (${event.roleId})` : ""}: ${event.message}`));
      break;
  }
}
function truncate(s, maxLen) {
  return s.length > maxLen ? s.slice(0, maxLen - 3) + "..." : s;
}
function stripAnsi(s) {
  return s.replace(/\x1b\[[0-9;]*m/g, "");
}

export {
  assignRoleColors,
  renderHubBanner,
  renderRoundHeader,
  renderAgentSpeaking,
  clearSpeakingLine,
  renderAgentMessage,
  renderConsensus,
  renderMaxRounds,
  renderUserInterrupt,
  renderSummary,
  renderHubEvent
};
