#!/usr/bin/env python3
"""
Refactor generate_weekN.py to use math_helpers.py.

Strategy: Line-by-line parsing that identifies sections:
  - KEEP: docstring, day functions (monday..friday), days list, generate loop
  - REPLACE: imports, BASE/WEEK setup, CSS, color constants, helpers, SVG funcs
  - ADD: teacher guide stubs
"""

import os
import re

BASE = os.path.expanduser("~/Home_School/2nd_Grade/Math")

# Names of functions we want to KEEP as day content
DAY_FUNCS = {'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'}

# Names of functions to REMOVE (now in math_helpers)
REMOVE_FUNCS = {
    'circle_svg', 'eq_group_svg', 'array_svg', 'shape_svg',
    'clock_svg', 'fraction_svg', 'coin_svg', 'grid_svg',
    'bar_graph_svg', 'star_svg', 'trophy_svg', 'medal_svg', 'check_svg',
    'times_table_html', 'skip_count_html', 'mini_chart_html',
    'ruler_inches', 'ruler_cm', 'measure_line', 'measure_line_cm',
    'fraction_bar_svg',
    'hdr', 'sec', 'b', 'bw', 'bl', 'page', 'page_multi',
}


def parse_week_file(path):
    """Parse a week file into sections."""
    with open(path, 'r') as f:
        lines = f.readlines()

    # Extract docstring
    docstring = ''
    doc_end = 0
    in_doc = False
    for i, line in enumerate(lines):
        if '"""' in line:
            if not in_doc:
                in_doc = True
                doc_start = i
            else:
                doc_end = i + 1
                break
    if in_doc:
        docstring = ''.join(lines[doc_start:doc_end])

    # Find function boundaries
    func_starts = {}  # name -> line index
    func_ends = {}    # name -> line index
    current_func = None
    current_func_indent = 0

    for i, line in enumerate(lines):
        # Check for top-level def
        stripped = line.strip()
        if stripped.startswith('def ') and not line[0].isspace():
            # End previous function
            if current_func:
                func_ends[current_func] = i
            match = re.match(r'def\s+(\w+)\s*\(', stripped)
            if match:
                current_func = match.group(1)
                func_starts[current_func] = i
                current_func_indent = 0

    # End last function
    if current_func:
        func_ends[current_func] = len(lines)

    # Find days list
    days_start = None
    days_end = None
    in_days = False
    for i, line in enumerate(lines):
        stripped = line.strip()
        if re.match(r'^days\s*=\s*\[', stripped) and not line[0].isspace():
            days_start = i
            in_days = True
        elif in_days:
            if stripped == ']':
                days_end = i + 1
                break
            if stripped.startswith(']') and not line[0].isspace():
                days_end = i + 1
                break

    # Find generate loop (after days list)
    gen_start = days_end if days_end else None
    gen_end = len(lines)

    # Find CSS block
    css_start = None
    css_end = None
    in_css = False
    for i, line in enumerate(lines):
        stripped = line.strip()
        if re.match(r'^CSS\s*=\s*r"""', stripped) or re.match(r'^CSS\s*=\s*"""', stripped):
            css_start = i
            in_css = True
        elif in_css:
            if stripped == '"""' or stripped.endswith('"""'):
                css_end = i + 1
                break

    # Find color constants block
    color_start = None
    color_end = None
    for i, line in enumerate(lines):
        stripped = line.strip()
        if stripped == '# Color palette':
            color_start = i
        elif color_start is not None:
            if stripped.startswith('#') or any(stripped.startswith(c) and '=' in stripped for c in ['RED', 'BLUE', 'GREEN', 'YELLOW', 'ORANGE', 'PURPLE', 'PINK', 'TEAL', 'GOLD']):
                color_end = i + 1
            elif stripped == '':
                continue
            else:
                color_end = i
                break

    # Find shebang line
    shebang = ''
    if lines and lines[0].startswith('#!'):
        shebang = lines[0].rstrip('\n')

    return {
        'shebang': shebang,
        'docstring': docstring,
        'func_starts': func_starts,
        'func_ends': func_ends,
        'days_start': days_start,
        'days_end': days_end,
        'gen_start': gen_start,
        'gen_end': gen_end,
        'css_start': css_start,
        'css_end': css_end,
        'color_start': color_start,
        'color_end': color_end,
        'lines': lines,
    }


def extract_day_topics(days_text):
    """Extract day name and topic from days list text."""
    topics = {}
    pattern = r'\("([^"]+)"\s*,\s*"([^"]+)"\s*,\s*(\w+)'
    for match in re.finditer(pattern, days_text):
        day = match.group(1).lower()
        topic = match.group(2)
        func = match.group(3)
        topics[day] = {'topic': topic, 'func': func}
    return topics


