"""
图表样式配置模块

定义默认的颜色方案、线型、标记点等样式。
"""

from typing import Dict, List, Tuple
from lxml import etree

from .oxml_ns import NAMESPACES

# ============================================================================
# 颜色方案定义（RGB 格式）
# ============================================================================

# 深色系列（主色）
DARK_RED = "C00000"      # 深红色
DARK_GRAY = "595959"     # 深灰色
DARK_BLUE = "0070C0"     # 深蓝色
DARK_ORANGE = "ED7D31"   # 深橙色

# 浅色系列（辅助色）
LIGHT_RED = "FF9999"     # 浅红色
LIGHT_GRAY = "BFBFBF"    # 浅灰色
LIGHT_BLUE = "9DC3E6"    # 浅蓝色
LIGHT_ORANGE = "F4B183"  # 浅橙色

# ⭐ aim00 风格颜色（对比色方案：浅灰柱状图 + 深红折线）
AIM00_LIGHT_GRAY = "C0C0C0"  # 浅灰色 - 用于柱状图/面积图（第一系列）
AIM00_DARK_RED = "C00000"    # 深红色 - 用于折线图（第二系列）
AIM00_DARK_BLUE = "305496"   # 深蓝色 - 备用
AIM00_GRAY = "808080"        # 中灰色 - 备用

# 默认颜色序列（深色 + 浅色交替）
DEFAULT_COLOR_SEQUENCE = [
    DARK_RED,
    DARK_BLUE,
    DARK_ORANGE,
    DARK_GRAY,
    LIGHT_RED,
    LIGHT_BLUE,
    LIGHT_ORANGE,
    LIGHT_GRAY,
]

# ── 主题配套图表系列色（每个主题一套 8 色） ──
COLOR_SCHEMES = {
    "midnight":      ["CADCFC", "1E2761", "E8B931", "4A6FA5", "9BB5D6", "B08C28", "8896AB", "484E5C"],
    "charcoal":      ["A8B4BE", "36454F", "E8B931", "607D8B", "B0BEC5", "C4A035", "78909C", "4A565E"],
    "jp_finance":    ["A8D5DC", "1B3D6E", "C9A84C", "4A8FB8", "7FBFCF", "A07840", "8FA8C0", "505868"],
    "pension_warm":  ["A8C4D4", "2E5FA3", "D4903F", "7BA7BC", "B0C9B0", "9C7B48", "8A9DB8", "606870"],
    "tech_blue":     ["90CAF9", "1565C0", "00BFA5", "7E57C2", "29B6F6", "FF7043", "90A4AE", "546E7A"],
    "state_red":     ["CDAC60", "8B0000", "B8860B", "4A6FA5", "C07840", "507050", "907878", "585048"],
    "esg_green":     ["A5D6A7", "1A5C2A", "8BC34A", "00838F", "C8E6C9", "795548", "78909C", "607D8B"],
    "dark_pro":      ["00BFFF", "FFD700", "00E676", "7B68EE", "FF6D00", "E040FB", "A0B0C0", "4A5868"],
    "morningstar":   ["A4C2D8", "1D2B3A", "E67E22", "5A9BD5", "95C8D8", "B87333", "7B8794", "495057"],
    "macro_research":["AED6F1", "2C3E50", "3498DB", "95A5A6", "85C1E9", "1ABC9C", "BDC3C7", "566573"],
    # 兜底别名
    "default":       ["CADCFC", "1E2761", "E8B931", "4A6FA5", "9BB5D6", "B08C28", "8896AB", "484E5C"],
}

# ============================================================================
# 线型配置
# ============================================================================

# 线宽（EMUs: English Metric Units, 1 pt = 12700 EMUs）
LINE_WIDTH_PT = {
    0.5: 6350,    # 0.5 pt
    0.75: 9525,   # 0.75 pt
    1.0: 12700,   # 1 pt (默认)
    1.5: 19050,   # 1.5 pt
    2.0: 25400,   # 2 pt
    2.25: 28575,  # 2.25 pt
    3.0: 38100,   # 3 pt
}

DEFAULT_LINE_WIDTH = LINE_WIDTH_PT[1.0]  # 1 pt

# ============================================================================
# 标记点配置
# ============================================================================

