// Utility for generating hierarchical numbering (1, a, i, A, I, α)

export const MAX_INDENT_LEVEL = 5;

// Roman numeral converter (1-3999)
const toRoman = (num, upper = false) => {
  if (num < 1) return '';
  const lookup = [
    { value: 1000, symbol: 'M' },
    { value: 900, symbol: 'CM' },
    { value: 500, symbol: 'D' },
    { value: 400, symbol: 'CD' },
    { value: 100, symbol: 'C' },
    { value: 90, symbol: 'XC' },
    { value: 50, symbol: 'L' },
    { value: 40, symbol: 'XL' },
    { value: 10, symbol: 'X' },
    { value: 9, symbol: 'IX' },
    { value: 5, symbol: 'V' },
    { value: 4, symbol: 'IV' },
    { value: 1, symbol: 'I' },
  ];
  let roman = '';
  for (const i of lookup) {
    while (num >= i.value) {
      roman += i.symbol;
      num -= i.value;
    }
  }
  return upper ? roman : roman.toLowerCase();
};

// Alpha converter (1=a, 2=b, 26=z, 27=aa...)
const toAlpha = (num, upper = false) => {
  if (num < 1) return '';
  let str = '';
  while (num > 0) {
    let mod = (num - 1) % 26;
    str = String.fromCharCode(97 + mod) + str;
    num = Math.floor((num - 1) / 26);
  }
  return upper ? str.toUpperCase() : str;
};

// Greek converter (simple mapping for first few, then fallback)
const toGreek = (num) => {
  const greekChars = ['α', 'β', 'γ', 'δ', 'ε', 'ζ', 'η', 'θ', 'ι', 'κ', 'λ', 'μ', 'ν', 'ξ', 'ο', 'π', 'ρ', 'σ', 'τ', 'υ', 'φ', 'χ', 'ψ', 'ω'];
  if (num <= greekChars.length) return greekChars[num - 1];
  return `${num}`; // Fallback
};

export const getNumberingFormat = (level) => {
  // Cycle levels if deeper than defined
  const effectiveLevel = level % 6;
  switch (effectiveLevel) {
    case 0: return 'decimal';       // 1, 2, 3
    case 1: return 'lower-alpha';   // a, b, c
    case 2: return 'lower-roman';   // i, ii, iii
    case 3: return 'upper-alpha';   // A, B, C
    case 4: return 'upper-roman';   // I, II, III
    case 5: return 'greek';         // α, β, γ
    default: return 'decimal';
  }
};

export const formatNumber = (number, level) => {
  const effectiveLevel = level % 6;
  switch (effectiveLevel) {
    case 0: return `${number}.`;
    case 1: return `${toAlpha(number)}.`;
    case 2: return `${toRoman(number)}.`;
    case 3: return `${toAlpha(number, true)}.`;
    case 4: return `${toRoman(number, true)}.`;
    case 5: return `${toGreek(number)}.`;
    default: return `${number}.`;
  }
};

// Helper for managing counters during traversal
export class NumberingCounter {
  constructor() {
    this.counters = {};
  }

  reset() {
    this.counters = {};
  }

  increment(level) {
    if (!this.counters[level]) this.counters[level] = 0;
    this.counters[level]++;
    // Reset all deeper levels
    for (let i = level + 1; i <= MAX_INDENT_LEVEL + 5; i++) {
      this.counters[i] = 0;
    }
    return this.counters[level];
  }

  getCurrent(level) {
    return this.counters[level] || 0;
  }
}

/**
 * Checks if a block should be numbered based on preference
 */
export const shouldNumberBlock = (block) => {
  if (!block) return false;
  // Check new preference property first, fallback to legacy property
  return block.numbering_preference === true || block.subtitle_numbering === true;
};

/**
 * Calculates hierarchy numbering for SECTION HEADERS only.
 * This is used for generating the outline (e.g. 1. Introduction, A. Subsection).
 * It treats blocks with titles as the structure nodes.
 */
export const getHierarchicalNumbering = (blocks, index) => {
    if (!blocks || index < 0 || index >= blocks.length) return '';
    
    // We only number explicit section headers (blocks that act as sections in the form builder)
    // Updated to include 'subtitle' and 'subsection' as numbered block types
    const targetBlock = blocks[index];
    const numberedTypes = ['unified_text', 'text_section', 'heading', 'subtitle', 'subsection'];
    
    if (!targetBlock || !numberedTypes.includes(targetBlock.type)) {
        return '';
    }

    // Specific check for numbering preference
    if (!shouldNumberBlock(targetBlock)) {
        return '';
    }

    const counter = new NumberingCounter();
    let result = '';

    for (let i = 0; i <= index; i++) {
        const block = blocks[i];
        if (!numberedTypes.includes(block.type)) continue;
        
        // Skip numbering if disabled
        if (!shouldNumberBlock(block)) continue;
        
        const indent = block.indent || 0;
        const num = counter.increment(indent);
        
        if (i === index) {
            result = formatNumber(num, indent);
        }
    }
    return result;
};

/**
 * Calculates numbering for BULLETS within a text block.
 * This is completely independent of section hierarchy.
 * @param {number} level - The indentation level of the bullet (0-based)
 * @param {number} indexInList - The 1-based index of this item among its siblings at the same level
 */
export const getBulletNumbering = (level, indexInList) => {
    // Bullet numbering usually follows the same format pattern as hierarchy (1, a, i)
    // but resets locally within the text editor list context.
    return formatNumber(indexInList, level);
};

/**
 * Legacy compatibility wrapper - defaults to hierarchical for blocks
 */
export const calculateBlockNumbering = getHierarchicalNumbering;