def build_refactored(path, week_num):
    """Build refactored version of a week file."""
    info = parse_week_file(path)
    lines = info['lines']

    # Extract day function content
    day_content_lines = []
    for day in DAY_FUNCS:
        if day in info['func_starts']:
            start = info['func_starts'][day]
            end = info['func_ends'].get(day, len(lines))
            # Add comment header
            day_content_lines.append(f'\n# ═══════════════════════════════════════════════════')
            day_content_lines.append(f'# {day.upper()}')
            day_content_lines.append(f'# ═══════════════════════════════════════════════════')
            day_content_lines.append('')
            for i in range(start, end):
                day_content_lines.append(lines[i])
            day_content_lines.append('')

    # Extract and update days list + generate loop
    days_list_lines = []
    gen_lines = []
    if info['days_start'] is not None:
        for i in range(info['days_start'], info['gen_end']):
            days_list_lines.append(lines[i])

    days_text = ''.join(days_list_lines)
    topics = extract_day_topics(days_text)

    # Build teacher guide stubs
    tg_lines = []
    tg_lines.append('')
    tg_lines.append('# ═══════════════════════════════════════════════════')
    tg_lines.append('# TEACHER GUIDES')
    tg_lines.append('# ═══════════════════════════════════════════════════')

    for day, info_dict in topics.items():
        topic = info_dict['topic']
        tg_name = f'{day}_tg'
        tg_lines.append(f'''
def {tg_name}():
    """Teacher guide for {day.capitalize()} - {topic}."""
    return tg_page("{day.capitalize()}", "{topic}",
        tg_note("Answers for {day.capitalize()} - {topic}")
    )''')

    # Build new days list
    new_days_lines = []
    new_days_lines.append('')
    new_days_lines.append('# ═══════════════════════════════════════════════════')
    new_days_lines.append('# Generate')
    new_days_lines.append('# ═══════════════════════════════════════════════════')
    new_days_lines.append('days = [')
    for day, info_dict in topics.items():
        day_cap = day.capitalize()
        func = info_dict['func']
        tg_name = f'{day}_tg'
        new_days_lines.append(f'    ("{day_cap}", "{info_dict["topic"]}", {func}, {tg_name}),')
    new_days_lines.append(']')
    new_days_lines.append('')
    new_days_lines.append('generate_simple(WEEK, days)')
    new_days_lines.append(f'print(f"\\\\nWeek {week_num} complete! PDFs + Teacher Guides in", WEEK)')

    # Assemble
    result = []
    if info['shebang']:
        result.append(info['shebang'])
    result.append('"""')
    # Clean up docstring
    doc_lines = info['docstring'].strip().split('\n')
    for dl in doc_lines:
        result.append(dl)
    result.append('"""')
    result.append('')
    result.append('import os')
    result.append('import glob')
    result.append('from weasyprint import HTML')
    result.append('')
    result.append('from math_helpers import (')
    result.append('    CSS, TEACHER_CSS,')
    result.append('    page, page_multi, hdr, sec, b, bw, bl,')
    result.append('    generate_simple,')
    result.append('    tg_page, tg_page_multi, tg_sec, tg_grid_answers, tg_note, tg_section_title,')
    result.append('    BLUE, GREEN, RED, YELLOW, ORANGE, PURPLE, PINK, TEAL, GOLD,')
    result.append('    circle_svg, eq_group_svg, array_svg, shape_svg,')
    result.append('    clock_svg, fraction_svg, coin_svg, grid_svg,')
    result.append('    bar_graph_svg, star_svg, trophy_svg, medal_svg, check_svg,')
    result.append('    times_table_html, skip_count_html, mini_chart_html,')
    result.append('    ruler_inches, ruler_cm, measure_line, measure_line_cm,')
    result.append('    fraction_bar_svg,')
    result.append(')')
    result.append('')
    result.append('BASE = os.path.expanduser("~/Home_School/2nd_Grade/Math")')
    result.append(f'WEEK = os.path.join(BASE, "Week_{week_num}")')

    # Day functions
    result.extend(day_content_lines)

    # Teacher guides
    result.extend(tg_lines)

    # Generate
    result.extend(new_days_lines)
    result.append('')

    return '\n'.join(result)


def main():
    print("Refactoring math course generators (v2)...")
    print()

    for week in range(2, 33):
        path = os.path.join(BASE, f'generate_week{week}.py')
        if not os.path.exists(path):
            print(f"  SKIP: Week {week} not found")
            continue

        try:
            new_content = build_refactored(path, week)
            with open(path, 'w') as f:
                f.write(new_content)

            size = len(new_content)
            print(f"  Week {week}: OK ({size:,} bytes)")
        except Exception as e:
            print(f"  Week {week}: ERROR - {e}")

    print()
    print("Done!")


if __name__ == '__main__':
    main()