# 标记点样式
MARKER_STYLES = {
    "none": None,        # 无标记
    "circle": "circle",  # 圆形
    "square": "square",  # 方形
    "diamond": "diamond", # 菱形
    "triangle": "triangle", # 三角形
}

DEFAULT_MARKER_STYLE = "none"  # 默认无标记点
DEFAULT_MARKER_SIZE = 5        # 标记点大小（pt）

# ============================================================================
# 样式应用函数
# ============================================================================

def apply_series_style(
    ser_element,
    color: str = None,
    line_width: int = None,
    marker_style: str = None,
    marker_size: int = None,
):
    """
    为系列元素应用样式
    
    Args:
        ser_element: 系列元素 (<c:ser>)
        color: RGB 颜色（6位十六进制，如 "C00000"）
        line_width: 线宽（EMUs）
        marker_style: 标记点样式（"none", "circle", "square" 等）
        marker_size: 标记点大小（pt）
    """
    # ⭐ 检测图表类型（通过父元素）
    parent = ser_element.getparent()
    parent_tag = parent.tag.split('}')[1] if '}' in parent.tag else parent.tag
    is_area_or_bar = parent_tag in ('barChart', 'areaChart')
    
    # 查找或创建 spPr (shape properties) 元素
    spPr = ser_element.find('c:spPr', namespaces=NAMESPACES)
    if spPr is None:
        # 在 idx/order/tx 之后插入 spPr
        insert_index = _find_insert_position(ser_element, 'spPr')
        spPr = etree.Element(f"{{{NAMESPACES['c']}}}spPr")
        ser_element.insert(insert_index, spPr)
    
    # 应用线条样式（传入图表类型信息）
    if line_width is not None or color is not None:
        _apply_line_style(spPr, color, line_width, is_area_or_bar)
    
    # 应用标记点样式
    if marker_style is not None:
        _apply_marker_style(ser_element, marker_style, marker_size, color)


def _apply_line_style(spPr, color: str = None, line_width: int = None, is_area_or_bar: bool = False):
    """
    应用线条样式
    
    Args:
        spPr: shape properties 元素
        color: 颜色
        line_width: 线宽
        is_area_or_bar: 是否为面积图或柱状图（这些图表类型需要设置填充色而非边框色）
    """
    # 清除现有的 ln 元素
    for ln in spPr.findall('a:ln', namespaces=NAMESPACES):
        spPr.remove(ln)
    
    # 创建新的 ln (line) 元素
    ln = etree.SubElement(spPr, f"{{{NAMESPACES['a']}}}ln")
    
    # ⭐ 如果是面积图或柱状图，设置为无边框
    if is_area_or_bar:
        # 设置为无边框（noFill）
        noFill = etree.SubElement(ln, f"{{{NAMESPACES['a']}}}noFill")
        
        # ⭐ 核心修复：为柱状图/面积图添加填充色
        if color is not None:
            # 清除现有的 solidFill 元素
            for fill in spPr.findall('a:solidFill', namespaces=NAMESPACES):
                spPr.remove(fill)
            
            # 在 ln 之后添加 solidFill
            solidFill = etree.SubElement(spPr, f"{{{NAMESPACES['a']}}}solidFill")
            srgbClr = etree.SubElement(solidFill, f"{{{NAMESPACES['a']}}}srgbClr")
            srgbClr.set('val', color)
    else:
        # 折线图/散点图：设置线宽和颜色
        if line_width is not None:
            ln.set('w', str(line_width))
        
        # 设置线条颜色
        if color is not None:
            solidFill = etree.SubElement(ln, f"{{{NAMESPACES['a']}}}solidFill")
            srgbClr = etree.SubElement(solidFill, f"{{{NAMESPACES['a']}}}srgbClr")
            srgbClr.set('val', color)


