"""
填充样式组件模块
"""

from __future__ import annotations

from dataclasses import dataclass
from typing import Any, Dict

from openpyxl.cell import Cell as OpenpyxlCell
from openpyxl.styles import PatternFill

from ..color import Color
from .base import BaseStyleComponent


@dataclass
class FillStyle(BaseStyleComponent):
    """
    填充样式组件

    管理单元格填充相关的样式属性:
    - 填充图案类型
    - 前景色 (主要背景色)
    - 背景色 (图案背景色)
    """

    pattern: str | None = None  # 'solid', 'mediumGray', 'darkGray', etc.
    fg_color: Color | None = None  # 前景色 (实际显示的背景色)
    bg_color: Color | None = None  # 背景色 (图案背景色)

    def set(
        self,
        pattern: str | None = None,
        fg_color: str | Color | None = None,
        bg_color: str | Color | None = None,
    ) -> FillStyle:
        """
        批量设置填充属性

        参数:
            pattern: 填充图案类型 ('solid' 为纯色填充)
            fg_color: 前景色 (十六进制字符串或Color对象)
            bg_color: 背景色 (十六进制字符串或Color对象)

        返回:
            self, 支持链式调用
        """
        if pattern is not None:
            self.pattern = pattern
        if fg_color is not None:
            self.fg_color = (
                Color.from_hex(fg_color) if isinstance(fg_color, str) else fg_color
            )
        if bg_color is not None:
            self.bg_color = (
                Color.from_hex(bg_color) if isinstance(bg_color, str) else bg_color
            )
        return self

    def set_background_color(self, color: str | Color | None) -> FillStyle:
        """
        便捷方法: 设置纯色背景

        参数:
            color: 背景颜色 (十六进制字符串或Color对象)

        返回:
            self, 支持链式调用
        """
        if color is not None:
            self.fg_color = Color.from_hex(color) if isinstance(color, str) else color
            # 设置背景色时自动使用solid填充
            if self.pattern is None:
                self.pattern = "solid"
        return self

    def apply_to_cell(self, cell: OpenpyxlCell) -> None:
        """
        应用填充样式到单元格

        参数:
            cell: openpyxl单元格对象
        """
        if not self.has_settings():
            return

        fill_kwargs: Dict[str, Any] = {}

        if self.pattern is not None:
            fill_kwargs["patternType"] = self.pattern
        if self.fg_color is not None:
            fill_kwargs["fgColor"] = self.fg_color.to_openpyxl_color()
        if self.bg_color is not None:
            fill_kwargs["bgColor"] = self.bg_color.to_openpyxl_color()

        if fill_kwargs:
            cell.fill = PatternFill(**fill_kwargs)

    def to_dict(self) -> Dict[str, Any]:
        """
        序列化为字典

        返回:
            包含所有非None填充属性的字典
        """
        result: Dict[str, Any] = {}

        if self.pattern is not None:
            result["pattern"] = self.pattern
        if self.fg_color is not None:
            result["fg_color"] = self.fg_color.rgb if self.fg_color.rgb else None
        if self.bg_color is not None:
            result["bg_color"] = self.bg_color.rgb if self.bg_color.rgb else None

        return result

    def from_dict(self, data: Dict[str, Any]) -> None:
        """
        从字典反序列化

        参数:
            data: 包含填充属性的字典
        """
        if "pattern" in data:
            self.pattern = data["pattern"]
        if "fg_color" in data and data["fg_color"]:
            self.fg_color = Color(rgb=data["fg_color"])
        if "bg_color" in data and data["bg_color"]:
            self.bg_color = Color(rgb=data["bg_color"])

    def copy(self) -> FillStyle:
        """
        深拷贝填充样式

        返回:
            新的FillStyle实例
        """
        return FillStyle(
            pattern=self.pattern,
            fg_color=(
                Color(
                    rgb=self.fg_color.rgb,
                    indexed=self.fg_color.indexed,
                    auto=self.fg_color.auto,
                    theme=self.fg_color.theme,
                    tint=self.fg_color.tint,
                )
                if self.fg_color
                else None
            ),
            bg_color=(
                Color(
                    rgb=self.bg_color.rgb,
                    indexed=self.bg_color.indexed,
                    auto=self.bg_color.auto,
                    theme=self.bg_color.theme,
                    tint=self.bg_color.tint,
                )
                if self.bg_color
                else None
            ),
        )
