'use strict';

var process = require('process');
var readline = require('readline');

function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }

var readline__default = /*#__PURE__*/_interopDefault(readline);

// src/platform/ui/text-utils.ts
var ANSI = {
  blue: "\x1B[34m",
  bold: "\x1B[1m",
  cyan: "\x1B[36m",
  dim: "\x1B[2m",
  gray: "\x1B[90m",
  green: "\x1B[32m",
  red: "\x1B[31m",
  reset: "\x1B[0m",
  white: "\x1B[37m",
  yellow: "\x1B[33m"
};
var ANSI_PATTERN = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
var COMBINING_MARK_PATTERN = /\p{Mark}/u;
var GRAPHEME_SEGMENTER = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter("ko", { granularity: "grapheme" }) : null;
function colorize(text, color) {
  return `${color}${text}${ANSI.reset}`;
}
function segmentGraphemes(value) {
  if (!GRAPHEME_SEGMENTER) {
    return [...value];
  }
  return [...GRAPHEME_SEGMENTER.segment(value)].map(({ segment }) => segment);
}
function getGraphemeWidth(grapheme) {
  let width = 0;
  for (const character of grapheme) {
    const codePoint = character.codePointAt(0);
    if (!codePoint || COMBINING_MARK_PATTERN.test(character) || codePoint === 8205) {
      continue;
    }
    if (codePoint >= 65024 && codePoint <= 65039 || codePoint >= 917760 && codePoint <= 917999) {
      continue;
    }
    if (isWideCodePoint(codePoint) || isEmojiCodePoint(codePoint)) {
      width = Math.max(width, 2);
      continue;
    }
    width = Math.max(width, 1);
  }
  return width;
}
function tokenizePlainText(value) {
  return segmentGraphemes(value).map((segment) => ({
    value: segment,
    visibleWidth: getGraphemeWidth(segment)
  }));
}
function tokenizeVisibleText(value) {
  const tokens = [];
  let lastIndex = 0;
  for (const match of value.matchAll(ANSI_PATTERN)) {
    const index = match.index ?? 0;
    if (index > lastIndex) {
      tokens.push(...tokenizePlainText(value.slice(lastIndex, index)));
    }
    tokens.push({
      value: match[0],
      visibleWidth: 0
    });
    lastIndex = index + match[0].length;
  }
  if (lastIndex < value.length) {
    tokens.push(...tokenizePlainText(value.slice(lastIndex)));
  }
  return tokens;
}
function isWideCodePoint(codePoint) {
  return codePoint >= 4352 && (codePoint <= 4447 || codePoint === 9001 || codePoint === 9002 || codePoint >= 11904 && codePoint <= 12871 && codePoint !== 12351 || codePoint >= 12880 && codePoint <= 19903 || codePoint >= 19968 && codePoint <= 42182 || codePoint >= 43360 && codePoint <= 43388 || codePoint >= 44032 && codePoint <= 55203 || codePoint >= 63744 && codePoint <= 64255 || codePoint >= 65040 && codePoint <= 65049 || codePoint >= 65072 && codePoint <= 65131 || codePoint >= 65281 && codePoint <= 65376 || codePoint >= 65504 && codePoint <= 65510 || codePoint >= 127488 && codePoint <= 127569 || codePoint >= 131072 && codePoint <= 262141);
}
function isEmojiCodePoint(codePoint) {
  return codePoint >= 127462 && codePoint <= 127487 || codePoint >= 127744 && codePoint <= 129791 || codePoint >= 9728 && codePoint <= 10175;
}
function visibleLength(value) {
  return tokenizeVisibleText(value).reduce((total, token) => total + token.visibleWidth, 0);
}
function sliceVisible(value, width) {
  if (width <= 0) {
    return "";
  }
  let currentWidth = 0;
  let output = "";
  let truncated = false;
  let containsAnsi = false;
  for (const token of tokenizeVisibleText(value)) {
    if (token.visibleWidth === 0) {
      output += token.value;
      containsAnsi = true;
      continue;
    }
    if (currentWidth + token.visibleWidth > width) {
      truncated = true;
      break;
    }
    output += token.value;
    currentWidth += token.visibleWidth;
  }
  if (truncated && containsAnsi && !output.endsWith(ANSI.reset)) {
    output += ANSI.reset;
  }
  return output;
}
function padVisible(value, width) {
  const slicedValue = sliceVisible(value, width);
  const length = visibleLength(slicedValue);
  if (length >= width) {
    return slicedValue;
  }
  return `${slicedValue}${" ".repeat(width - length)}`;
}
function truncateValue(value, width) {
  if (visibleLength(value) <= width) {
    return value;
  }
  if (width <= 3) {
    return sliceVisible(value, width);
  }
  return `${sliceVisible(value, width - 3)}...`;
}
function getViewportWidth() {
  const columns = process.stdout.columns || 100;
  return Math.max(Math.min(columns - 2, 108), 4);
}
function getTerminalColumns() {
  return Math.max(process.stdout.columns || 100, 4);
}
function renderBadge(text, tone) {
  const theme = tone === "service" ? ANSI.cyan : tone === "accent" ? ANSI.green : tone === "warn" ? ANSI.yellow : ANSI.gray;
  return colorize(`[${text}]`, theme);
}
function createBox(title, lines, footerLines = []) {
  const contentLines = lines.length > 0 ? lines : [""];
  const footer = footerLines.length > 0 ? ["", ...footerLines] : [];
  const width = getViewportWidth();
  const top = `+${"-".repeat(width - 2)}+`;
  const titleLine = `| ${padVisible(colorize(title, ANSI.bold), width - 4)} |`;
  const body = [...contentLines, ...footer].map((line) => `| ${padVisible(line, width - 4)} |`);
  return [top, titleLine, top, ...body, top];
}
function renderScreenBox(title, lines, footerLines = []) {
  console.clear();
  console.log(createBox(title, lines, footerLines).join("\n"));
}
function wrapPlainText(value, firstLineWidth, continuationLineWidth) {
  const renderedLines = [];
  const safeFirstLineWidth = Math.max(firstLineWidth, 1);
  const safeContinuationLineWidth = Math.max(continuationLineWidth, 1);
  const normalizedValue = value.replace(/\r\n?/g, "\n");
  const pushWrappedLine = (line) => {
    if (line.length === 0) {
      renderedLines.push("");
      return;
    }
    let currentLine = "";
    let currentWidth = 0;
    let currentLineWidth = renderedLines.length === 0 ? safeFirstLineWidth : safeContinuationLineWidth;
    for (const segment of segmentGraphemes(line)) {
      const segmentWidth = Math.max(getGraphemeWidth(segment), 1);
      if (currentLine && currentWidth + segmentWidth > currentLineWidth) {
        renderedLines.push(currentLine);
        currentLine = "";
        currentWidth = 0;
        currentLineWidth = safeContinuationLineWidth;
      }
      currentLine += segment;
      currentWidth += segmentWidth;
    }
    renderedLines.push(currentLine);
  };
  normalizedValue.split("\n").forEach(pushWrappedLine);
  return renderedLines.length > 0 ? renderedLines : [""];
}
function buildPromptRenderLayout(promptLabel, buffer, placeholder) {
  const columns = getTerminalColumns();
  const promptLabelWidth = visibleLength(promptLabel);
  const continuationIndentWidth = Math.min(promptLabelWidth, Math.max(columns - 1, 0));
  const continuationIndent = " ".repeat(continuationIndentWidth);
  const firstLineWidth = Math.max(columns - promptLabelWidth, 1);
  const continuationLineWidth = Math.max(columns - continuationIndentWidth, 1);
  const hasBuffer = buffer.length > 0;
  const contentLines = hasBuffer ? wrapPlainText(buffer, firstLineWidth, continuationLineWidth) : wrapPlainText(placeholder || "", firstLineWidth, continuationLineWidth);
  const cursorLines = hasBuffer ? contentLines : [""];
  const renderedPromptLines = contentLines.map((line, index) => {
    const linePrefix = index === 0 ? promptLabel : continuationIndent;
    return `${linePrefix}${hasBuffer ? line : colorize(line, ANSI.dim)}`;
  });
  const activeCursorLine = cursorLines.at(-1) || "";
  const activeCursorLinePrefixWidth = cursorLines.length <= 1 ? promptLabelWidth : continuationIndentWidth;
  return {
    cursorColumn: activeCursorLinePrefixWidth + visibleLength(activeCursorLine),
    cursorRowOffset: Math.max(cursorLines.length - 1, 0),
    lines: renderedPromptLines,
    totalLines: renderedPromptLines.length
  };
}
function clearRenderedPrompt(previousState) {
  if (previousState?.cursorRowOffset) {
    readline__default.default.moveCursor(process.stdout, 0, -previousState.cursorRowOffset);
  }
  readline__default.default.cursorTo(process.stdout, 0);
  readline__default.default.clearScreenDown(process.stdout);
}
function renderPromptLayout(layout, previousState) {
  clearRenderedPrompt(previousState);
  process.stdout.write(layout.lines.join("\n"));
  const linesBelowCursor = layout.totalLines - 1 - layout.cursorRowOffset;
  if (linesBelowCursor > 0) {
    readline__default.default.moveCursor(process.stdout, 0, -linesBelowCursor);
  }
  readline__default.default.cursorTo(process.stdout, layout.cursorColumn);
  return {
    cursorRowOffset: layout.cursorRowOffset,
    totalLines: layout.totalLines
  };
}

exports.ANSI = ANSI;
exports.buildPromptRenderLayout = buildPromptRenderLayout;
exports.clearRenderedPrompt = clearRenderedPrompt;
exports.colorize = colorize;
exports.createBox = createBox;
exports.getGraphemeWidth = getGraphemeWidth;
exports.getTerminalColumns = getTerminalColumns;
exports.getViewportWidth = getViewportWidth;
exports.padVisible = padVisible;
exports.renderBadge = renderBadge;
exports.renderPromptLayout = renderPromptLayout;
exports.renderScreenBox = renderScreenBox;
exports.segmentGraphemes = segmentGraphemes;
exports.sliceVisible = sliceVisible;
exports.tokenizePlainText = tokenizePlainText;
exports.tokenizeVisibleText = tokenizeVisibleText;
exports.truncateValue = truncateValue;
exports.visibleLength = visibleLength;
exports.wrapPlainText = wrapPlainText;
