import { MIN_ROW_HEIGHT_PX, PAGE_CONTENT_HEIGHT_PX } from "./documentPageMetrics.js";

export const MIN_TEXT_BLOCKS = 1;
export const MAX_TEXT_BLOCKS = 12;
export const DEFAULT_PAGE_ROW_COUNT = 3;
export const DEFAULT_TEXT_BLOCK_HEIGHT = 0;
export const DEFAULT_ROW_MARKERS = {
  tips: false,
  quality: false,
  safety: false,
  visual: false,
};

function parseHeightPx(value) {
  const h = Number(value);
  return Number.isFinite(h) && h >= MIN_ROW_HEIGHT_PX ? h : DEFAULT_TEXT_BLOCK_HEIGHT;
}

const LEGACY_FIXED_ROW_HEIGHTS = new Set([56, 96]);

export function equalSplitRowHeightPx(rowCount) {
  const count = Math.max(1, rowCount);
  const borders = Math.max(0, count - 1);
  return Math.floor((PAGE_CONTENT_HEIGHT_PX - borders) / count);
}

/** Heights from old fixed defaults (56 / 96 px) — treat as compact (0). User-resized and equal-split saves are kept. */
export function isLegacyAutoRowHeight(heightPx, _rowCount) {
  const h = Number(heightPx);
  if (!Number.isFinite(h) || h <= MIN_ROW_HEIGHT_PX) return false;
  return LEGACY_FIXED_ROW_HEIGHTS.has(h);
}

export function clearLegacyAutoRowHeights(textBlocks) {
  const blocks = Array.isArray(textBlocks) ? textBlocks : [];
  const rowCount = blocks.length;
  return blocks.map((block) =>
    isLegacyAutoRowHeight(block.height_px, rowCount)
      ? { ...block, height_px: DEFAULT_TEXT_BLOCK_HEIGHT }
      : block
  );
}

function normalizeMarkers(source = {}) {
  return {
    tips: Boolean(source?.tips ?? source?.marker_tips),
    quality: Boolean(source?.quality ?? source?.marker_quality),
    safety: Boolean(source?.safety ?? source?.marker_safety),
    visual: Boolean(source?.visual ?? source?.marker_visual),
  };
}

export function createTextBlock(
  blockIndex,
  text = "",
  heightPx = DEFAULT_TEXT_BLOCK_HEIGHT,
  markers = DEFAULT_ROW_MARKERS
) {
  return {
    block_index: blockIndex,
    text,
    height_px: heightPx,
    text_block_id: null,
    ...normalizeMarkers(markers),
  };
}

export function defaultTextBlocks() {
  return Array.from({ length: DEFAULT_PAGE_ROW_COUNT }, (_, index) =>
    createTextBlock(index + 1, "", DEFAULT_TEXT_BLOCK_HEIGHT)
  );
}

/** Normalize page/API payload into a sorted text_blocks array. */
export function normalizeTextBlocks(source = {}) {
  if (Array.isArray(source.text_blocks) && source.text_blocks.length) {
    return source.text_blocks
      .map((block, index) =>
        createTextBlock(
          Number(block.block_index) || index + 1,
          block.text ?? "",
          parseHeightPx(block.height_px),
          block
        )
      )
      .slice(0, MAX_TEXT_BLOCKS)
      .map((block, index) => ({ ...block, block_index: index + 1 }));
  }

  const fromApiBlocks = Array.isArray(source.blocks)
    ? source.blocks
        .map((block, index) =>
          createTextBlock(
            Number(block.block_index) || index + 1,
            block.text ?? "",
            parseHeightPx(block.height_px),
            block
          )
        )
        .sort((a, b) => a.block_index - b.block_index)
    : [];

  if (fromApiBlocks.length) {
    return fromApiBlocks
      .slice(0, MAX_TEXT_BLOCKS)
      .map((block, index) => ({ ...block, block_index: index + 1 }));
  }

  const legacy = [1, 2, 3].map((index) =>
    createTextBlock(
      index,
      source[`block${index}`] ?? "",
      parseHeightPx(source.text_block_heights?.[String(index)])
    )
  );

  return legacy;
}

export function reindexTextBlocks(blocks) {
  return blocks.map((block, index) => ({
    ...block,
    block_index: index + 1,
  }));
}

export function addTextBlock(blocks) {
  if (blocks.length >= MAX_TEXT_BLOCKS) return blocks;
  return reindexTextBlocks([
    ...blocks,
    createTextBlock(blocks.length + 1, "", DEFAULT_TEXT_BLOCK_HEIGHT),
  ]);
}

export function removeTextBlock(blocks, index) {
  if (blocks.length <= MIN_TEXT_BLOCKS) return blocks;
  return reindexTextBlocks(blocks.filter((_, i) => i !== index));
}

export function updateTextBlock(blocks, index, patch) {
  return blocks.map((block, i) => (i === index ? { ...block, ...patch } : block));
}

/** Legacy block1–3 fields for APIs that still read them. */
export function textBlocksToLegacyFields(textBlocks) {
  const out = { block1: "", block2: "", block3: "" };
  for (const block of textBlocks) {
    if (block.block_index >= 1 && block.block_index <= 3) {
      out[`block${block.block_index}`] = block.text || "";
    }
  }
  return out;
}

export function textBlocksSnippet(textBlocks) {
  return (textBlocks || [])
    .map((block) => (block.text || "").trim().replace(/\s+/g, " "))
    .find(Boolean);
}
