/**
 * Chunking simple por headings markdown con tope de ~600 tokens (≈ 2400 chars).
 * Devuelve trozos con un "encabezado" reconstruido para que cada chunk sea
 * autocontenido (incluye el path de headings hasta el actual).
 */

const APROX_CHARS_POR_TOKEN = 4;
const MAX_CHARS = 2400;

export interface MarkdownChunk {
  contenido: string;
  token_count: number;
}

export function chunkMarkdown(md: string, docTitulo?: string): MarkdownChunk[] {
  if (!md.trim()) return [];
  // Encabezados rotulados como títulos de documento y SIN el separador «›»:
  // el prompt reserva «›» para rutas de menú, y con `[Doc › Sección]` el modelo
  // leía el índice de la guía como un camino de navegación ("Configuración ›
  // Sucursales, Cajas y Configuración POS › Numeraciones de Documentos", que no
  // existe). Ver regla 1 del SYSTEM_PROMPT en ayuda-ia.service.ts.
  const tituloPrefix = docTitulo ? `[Guía: ${docTitulo}]\n` : '';

  // Split por líneas y reconstruir secciones por heading
  const lineas = md.split('\n');
  type Seccion = { headingPath: string[]; lineas: string[] };
  const secciones: Seccion[] = [];
  let actual: Seccion = { headingPath: [], lineas: [] };
  let pila: string[] = []; // path acumulado por nivel

  const pushActual = () => {
    if (actual.lineas.join('').trim().length > 0) {
      secciones.push(actual);
    }
  };

  for (const linea of lineas) {
    const m = linea.match(/^(#{1,4})\s+(.+)$/);
    if (m) {
      pushActual();
      const nivel = m[1].length;
      const titulo = m[2].trim();
      pila = pila.slice(0, nivel - 1);
      pila[nivel - 1] = titulo;
      actual = { headingPath: [...pila].filter(Boolean), lineas: [linea] };
    } else {
      actual.lineas.push(linea);
    }
  }
  pushActual();

  // Si no hay secciones (markdown sin headings), tratá todo como uno
  if (secciones.length === 0) {
    secciones.push({ headingPath: [], lineas: md.split('\n') });
  }

  const chunks: MarkdownChunk[] = [];
  for (const sec of secciones) {
    const apartado = sec.headingPath.length > 0 ? sec.headingPath.join(' / ') : '';
    const cuerpo = sec.lineas.join('\n').trim();
    if (!cuerpo) continue;

    if (cuerpo.length <= MAX_CHARS) {
      const contenido = `${tituloPrefix}${apartado ? `[Apartado de la guía: ${apartado}]\n` : ''}${cuerpo}`;
      chunks.push({
        contenido,
        token_count: Math.ceil(contenido.length / APROX_CHARS_POR_TOKEN),
      });
    } else {
      // Trozar por párrafos
      const partes = cuerpo.split(/\n\n+/);
      let buf = '';
      const flush = () => {
        if (!buf.trim()) return;
        const contenido = `${tituloPrefix}${apartado ? `[Apartado de la guía: ${apartado}]\n` : ''}${buf.trim()}`;
        chunks.push({
          contenido,
          token_count: Math.ceil(contenido.length / APROX_CHARS_POR_TOKEN),
        });
        buf = '';
      };
      for (const p of partes) {
        if ((buf + '\n\n' + p).length > MAX_CHARS) {
          flush();
        }
        buf = buf ? `${buf}\n\n${p}` : p;
      }
      flush();
    }
  }

  return chunks;
}
