"""fix_bpy_import.py — scanvas_maker.py 의 bpy import 오류 핫픽스.

증상:
    [모듈 없음] Blender 렌더 모듈을 찾을 수 없습니다: No module named 'bpy'

원인:
    apply_blender_patch.py v1 의 P1 콜백 안에서 dump_params_to_json 을
    gate_3d_builder_bpy 에서 import 하도록 되어 있는데, 이 모듈은 첫 줄에
    `import bpy` 가 있어 S-CANVAS conda env(GUI 측)에서는 import 불가.

수정:
    동일 함수의 bpy-무의존 버전인 params_to_json.dump_dataclass_to_json 으로 교체.
    (params_to_json.py 는 이미 D:\\에 있음)

이 스크립트는 idempotent: 이미 수정돼있으면 변경 없음.
백업: 실행 전 scanvas_maker.py.bak_bpyfix 자동 생성.

사용법:
    cd D:\\2026\\PROGRAM\\1_S-CANVAS
    python fix_bpy_import.py
"""

from __future__ import annotations

import ast
import shutil
import sys
from pathlib import Path

TARGET = Path("scanvas_maker.py")
BACKUP = Path("scanvas_maker.py.bak_bpyfix")


# 정확한 한 줄을 교체 (CRLF/LF 무관 — bytes로 처리)
OLD_LINE = b"from gate_3d_builder_bpy import dump_params_to_json as _dump_gate"
NEW_LINE = b"from params_to_json import dump_dataclass_to_json as _dump_gate"


def main():
    if not TARGET.is_file():
        sys.exit(f"[ERR] {TARGET} 가 현재 폴더에 없습니다. "
                 f"D:\\2026\\PROGRAM\\1_S-CANVAS 에서 실행하세요.")

    raw = TARGET.read_bytes()
    print(f"파일: {TARGET} ({len(raw):,} bytes)")

    if NEW_LINE in raw:
        print("\n→ 이미 수정됨. 추가 작업 없음.")
        # 그래도 import 실제로 동작하는지 확인
        if not Path("params_to_json.py").is_file():
            print("\n  ⚠ 경고: params_to_json.py 가 현재 폴더에 없습니다.")
            print("  S-CANVAS 폴더에 이 모듈이 있어야 import 가 성공합니다.")
        return 0

    if OLD_LINE not in raw:
        print("\n[INFO] OLD 패턴을 찾지 못했습니다.")
        print("       apply_blender_patch.py 를 먼저 실행했는지 확인하세요.")
        # 진단 — 어떤 import가 있는지
        for keyword in [b"gate_3d_builder_bpy", b"_dump_gate", b"dump_params_to_json"]:
            n = raw.count(keyword)
            print(f"       '{keyword.decode()}' 발생: {n}회")
        sys.exit(1)

    # params_to_json.py 가 실제로 있는지 미리 확인
    if not Path("params_to_json.py").is_file():
        sys.exit("[ERR] params_to_json.py 가 현재 폴더에 없습니다. "
                 "이 모듈이 import 대상입니다.")

    # 단일 라인 치환
    new_raw = raw.replace(OLD_LINE, NEW_LINE, 1)
    n_replaced = raw.count(OLD_LINE) - new_raw.count(OLD_LINE)
    print(f"  교체 라인 수: {n_replaced}")

    # AST parse 검증 (utf-8 디코드 후)
    try:
        text = new_raw.decode("utf-8")
        # CRLF면 그대로, AST는 양쪽 다 받음
        ast.parse(text)
        print(f"  AST parse: OK ({len(text.splitlines()):,} lines)")
    except SyntaxError as e:
        sys.exit(f"\n[ERR] 수정 후 syntax error: {e}\n파일 변경 안 함.")

    # 백업
    shutil.copy2(TARGET, BACKUP)
    print(f"\n  백업: {BACKUP}")

    # 저장
    TARGET.write_bytes(new_raw)
    print(f"\n✓ 핫픽스 적용 완료: {TARGET} ({len(new_raw):,} bytes)")
    print("\n변경 내용:")
    print(f"  - {OLD_LINE.decode()}")
    print(f"  + {NEW_LINE.decode()}")
    print("\n다음 단계:")
    print("  1) S-CANVAS 재시작 (또는 그냥 다이얼로그를 다시 열어 다시 시도)")
    print("  2) '🎨 Blender 렌더' 버튼 클릭")


if __name__ == "__main__":
    sys.exit(main() or 0)
