import json
import re
from pathlib import Path

OLD_APP = Path("/mnt/storage/sftp/mcelwain/repository/word-doc-generator")
OLD_CONSTANTS_CANDIDATES = [
    OLD_APP / "public" / "constants.js",
    OLD_APP / "constants.js",
]

OUT_DIR = Path("tools/doc_generator/content/excel_maps")
OUT_FILE = OUT_DIR / "legacy_excel_maps.json"

CELL_RE = re.compile(r"([A-Za-z_][A-Za-z0-9_]*)\s*:\s*['\"]([A-Z]{1,3}[0-9]{1,5})['\"]")


def find_constants_file():
    for path in OLD_CONSTANTS_CANDIDATES:
        if path.exists():
            return path
    raise SystemExit("Could not find old constants.js")


def extract_object_blocks(text):
    """
    Finds JS object-ish assignment/export blocks that contain Excel cell mappings.
    This is intentionally simple and robust for the old constants.js style.
    """
    blocks = []

    # Match things like:
    # const fieldToCellMap = { ... };
    # export const fieldToCellMap = { ... };
    # let someMap = { ... };
    pattern = re.compile(
        r"(?:export\s+)?(?:const|let|var)\s+([A-Za-z_][A-Za-z0-9_]*)\s*=\s*\{",
        re.MULTILINE,
    )

    for match in pattern.finditer(text):
        name = match.group(1)
        start = match.end() - 1

        depth = 0
        end = None

        for i in range(start, len(text)):
            char = text[i]
            if char == "{":
                depth += 1
            elif char == "}":
                depth -= 1
                if depth == 0:
                    end = i + 1
                    break

        if end:
            block = text[start:end]
            cells = dict(CELL_RE.findall(block))
            if cells:
                blocks.append((name, cells))

    return blocks


def label_from_name(name):
    label = re.sub(r"([a-z])([A-Z])", r"\1 \2", name)
    label = label.replace("_", " ").replace("-", " ")
    label = re.sub(r"\s+", " ", label).strip()
    return label.title()


def normalize_id(name):
    value = re.sub(r"([a-z])([A-Z])", r"\1_\2", name)
    value = re.sub(r"[^A-Za-z0-9]+", "_", value).strip("_").lower()
    return value or "excel_map"


def discover_excel_templates():
    templates = []

    for path in sorted(OLD_APP.rglob("*.xlsx")):
        if ".git" in path.parts or "node_modules" in path.parts:
            continue

        rel = path.relative_to(OLD_APP).as_posix()
        templates.append({
            "label": rel,
            "legacyPath": str(path),
            "filename": path.name
        })

    return templates


def main():
    constants_path = find_constants_file()
    text = constants_path.read_text(encoding="utf-8", errors="ignore")

    blocks = extract_object_blocks(text)
    excel_templates = discover_excel_templates()

    maps = []

    for name, cells in blocks:
        map_id = normalize_id(name)

        maps.append({
            "id": map_id,
            "sourceName": name,
            "label": label_from_name(name),
            "description": f"Generated from {constants_path.relative_to(OLD_APP)} object {name}.",
            "template": excel_templates[0]["filename"] if excel_templates else "",
            "legacyTemplateCandidates": excel_templates,
            "fields": dict(sorted(cells.items(), key=lambda item: item[1]))
        })

    OUT_DIR.mkdir(parents=True, exist_ok=True)
    OUT_FILE.write_text(json.dumps({
        "id": "legacy_excel_maps",
        "source": str(constants_path),
        "maps": maps
    }, indent=2), encoding="utf-8")

    print(f"Wrote {OUT_FILE}")
    print(f"Source: {constants_path}")
    print(f"Excel templates found: {len(excel_templates)}")
    for t in excel_templates:
        print(f"- {t['legacyPath']}")

    print(f"Maps found: {len(maps)}")
    for item in maps:
        print(f"- {item['id']}: {len(item['fields'])} fields")


if __name__ == "__main__":
    main()
