"use strict";

const { brand, box: chars, stripAnsi } = require("./theme");

const MIN_WIDTH = 40;
const MAX_WIDTH = 70;

/** Return the visible (printed) length of a string, ignoring ANSI escapes. */
function visibleLength(str) {
  return stripAnsi(str).length;
}

/**
 * Render a bordered key-value box as a string.
 * All border chars are rendered in brand color.
 */
function renderBox(options = {}) {
  const { title, items = [], width: explicitWidth } = options;

  // Calculate label column width (longest label + 2 spaces padding)
  const labelWidth =
    items.reduce((max, item) => Math.max(max, visibleLength(item.label)), 0) +
    2;

  // Calculate box width
  let width;
  if (explicitWidth) {
    width = Math.min(explicitWidth, MAX_WIDTH);
  } else {
    const contentWidth = items.reduce(
      (max, item) =>
        Math.max(
          max,
          visibleLength(item.label) + visibleLength(item.value) + 4,
        ),
      0,
    );
    width = Math.max(Math.min(contentWidth + 4, MAX_WIDTH), MIN_WIDTH);
  }

  const inner = width - 2; // space between border chars
  const lines = [];

  // Top border
  if (title) {
    const titleStr = ` ${title} `;
    const remaining = inner - titleStr.length;
    lines.push(
      brand(
        chars.tl + titleStr + chars.h.repeat(Math.max(remaining, 0)) + chars.tr,
      ),
    );
  } else {
    lines.push(brand(chars.tl + chars.h.repeat(inner) + chars.tr));
  }

  // Blank padding row
  lines.push(brand(chars.v) + " ".repeat(inner) + brand(chars.v));

  // Content rows
  for (const item of items) {
    const label = item.label.padEnd(labelWidth);
    let content = "  " + label + item.value;
    const visible = visibleLength(content);
    if (visible > inner) {
      content = content.slice(0, inner);
    }
    const padLen = inner - visibleLength(content);
    lines.push(brand(chars.v) + content + " ".repeat(padLen) + brand(chars.v));
  }

  // Blank padding row
  lines.push(brand(chars.v) + " ".repeat(inner) + brand(chars.v));

  // Bottom border
  lines.push(brand(chars.bl + chars.h.repeat(inner) + chars.br));

  return lines.join("\n");
}

module.exports = { renderBox };
