# -*- coding: utf-8 -*-
"""
HWPX 표 열 너비 수정기 v2
표 생성 후 HWPX 파일을 직접 수정하여 열 너비 적용
"""

import zipfile
import re
from pathlib import Path
import tempfile
import shutil

# mm → HWPML 단위 변환 (1mm ≈ 283.46 HWPML units)
MM_TO_HWPML = 7200 / 25.4  # ≈ 283.46


def inject_table_widths(hwpx_path: str, table_widths_list: list):
    """
    HWPX 파일의 표 열 너비를 수정
    
    Args:
        hwpx_path: HWPX 파일 경로
        table_widths_list: [[w1, w2, w3], [w1, w2], ...] 형태 (mm 단위)
    """
    if not table_widths_list:
        print("   [INFO] 수정할 표 없음")
        return
    
    print(f"📐 HWPX 표 열 너비 수정 시작... ({len(table_widths_list)}개 표)")
    
    # HWPX 압축 해제
    temp_dir = Path(tempfile.mkdtemp(prefix="hwpx_table_"))
    
    with zipfile.ZipFile(hwpx_path, 'r') as zf:
        zf.extractall(temp_dir)
    
    # section*.xml 파일들에서 표 찾기
    contents_dir = temp_dir / "Contents"
    
    table_idx = 0
    total_modified = 0
    
    for section_file in sorted(contents_dir.glob("section*.xml")):
        with open(section_file, 'r', encoding='utf-8') as f:
            content = f.read()
        
        original_content = content
        
        # 모든 표(<hp:tbl>...</hp:tbl>) 찾기
        tbl_pattern = re.compile(r'(<hp:tbl\b[^>]*>)(.*?)(</hp:tbl>)', re.DOTALL)
        
        def process_table(match):
            nonlocal table_idx, total_modified
            
            if table_idx >= len(table_widths_list):
                return match.group(0)
            
            tbl_open = match.group(1)
            tbl_content = match.group(2)
            tbl_close = match.group(3)
            
            col_widths_mm = table_widths_list[table_idx]
            col_widths_hwpml = [int(w * MM_TO_HWPML) for w in col_widths_mm]
            
            # 표 전체 너비 수정 (hp:sz width="...")
            total_width = int(sum(col_widths_mm) * MM_TO_HWPML)
            tbl_content = re.sub(
                r'(<hp:sz\s+width=")(\d+)(")',
                lambda m: f'{m.group(1)}{total_width}{m.group(3)}',
                tbl_content,
                count=1
            )
            
            # 각 셀의 cellSz width 수정
            # 방법: colAddr별로 너비 매핑
            def replace_cell_width(tc_match):
                tc_content = tc_match.group(0)
                
                # colAddr 추출
                col_addr_match = re.search(r'<hp:cellAddr\s+colAddr="(\d+)"', tc_content)
                if not col_addr_match:
                    return tc_content
                
                col_idx = int(col_addr_match.group(1))
                if col_idx >= len(col_widths_hwpml):
                    return tc_content
                
                new_width = col_widths_hwpml[col_idx]
                
                # cellSz width 교체
                tc_content = re.sub(
                    r'(<hp:cellSz\s+width=")(\d+)(")',
                    lambda m: f'{m.group(1)}{new_width}{m.group(3)}',
                    tc_content
                )
                
                return tc_content
            
            # 각 <hp:tc>...</hp:tc> 블록 처리
            tbl_content = re.sub(
                r'<hp:tc\b[^>]*>.*?</hp:tc>',
                replace_cell_width,
                tbl_content,
                flags=re.DOTALL
            )
            
            print(f"   ✅ 표 #{table_idx + 1}: {col_widths_mm} mm → HWPML 적용")
            table_idx += 1
            total_modified += 1
            
            return tbl_open + tbl_content + tbl_close
        
        # 표 처리
        new_content = tbl_pattern.sub(process_table, content)
        
        # 변경사항 있으면 저장
        if new_content != original_content:
            with open(section_file, 'w', encoding='utf-8') as f:
                f.write(new_content)
            print(f"   → {section_file.name} 저장됨")
    
    # 다시 압축
    repack_hwpx(temp_dir, hwpx_path)
    
    # 임시 폴더 삭제
    shutil.rmtree(temp_dir)
    
    print(f"   ✅ 총 {total_modified}개 표 열 너비 수정 완료")


def repack_hwpx(source_dir: Path, output_path: str):
    """HWPX 파일 다시 압축"""
    import os
    import time
    
    temp_output = output_path + ".tmp"
    
    with zipfile.ZipFile(temp_output, 'w', zipfile.ZIP_DEFLATED) as zf:
        # mimetype은 압축 없이 첫 번째로
        mimetype_path = source_dir / "mimetype"
        if mimetype_path.exists():
            zf.write(mimetype_path, "mimetype", compress_type=zipfile.ZIP_STORED)
        
        # 나머지 파일들
        for root, dirs, files in os.walk(source_dir):
            for file in files:
                if file == "mimetype":
                    continue
                file_path = Path(root) / file
                arcname = file_path.relative_to(source_dir)
                zf.write(file_path, arcname)
    
    # 원본 교체
    for attempt in range(3):
        try:
            if os.path.exists(output_path):
                os.remove(output_path)
            os.rename(temp_output, output_path)
            break
        except PermissionError:
            time.sleep(0.5)


# 테스트용
if __name__ == "__main__":
    test_widths = [
        [18.2, 38.9, 42.8, 70.1],
        [19.9, 79.6, 70.5],
        [28.7, 81.4, 59.9],
        [19.2, 61.4, 89.5],
    ]
    
    hwpx_path = r"C:\Users\User\AppData\Local\Temp\geulbeot_output.hwpx"
    inject_table_widths(hwpx_path, test_widths)