"""
边框样式组件模块
"""

from __future__ import annotations

from dataclasses import dataclass
from typing import Any, Dict

from openpyxl.cell import Cell as OpenpyxlCell
from openpyxl.styles import Border, Side

from ..color import Color
from .base import BaseStyleComponent


@dataclass
class BorderStyle(BaseStyleComponent):
    """
    边框样式组件

    管理单元格边框相关的样式属性:
    - 四周边框样式 (左、右、上、下)
    - 对角线边框
    - 各边框的颜色
    """

    # 边框样式
    left: str | None = None  # 'thin', 'medium', 'thick', 'double', etc.
    right: str | None = None
    top: str | None = None
    bottom: str | None = None
    diagonal: str | None = None
    diagonal_direction: str | None = None  # 'up', 'down', 'both'

    # 边框颜色
    left_color: Color | None = None
    right_color: Color | None = None
    top_color: Color | None = None
    bottom_color: Color | None = None
    diagonal_color: Color | None = None

    def set(
        self,
        left: str | None = None,
        right: str | None = None,
        top: str | None = None,
        bottom: str | None = None,
        diagonal: str | None = None,
        left_color: str | Color | None = None,
        right_color: str | Color | None = None,
        top_color: str | Color | None = None,
        bottom_color: str | Color | None = None,
        diagonal_color: str | Color | None = None,
        diagonal_direction: str | None = None,
    ) -> BorderStyle:
        """
        批量设置边框属性

        参数:
            left: 左边框样式
            right: 右边框样式
            top: 上边框样式
            bottom: 下边框样式
            diagonal: 对角线边框样式
            left_color: 左边框颜色
            right_color: 右边框颜色
            top_color: 上边框颜色
            bottom_color: 下边框颜色
            diagonal_color: 对角线边框颜色
            diagonal_direction: 对角线方向

        返回:
            self, 支持链式调用
        """
        if left is not None:
            self.left = left
        if right is not None:
            self.right = right
        if top is not None:
            self.top = top
        if bottom is not None:
            self.bottom = bottom
        if diagonal is not None:
            self.diagonal = diagonal
        if diagonal_direction is not None:
            self.diagonal_direction = diagonal_direction

        # 处理颜色
        if left_color is not None:
            self.left_color = (
                Color.from_hex(left_color)
                if isinstance(left_color, str)
                else left_color
            )
        if right_color is not None:
            self.right_color = (
                Color.from_hex(right_color)
                if isinstance(right_color, str)
                else right_color
            )
        if top_color is not None:
            self.top_color = (
                Color.from_hex(top_color) if isinstance(top_color, str) else top_color
            )
        if bottom_color is not None:
            self.bottom_color = (
                Color.from_hex(bottom_color)
                if isinstance(bottom_color, str)
                else bottom_color
            )
        if diagonal_color is not None:
            self.diagonal_color = (
                Color.from_hex(diagonal_color)
                if isinstance(diagonal_color, str)
                else diagonal_color
            )

        return self

    def set_all(self, style: str, color: str | Color | None = None) -> BorderStyle:
        """
        便捷方法: 设置四周边框为相同样式

        参数:
            style: 边框样式 ('thin', 'medium', 'thick' 等)
            color: 边框颜色 (可选)

        返回:
            self, 支持链式调用
        """
        self.left = self.right = self.top = self.bottom = style

        if color is not None:
            c = Color.from_hex(color) if isinstance(color, str) else color
            self.left_color = self.right_color = self.top_color = self.bottom_color = c

        return self

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

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

        # 创建各边的Side对象
        left_side = None
        right_side = None
        top_side = None
        bottom_side = None
        diagonal_side = None

        if self.left is not None:
            left_side = Side(
                style=self.left,
                color=self.left_color.to_openpyxl_color() if self.left_color else None,
            )
        if self.right is not None:
            right_side = Side(
                style=self.right,
                color=(
                    self.right_color.to_openpyxl_color() if self.right_color else None
                ),
            )
        if self.top is not None:
            top_side = Side(
                style=self.top,
                color=self.top_color.to_openpyxl_color() if self.top_color else None,
            )
        if self.bottom is not None:
            bottom_side = Side(
                style=self.bottom,
                color=(
                    self.bottom_color.to_openpyxl_color() if self.bottom_color else None
                ),
            )
        if self.diagonal is not None:
            diagonal_side = Side(
                style=self.diagonal,
                color=(
                    self.diagonal_color.to_openpyxl_color()
                    if self.diagonal_color
                    else None
                ),
            )

        # 创建Border对象
        border_kwargs: Dict[str, Any] = {}
        if left_side is not None:
            border_kwargs["left"] = left_side
        if right_side is not None:
            border_kwargs["right"] = right_side
        if top_side is not None:
            border_kwargs["top"] = top_side
        if bottom_side is not None:
            border_kwargs["bottom"] = bottom_side
        if diagonal_side is not None:
            border_kwargs["diagonal"] = diagonal_side

        if border_kwargs:
            cell.border = Border(**border_kwargs)

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

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

        if self.left is not None:
            result["left"] = self.left
        if self.right is not None:
            result["right"] = self.right
        if self.top is not None:
            result["top"] = self.top
        if self.bottom is not None:
            result["bottom"] = self.bottom
        if self.diagonal is not None:
            result["diagonal"] = self.diagonal
        if self.diagonal_direction is not None:
            result["diagonal_direction"] = self.diagonal_direction

        if self.left_color is not None:
            result["left_color"] = self.left_color.rgb if self.left_color.rgb else None
        if self.right_color is not None:
            result["right_color"] = (
                self.right_color.rgb if self.right_color.rgb else None
            )
        if self.top_color is not None:
            result["top_color"] = self.top_color.rgb if self.top_color.rgb else None
        if self.bottom_color is not None:
            result["bottom_color"] = (
                self.bottom_color.rgb if self.bottom_color.rgb else None
            )
        if self.diagonal_color is not None:
            result["diagonal_color"] = (
                self.diagonal_color.rgb if self.diagonal_color.rgb else None
            )

        return result

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

        参数:
            data: 包含边框属性的字典
        """
        if "left" in data:
            self.left = data["left"]
        if "right" in data:
            self.right = data["right"]
        if "top" in data:
            self.top = data["top"]
        if "bottom" in data:
            self.bottom = data["bottom"]
        if "diagonal" in data:
            self.diagonal = data["diagonal"]
        if "diagonal_direction" in data:
            self.diagonal_direction = data["diagonal_direction"]

        if "left_color" in data and data["left_color"]:
            self.left_color = Color(rgb=data["left_color"])
        if "right_color" in data and data["right_color"]:
            self.right_color = Color(rgb=data["right_color"])
        if "top_color" in data and data["top_color"]:
            self.top_color = Color(rgb=data["top_color"])
        if "bottom_color" in data and data["bottom_color"]:
            self.bottom_color = Color(rgb=data["bottom_color"])
        if "diagonal_color" in data and data["diagonal_color"]:
            self.diagonal_color = Color(rgb=data["diagonal_color"])

    def copy(self) -> BorderStyle:
        """
        深拷贝边框样式

        返回:
            新的BorderStyle实例
        """

        def copy_color(c: Color | None) -> Color | None:
            if c is None:
                return None
            return Color(
                rgb=c.rgb,
                indexed=c.indexed,
                auto=c.auto,
                theme=c.theme,
                tint=c.tint,
            )

        return BorderStyle(
            left=self.left,
            right=self.right,
            top=self.top,
            bottom=self.bottom,
            diagonal=self.diagonal,
            diagonal_direction=self.diagonal_direction,
            left_color=copy_color(self.left_color),
            right_color=copy_color(self.right_color),
            top_color=copy_color(self.top_color),
            bottom_color=copy_color(self.bottom_color),
            diagonal_color=copy_color(self.diagonal_color),
        )
