"""파서 결과 → JSON 브리지 (S-CANVAS env 측 generic 헬퍼).

이 모듈은 bpy를 import하지 않으므로 기존 S-CANVAS conda 환경에서 그대로 사용 가능.
파서가 생성한 dataclass 파라미터(IntakeTowerParams, GateParams, ...)를 JSON으로 직렬화.

사용:
    # 취수탑
    from intake_tower_parser import parse_intake_tower
    from params_to_json import dump_dataclass_to_json
    p = parse_intake_tower(dxf_paths)
    dump_dataclass_to_json(p, "intake_params.json")

    # 여수로 수문
    from gate_parser import parse_gate_dxf
    from params_to_json import dump_dataclass_to_json
    p = parse_gate_dxf(plan_dxf, section_dxf)
    dump_dataclass_to_json(p, "gate_params.json")

이후 Blender 헤드리스로:
    blender --background --python <builder_bpy>.py -- ^
        --params <params>.json --blend out.blend --render out.png
"""

from __future__ import annotations

import json
from dataclasses import asdict
from pathlib import Path


def _to_serializable(obj):
    """dataclass / list / tuple / dict / 기본형 → JSON 직렬화 가능 구조."""
    if hasattr(obj, "__dataclass_fields__"):
        return {k: _to_serializable(v) for k, v in asdict(obj).items()}
    if isinstance(obj, (list, tuple)):
        return [_to_serializable(x) for x in obj]
    if isinstance(obj, dict):
        return {k: _to_serializable(v) for k, v in obj.items()}
    if isinstance(obj, (str, int, float, bool)) or obj is None:
        return obj
    # numpy / 기타: 가능하면 float, 아니면 str로 폴백
    try:
        return float(obj)
    except (TypeError, ValueError):
        return str(obj)


def dump_dataclass_to_json(params, path: str) -> str:
    """dataclass 인스턴스 → JSON 파일.

    구조 종류와 무관하게 동작 (IntakeTowerParams, GateParams, ...).
    Returns: 작성한 절대 경로 (str)
    """
    payload = _to_serializable(params)
    out_path = Path(path).resolve()
    out_path.write_text(
        json.dumps(payload, ensure_ascii=False, indent=2),
        encoding="utf-8",
    )
    return str(out_path)


# 이전 버전 호환 alias (intake_tower_3d_builder_bpy 가이드와의 호환)
dump_intake_tower_params = dump_dataclass_to_json


# ---------------------------------------------------------------------------
# CLI: 구조물 종류 자동 감지 → JSON 변환
# ---------------------------------------------------------------------------

def _cli_intake_tower(out_json: str, dxf_paths: list[str]) -> None:
    from intake_tower_parser import parse_intake_tower
    params = parse_intake_tower(dxf_paths)
    print(params.summary())
    final = dump_dataclass_to_json(params, out_json)
    print(f"\nJSON written: {final}")


def _cli_gate(out_json: str, plan_dxf: str, section_dxf: str | None = None) -> None:
    from gate_parser import parse_gate_dxf
    params = parse_gate_dxf(plan_dxf, section_dxf)
    print(params.summary())
    final = dump_dataclass_to_json(params, out_json)
    print(f"\nJSON written: {final}")


def _print_usage_and_exit():
    print("Usage:")
    print("  python params_to_json.py intake <out.json> <dxf_1> [dxf_2 ...]")
    print("  python params_to_json.py gate   <out.json> <plan.dxf> [section.dxf]")
    print("")
    print("Examples:")
    print("  python params_to_json.py intake intake.json \\")
    print("    SAMPLE_CAD/취수탑1.dxf SAMPLE_CAD/취수탑2.dxf")
    print("")
    print("  python params_to_json.py gate gate.json \\")
    print("    Gate_Sample/수문_1.dxf Gate_Sample/수문_2.dxf")
    raise SystemExit(1)


if __name__ == "__main__":
    import sys

    if len(sys.argv) < 4:
        _print_usage_and_exit()

    kind = sys.argv[1].lower()
    out_json = sys.argv[2]
    rest = sys.argv[3:]

    if kind in ("intake", "intake_tower", "tower"):
        _cli_intake_tower(out_json, rest)
    elif kind in ("gate", "spillway", "weir"):
        plan = rest[0]
        section = rest[1] if len(rest) > 1 else None
        _cli_gate(out_json, plan, section)
    else:
        print(f"Unknown structure kind: {kind!r}")
        _print_usage_and_exit()
