# -*- coding: utf-8 -*-
"""
문서 템플릿 분석기 v5.1 (오케스트레이터)

역할: tools/ 모듈을 조합하여 HWPX → 템플릿 정보 추출
- 직접 파싱 로직 없음 (모두 tools에 위임)
- 디폴트값 생성 없음 (tools가 None 반환하면 결과에서 제외)
- 사용자 추가 사항(config.json) → 템플릿에도 반영

구조:
  tools/
    page_setup.py   §7  용지/여백
    font.py         §3  글꼴
    char_style.py   §4  글자 모양
    para_style.py   §5  문단 모양
    border_fill.py  §2  테두리/배경
    table.py        §6  표
    header_footer.py §8 머리말/꼬리말
    section.py      §9  구역 정의
    style_def.py        스타일 정의
    numbering.py        번호매기기/글머리표
    image.py            이미지
"""

import json
from pathlib import Path
from typing import Optional

from .tools import (
    page_setup,
    font,
    char_style,
    para_style,
    border_fill,
    table,
    header_footer,
    section,
    style_def,
    numbering,
    image,
    content_order,
)


class DocTemplateAnalyzer:
    """HWPX → 템플릿 추출 오케스트레이터"""

    # ================================================================
    #  Phase 1: 추출 (모든 tools 호출)
    # ================================================================

    def analyze(self, parsed: dict) -> dict:
        """HWPX parsed 결과에서 템플릿 구조 추출.

        Args:
            parsed: processor.py가 HWPX를 파싱한 결과 dict.
                    raw_xml, section_xml, header_xml, footer_xml,
                    tables, paragraphs 등 포함.

        Returns:
            추출된 항목만 포함하는 dict (None인 항목은 제외).
        """
        raw_xml = parsed.get("raw_xml", {})

        extractors = {
            "page":         lambda: page_setup.extract(raw_xml, parsed),
            "fonts":        lambda: font.extract(raw_xml, parsed),
            "char_styles":  lambda: char_style.extract(raw_xml, parsed),
            "para_styles":  lambda: para_style.extract(raw_xml, parsed),
            "border_fills": lambda: border_fill.extract(raw_xml, parsed),
            "tables":       lambda: table.extract(raw_xml, parsed),
            "header":       lambda: header_footer.extract_header(raw_xml, parsed),
            "footer":       lambda: header_footer.extract_footer(raw_xml, parsed),
            "section":      lambda: section.extract(raw_xml, parsed),
            "styles":       lambda: style_def.extract(raw_xml, parsed),
            "numbering":    lambda: numbering.extract(raw_xml, parsed),
            "images":       lambda: image.extract(raw_xml, parsed),
            "content_order":lambda: content_order.extract(raw_xml, parsed),
        }

        result = {}
        for key, extractor in extractors.items():
            try:
                value = extractor()
                if value is not None:
                    result[key] = value
            except Exception as e:
                # 개별 tool 실패 시 로그만, 전체 중단 안 함
                result.setdefault("_errors", []).append(
                    f"{key}: {type(e).__name__}: {e}"
                )

        return result


    # ================================================================
    #  Phase 2: 사용자 추가 사항 병합
    # ================================================================

    def merge_user_config(self, template_info: dict,
                          config: dict) -> dict:
        """config.json의 사용자 요구사항을 template_info에 병합.

        사용자가 문서 유형 추가 시 지정한 커스텀 사항을 반영:
        - 색상 오버라이드
        - 글꼴 오버라이드
        - 제목 크기 오버라이드
        - 기타 레이아웃 커스텀

        이 병합 결과는 style.json에 저장되고,
        이후 template.html 생성 시에도 반영됨.

        Args:
            template_info: analyze()의 결과
            config: config.json 내용

        Returns:
            병합된 template_info (원본 수정됨)
        """
        user_overrides = config.get("user_overrides", {})
        if not user_overrides:
            return template_info

        # 모든 사용자 오버라이드를 template_info에 기록
        template_info["user_overrides"] = user_overrides

        return template_info

    # ================================================================
    #  Phase 3: template_info → style.json 저장
    # ================================================================

    def save_style(self, template_info: dict,
                   save_path: Path) -> Path:
        """template_info를 style.json으로 저장.

        Args:
            template_info: analyze() + merge_user_config() 결과
            save_path: 저장 경로 (예: templates/user/{doc_type}/style.json)

        Returns:
            저장된 파일 경로
        """
        save_path = Path(save_path)
        save_path.parent.mkdir(parents=True, exist_ok=True)

        with open(save_path, 'w', encoding='utf-8') as f:
            json.dump(template_info, f, ensure_ascii=False, indent=2)

        return save_path