def _apply_marker_style(
    ser_element,
    marker_style: str,
    marker_size: int = None,
    color: str = None
):
    """应用标记点样式"""
    # 清除现有的 marker 元素
    for marker in ser_element.findall('c:marker', namespaces=NAMESPACES):
        ser_element.remove(marker)
    
    if marker_style == "none" or marker_style is None:
        # 创建无标记的 marker 元素
        insert_index = _find_insert_position(ser_element, 'marker')
        marker = etree.Element(f"{{{NAMESPACES['c']}}}marker")
        ser_element.insert(insert_index, marker)
        
        symbol = etree.SubElement(marker, f"{{{NAMESPACES['c']}}}symbol")
        symbol.set('val', 'none')
    else:
        # 创建有标记的 marker 元素
        insert_index = _find_insert_position(ser_element, 'marker')
        marker = etree.Element(f"{{{NAMESPACES['c']}}}marker")
        ser_element.insert(insert_index, marker)
        
        # 标记样式
        symbol = etree.SubElement(marker, f"{{{NAMESPACES['c']}}}symbol")
        symbol.set('val', marker_style)
        
        # 标记大小
        if marker_size is not None:
            size = etree.SubElement(marker, f"{{{NAMESPACES['c']}}}size")
            size.set('val', str(marker_size))
        
        # 标记颜色（如果提供）
        if color is not None:
            spPr = etree.SubElement(marker, f"{{{NAMESPACES['c']}}}spPr")
            solidFill = etree.SubElement(spPr, f"{{{NAMESPACES['a']}}}solidFill")
            srgbClr = etree.SubElement(solidFill, f"{{{NAMESPACES['a']}}}srgbClr")
            srgbClr.set('val', color)


def _find_insert_position(parent, target_element: str) -> int:
    """
    查找元素的正确插入位置（按照 OOXML 规范的顺序）
    
    OOXML 规范中 <c:ser> 的子元素顺序：
    1. idx
    2. order
    3. tx
    4. spPr (shape properties)
    5. marker
    6. cat / xVal
    7. val / yVal
    8. smooth
    """
    element_order = {
        'idx': 0,
        'order': 1,
        'tx': 2,
        'spPr': 3,
        'marker': 4,
        'cat': 5,
        'xVal': 5,
        'val': 6,
        'yVal': 6,
        'smooth': 7,
    }
    
    target_order = element_order.get(target_element, 99)
    
    # 查找第一个顺序大于 target 的元素位置
    for i, child in enumerate(parent):
        tag = child.tag.split('}')[-1] if '}' in child.tag else child.tag
        child_order = element_order.get(tag, 99)
        if child_order > target_order:
            return i
    
    # 如果没找到，返回末尾位置
    return len(parent)


def get_color_for_series(series_index: int, color_scheme: str = "default") -> str:
    """
    为系列获取颜色
    
    Args:
        series_index: 系列索引（0-based）
        color_scheme: 颜色方案名称
        
    Returns:
        RGB 颜色字符串（6位十六进制）
    """
    colors = COLOR_SCHEMES.get(color_scheme, DEFAULT_COLOR_SEQUENCE)
    return colors[series_index % len(colors)]


# ============================================================================
# 预设样式配置
# ============================================================================

class StyleConfig:
    """样式配置类"""
    
    def __init__(
        self,
        color_scheme: str = "default",
        line_width_pt: float = 1.0,
        marker_style: str = "none",
        marker_size: int = 5,
    ):
        """
        初始化样式配置
        
        Args:
            color_scheme: 颜色方案（"default", "dark_only", "light_only" 等）
            line_width_pt: 线宽（pt）
            marker_style: 标记点样式（"none", "circle", "square" 等）
            marker_size: 标记点大小（pt）
        """
        self.color_scheme = color_scheme
        self.line_width = LINE_WIDTH_PT.get(line_width_pt, DEFAULT_LINE_WIDTH)
        self.marker_style = marker_style
        self.marker_size = marker_size
    
    def apply_to_series(self, ser_element, series_index: int):
        """
        将样式应用到系列元素
        
        Args:
            ser_element: 系列元素
            series_index: 系列索引（用于选择颜色）
        """
        color = get_color_for_series(series_index, self.color_scheme)
        
        apply_series_style(
            ser_element,
            color=color,
            line_width=self.line_width,
            marker_style=self.marker_style,
            marker_size=self.marker_size,
        )


# 默认样式配置
DEFAULT_STYLE_CONFIG = StyleConfig(
    color_scheme="default",
    line_width_pt=1.0,
    marker_style="none",
    marker_size=5,
)

