# -*- coding: utf-8 -*-
"""
§2 테두리/배경(BorderFill) 추출

HWPX 실제 태그 (header.xml):
  <hh:borderFill id="3" threeD="0" shadow="0" centerLine="NONE" ...>
    <hh:leftBorder type="SOLID" width="0.12 mm" color="#000000"/>
    <hh:rightBorder type="SOLID" width="0.12 mm" color="#000000"/>
    <hh:topBorder type="SOLID" width="0.12 mm" color="#000000"/>
    <hh:bottomBorder type="SOLID" width="0.12 mm" color="#000000"/>
    <hh:diagonal type="SOLID" width="0.1 mm" color="#000000"/>
    <hc:fillBrush>
      <hc:winBrush faceColor="#EDEDED" hatchColor="#FFE7E7E7" alpha="0"/>
    </hc:fillBrush>
  </hh:borderFill>

디폴트값 생성 안 함.
"""

import re

from domain.hwpx.hwpx_utils import BORDER_TYPE_TO_CSS, hwpx_border_to_css


def extract(raw_xml: dict, parsed: dict = None) -> dict | None:
    """§2 borderFill 전체 추출 → id별 dict.

    Returns:
        {
            3: {
                "id": 3,
                "left":   {"type": "SOLID", "width": "0.12 mm", "color": "#000000"},
                "right":  {"type": "SOLID", "width": "0.12 mm", "color": "#000000"},
                "top":    {"type": "SOLID", "width": "0.12 mm", "color": "#000000"},
                "bottom": {"type": "SOLID", "width": "0.12 mm", "color": "#000000"},
                "diagonal": {"type": "SOLID", "width": "0.1 mm", "color": "#000000"},
                "background": "#EDEDED",      # fillBrush faceColor
                "css": {                       # 편의: 미리 변환된 CSS
                    "border-left": "0.12mm solid #000000",
                    ...
                    "background-color": "#EDEDED",
                }
            },
            ...
        }
        또는 추출 실패 시 None
    """
    header_xml = _get_header_xml(raw_xml, parsed)
    if not header_xml:
        return None

    blocks = re.findall(
        r'<hh:borderFill\b([^>]*)>(.*?)</hh:borderFill>',
        header_xml, re.DOTALL
    )

    if not blocks:
        return None

    result = {}
    for attrs_str, inner in blocks:
        id_m = re.search(r'\bid="(\d+)"', attrs_str)
        if not id_m:
            continue
        bf_id = int(id_m.group(1))

        item = {"id": bf_id}

        # 4방향 + diagonal
        for side, tag in [
            ("left",     "leftBorder"),
            ("right",    "rightBorder"),
            ("top",      "topBorder"),
            ("bottom",   "bottomBorder"),
            ("diagonal", "diagonal"),
        ]:
            # 태그 전체를 먼저 찾고, 속성을 개별 추출 (순서 무관)
            tag_m = re.search(rf'<hh:{tag}\b([^/]*?)/?>', inner)
            if tag_m:
                tag_attrs = tag_m.group(1)
                t = re.search(r'\btype="([^"]+)"', tag_attrs)
                w = re.search(r'\bwidth="([^"]+)"', tag_attrs)
                c = re.search(r'\bcolor="([^"]+)"', tag_attrs)
                item[side] = {
                    "type": t.group(1) if t else "NONE",
                    "width": w.group(1).replace(" ", "") if w else "0.12mm",
                    "color": c.group(1) if c else "#000000",
                }

        # 배경 (fillBrush > winBrush faceColor)
        bg_m = re.search(
            r'<hc:winBrush\b[^>]*\bfaceColor="([^"]+)"', inner
        )
        if bg_m:
            face = bg_m.group(1)
            if face and face.lower() != "none":
                item["background"] = face

        # CSS 편의 변환
        css = {}
        for side in ["left", "right", "top", "bottom"]:
            border_data = item.get(side)
            if border_data:
                css[f"border-{side}"] = hwpx_border_to_css(border_data)
            else:
                css[f"border-{side}"] = "none"
            # border_data가 없으면 CSS에도 넣지 않음

        if "background" in item:
            css["background-color"] = item["background"]

        if css:
            item["css"] = css

        result[bf_id] = item

    return result if result else None


def _get_header_xml(raw_xml: dict, parsed: dict = None) -> str | None:
    if parsed and parsed.get("header_xml"):
        return parsed["header_xml"]
    if isinstance(raw_xml, dict):
        for name, content in raw_xml.items():
            if "header" in name.lower() and isinstance(content, str):
                return content
    return raw_xml if isinstance(raw_xml, str) else None