"""Master CV parser — reads tagged LaTeX CV and extracts modular content pools."""

import re
from pathlib import Path


TAG_PATTERNS = {
    "skill": re.compile(r"^%\s*%%SKILL:(\S+)\s*::\s*(.+)$"),
    "bullet": re.compile(r"^%\s*%%BULLET:(\S+)\s*::\s*(.+)$"),
    "achievement": re.compile(r"^%\s*%%ACHIEVEMENT_\d+:(\S+)\s*::\s*(.+)$"),
    "summary": re.compile(r"^%\s*%%SUMMARY:(\S+)\s*::\s*(.+)$"),
}

FROZEN_START = re.compile(r"^%\s*%%FROZEN_SECTION:start:(\S+)")
FROZEN_END = re.compile(r"^%\s*%%FROZEN_SECTION:end:(\S+)")
PLACEHOLDER = re.compile(r"^%\s*%%(RODO_COMPANY_NAME|HEADER_TITLE)\s*::\s*(.+)$")


def parse_master(tex_path: str | Path) -> dict:
    """Parse a tagged master CV .tex file.

    Returns a dict with:
        skills: {id: latex_content}
        bullets: {id: latex_content}  (id format: company_number_version)
        achievements: {id: latex_content}
        summaries: {id: latex_content}
        frozen_sections: {name: latex_content}
        placeholders: {name: default_value}
        preamble: str (everything before \\begin{document})
        body: str (everything after \\begin{document})
        raw: str (full file content)
    """
    tex_path = Path(tex_path)
    content = tex_path.read_text(encoding="utf-8")
    lines = content.split("\n")

    result = {
        "skills": {},
        "bullets": {},
        "achievements": {},
        "summaries": {},
        "frozen_sections": {},
        "placeholders": {},
        "raw": content,
    }

    # Split preamble and body
    doc_start = content.find(r"\begin{document}")
    if doc_start >= 0:
        result["preamble"] = content[:doc_start]
        result["body"] = content[doc_start:]
    else:
        result["preamble"] = ""
        result["body"] = content

    # Parse tags
    tag_map = {
        "skill": "skills",
        "bullet": "bullets",
        "achievement": "achievements",
        "summary": "summaries",
    }

    current_frozen = None
    frozen_lines = []

    for line in lines:
        # Frozen sections
        m = FROZEN_START.match(line)
        if m:
            current_frozen = m.group(1)
            frozen_lines = []
            continue

        m = FROZEN_END.match(line)
        if m and current_frozen:
            result["frozen_sections"][current_frozen] = "\n".join(frozen_lines)
            current_frozen = None
            frozen_lines = []
            continue

        if current_frozen is not None:
            frozen_lines.append(line)
            continue

        # Placeholders
        m = PLACEHOLDER.match(line)
        if m:
            result["placeholders"][m.group(1)] = m.group(2).strip()
            continue

        # Content tags
        for tag_name, pattern in TAG_PATTERNS.items():
            m = pattern.match(line)
            if m:
                tag_id = m.group(1)
                tag_content = m.group(2).strip()
                result[tag_map[tag_name]][tag_id] = tag_content
                break

    return result


def get_bullet_variants(parsed: dict, company: str) -> dict[str, dict[str, str]]:
    """Group bullet variants by bullet number for a given company.

    Returns: {bullet_num: {version: content}}
    Example: {"1": {"v1": "...", "v2": "...", "v3": "..."}}
    """
    variants = {}
    prefix = f"{company}_"
    for tag_id, content in parsed["bullets"].items():
        if not tag_id.startswith(prefix):
            continue
        # Format: company_number_version (e.g. maczfit_1_v1)
        rest = tag_id[len(prefix):]
        parts = rest.rsplit("_", 1)
        if len(parts) == 2:
            num, ver = parts
        else:
            num, ver = parts[0], "v1"
        if num not in variants:
            variants[num] = {}
        variants[num][ver] = content
    return variants


def get_skill_groups(parsed: dict) -> dict[str, list[tuple[str, str]]]:
    """Group skills by prefix (plan_, anal_, soft_, lang_).

    Returns: {group: [(id, content), ...]}
    """
    groups = {
        "planning": [],
        "analytics": [],
        "soft_skills": [],
        "languages": [],
    }
    prefix_map = {
        "plan_": "planning",
        "anal_": "analytics",
        "soft_": "soft_skills",
        "lang_": "languages",
    }
    for skill_id, content in parsed["skills"].items():
        group = "planning"  # default
        for prefix, group_name in prefix_map.items():
            if skill_id.startswith(prefix):
                group = group_name
                break
        groups[group].append((skill_id, content))
    return groups
