"""
clean_lesson_notes.py  v2
Post-procesa los notes en course_map.json para:
  1. Eliminar ruido del player de video/audio
  2. Eliminar título duplicado al inicio
  3. Formatear pares bilingües EN/ES en Sección 1:
       **Hello, my name is David.**
       *Hola, mi nombre es David.*
  4. Re-importa la DB
"""
import json
import re
import subprocess
import sys
from pathlib import Path

sys.stdout.reconfigure(encoding="utf-8")

SCRIPTS_DIR = Path(__file__).parent
BASE_DIR    = SCRIPTS_DIR.parent
MAP_FILE    = SCRIPTS_DIR / "course_map.json"

# ── Noise patterns ─────────────────────────────────────────────────────────────

def is_player_noise(s: str) -> bool:
    """Return True if line is video/audio player UI noise."""
    s = re.sub(r'^#{1,3}\s+', '', s.strip())
    return bool(re.match(
        r'^(?:Play|\d+:\d+(?::\d+)?|Closed\s+Captions|Settings|Fullscreen'
        r'|Velocidad:|\d+\.\d+x|1x|2x'
        r'|Descargar\s+texto|Section\s+\d+,\s+Chapter\s+\d+'
        r'|Normal\s+version|Interactive\s+version)$',
        s, re.I
    ))


# ── Bilingual pair formatting ──────────────────────────────────────────────────

def format_bilingual_section(section_text: str) -> str:
    """
    Within 'Escucha con traducción' text, find paragraphs that are
    exactly 2 lines (EN + ES pairs) and format them as:
        **English sentence.**
        *Traducción en español.*
    Single-line paragraphs (instructions) are left unchanged.
    """
    # Split into paragraphs (chunks separated by blank lines)
    paragraphs = re.split(r'\n\s*\n', section_text.strip())
    result = []

    for para in paragraphs:
        lines = [l.strip() for l in para.strip().splitlines() if l.strip()]

        if len(lines) == 2:
            # Two-line block → bilingual pair; strip existing markup and reformat
            en_line = re.sub(r'^\*{1,2}(.*?)\*{0,2}$', r'\1', lines[0].strip())
            es_line = re.sub(r'^\*{1,2}(.*?)\*{0,2}$', r'\1', lines[1].strip())
            result.append(f"**{en_line}**  \n*{es_line}*")
        else:
            result.append(para.strip())

    return "\n\n".join(result)


def apply_bilingual_format(notes: str) -> str:
    """
    Find section 1 (between '### 1.' and '### 2.') and apply bilingual formatting.
    Sections 2 and 3 are left as-is.
    """
    sec1_match = re.search(r'(### 1\.[^\n]*\n)(.*?)(?=\n### 2\.|\Z)', notes, re.S)
    if not sec1_match:
        return notes

    header = sec1_match.group(1)       # "### 1. Escucha con traducción\n"
    body   = sec1_match.group(2)       # everything inside section 1

    formatted_body = format_bilingual_section(body)
    new_section    = header + "\n" + formatted_body

    return (
        notes[:sec1_match.start()]
        + new_section
        + notes[sec1_match.end():]
    )


# ── Main clean function ────────────────────────────────────────────────────────

def clean_notes(notes: str, lesson_title: str = "") -> str:
    lines = notes.splitlines()
    cleaned = []
    title_header_seen = False

    for line in lines:
        stripped = line.strip()

        # Remove duplicate plain-text title after the ## header
        if lesson_title:
            if not title_header_seen and stripped == f"## {lesson_title}":
                title_header_seen = True
                cleaned.append(line)
                continue
            if title_header_seen and stripped == lesson_title:
                continue  # skip the plain duplicate

        if stripped and is_player_noise(stripped):
            continue

        cleaned.append(line)

    text = "\n".join(cleaned)
    text = re.sub(r'\n{3,}', '\n\n', text)
    text = text.strip()

    # Apply bilingual pair formatting to section 1
    text = apply_bilingual_format(text)

    return text


# ── Entry point ────────────────────────────────────────────────────────────────

def main():
    data = json.loads(MAP_FILE.read_text(encoding="utf-8"))
    changed = 0

    for lesson in data:
        notes = lesson.get("notes", "")
        if not notes:
            continue
        title    = lesson.get("title", "")
        new_text = clean_notes(notes, title)
        if new_text != notes:
            lesson["notes"] = new_text
            changed += 1

    MAP_FILE.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8")
    print(f"{changed} lecciones actualizadas en course_map.json")

    print("Actualizando DB...")
    subprocess.run(["php", "artisan", "course:import", "--force"], cwd=str(BASE_DIR), check=True)
    subprocess.run(
        ["php", "artisan", "tinker", "--execute",
         "App\\Models\\Lesson::where('position', 2)->update(['is_available' => true]); echo 'OK';"],
        cwd=str(BASE_DIR),
    )
    print("Listo.")


if __name__ == "__main__":
    main()
