"""
Symphra Excel库的单元格样式类

重构后使用组合模式管理各个样式组件,保持100%向后兼容。
"""

from __future__ import annotations

from typing import Any

from openpyxl.cell import Cell as OpenpyxlCell

# 导入颜色类和组件
from .color import Color
from .components import (
    AlignmentStyle,
    BorderStyle,
    FillStyle,
    FontStyle,
    NumberFormatStyle,
    ProtectionStyle,
)

# 导出Color类以保持向后兼容
__all__ = ["Color", "CellStyle"]


class CellStyle:
    """
    单元格样式组合容器

    使用组合模式管理各个样式组件:
    - font: 字体样式 (FontStyle)
    - fill: 填充样式 (FillStyle)
    - border: 边框样式 (BorderStyle)
    - alignment: 对齐样式 (AlignmentStyle)
    - number_format: 数字格式 (NumberFormatStyle)
    - protection: 保护属性 (ProtectionStyle)

    保持所有原有API接口,实现向后兼容。
    """

    def __init__(self, name: str | None = None) -> None:
        """
        初始化单元格样式

        参数:
            name: 样式名称,用于命名样式
        """
        self.name = name

        # 组合各个样式组件
        self.font = FontStyle()
        self.fill = FillStyle()
        self.border = BorderStyle()
        self.alignment = AlignmentStyle()
        self._number_format = NumberFormatStyle()
        self.protection = ProtectionStyle()

    # ===== 向后兼容的属性访问器 =====

    @property
    def background_color(self) -> Color | None:
        """获取背景颜色 (fill.fg_color的别名)"""
        return self.fill.fg_color

    @background_color.setter
    def background_color(self, value: str | Color | None) -> None:
        """设置背景颜色 (fill.fg_color的别名)"""
        if isinstance(value, str):
            self.fill.fg_color = Color.from_hex(value)
        else:
            self.fill.fg_color = value
        # 设置背景色时自动使用solid填充
        if value is not None and self.fill.pattern is None:
            self.fill.pattern = "solid"

    # 字体属性的向后兼容访问器
    @property
    def font_name(self) -> str | None:
        return self.font.name

    @font_name.setter
    def font_name(self, value: str | None) -> None:
        self.font.name = value

    @property
    def font_size(self) -> float | None:
        return self.font.size

    @font_size.setter
    def font_size(self, value: float | None) -> None:
        self.font.size = value

    @property
    def font_bold(self) -> bool | None:
        return self.font.bold

    @font_bold.setter
    def font_bold(self, value: bool | None) -> None:
        self.font.bold = value

    @property
    def font_italic(self) -> bool | None:
        return self.font.italic

    @font_italic.setter
    def font_italic(self, value: bool | None) -> None:
        self.font.italic = value

    @property
    def font_underline(self) -> str | None:
        return self.font.underline

    @font_underline.setter
    def font_underline(self, value: str | None) -> None:
        self.font.underline = value

    @property
    def font_strikethrough(self) -> bool | None:
        return self.font.strikethrough

    @font_strikethrough.setter
    def font_strikethrough(self, value: bool | None) -> None:
        self.font.strikethrough = value

    @property
    def font_color(self) -> Color | None:
        return self.font.color

    @font_color.setter
    def font_color(self, value: Color | None) -> None:
        self.font.color = value

    @property
    def font_vert_align(self) -> str | None:
        return self.font.vert_align

    @font_vert_align.setter
    def font_vert_align(self, value: str | None) -> None:
        self.font.vert_align = value

    # 填充属性的向后兼容访问器
    @property
    def fill_pattern(self) -> str | None:
        return self.fill.pattern

    @fill_pattern.setter
    def fill_pattern(self, value: str | None) -> None:
        self.fill.pattern = value

    @property
    def fill_fg_color(self) -> Color | None:
        return self.fill.fg_color

    @fill_fg_color.setter
    def fill_fg_color(self, value: Color | None) -> None:
        self.fill.fg_color = value

    @property
    def fill_bg_color(self) -> Color | None:
        return self.fill.bg_color

    @fill_bg_color.setter
    def fill_bg_color(self, value: Color | None) -> None:
        self.fill.bg_color = value

    # 边框属性的向后兼容访问器
    @property
    def border_left(self) -> str | None:
        return self.border.left

    @border_left.setter
    def border_left(self, value: str | None) -> None:
        self.border.left = value

    @property
    def border_right(self) -> str | None:
        return self.border.right

    @border_right.setter
    def border_right(self, value: str | None) -> None:
        self.border.right = value

    @property
    def border_top(self) -> str | None:
        return self.border.top

    @border_top.setter
    def border_top(self, value: str | None) -> None:
        self.border.top = value

    @property
    def border_bottom(self) -> str | None:
        return self.border.bottom

    @border_bottom.setter
    def border_bottom(self, value: str | None) -> None:
        self.border.bottom = value

    @property
    def border_diagonal(self) -> str | None:
        return self.border.diagonal

    @border_diagonal.setter
    def border_diagonal(self, value: str | None) -> None:
        self.border.diagonal = value

    @property
    def border_diagonal_direction(self) -> str | None:
        return self.border.diagonal_direction

    @border_diagonal_direction.setter
    def border_diagonal_direction(self, value: str | None) -> None:
        self.border.diagonal_direction = value

    @property
    def border_left_color(self) -> Color | None:
        return self.border.left_color

    @border_left_color.setter
    def border_left_color(self, value: Color | None) -> None:
        self.border.left_color = value

    @property
    def border_right_color(self) -> Color | None:
        return self.border.right_color

    @border_right_color.setter
    def border_right_color(self, value: Color | None) -> None:
        self.border.right_color = value

    @property
    def border_top_color(self) -> Color | None:
        return self.border.top_color

    @border_top_color.setter
    def border_top_color(self, value: Color | None) -> None:
        self.border.top_color = value

    @property
    def border_bottom_color(self) -> Color | None:
        return self.border.bottom_color

    @border_bottom_color.setter
    def border_bottom_color(self, value: Color | None) -> None:
        self.border.bottom_color = value

    @property
    def border_diagonal_color(self) -> Color | None:
        return self.border.diagonal_color

    @border_diagonal_color.setter
    def border_diagonal_color(self, value: Color | None) -> None:
        self.border.diagonal_color = value

    # 对齐属性的向后兼容访问器
    @property
    def horizontal_alignment(self) -> str | None:
        return self.alignment.horizontal

    @horizontal_alignment.setter
    def horizontal_alignment(self, value: str | None) -> None:
        self.alignment.horizontal = value

    @property
    def vertical_alignment(self) -> str | None:
        return self.alignment.vertical

    @vertical_alignment.setter
    def vertical_alignment(self, value: str | None) -> None:
        self.alignment.vertical = value

    @property
    def text_rotation(self) -> int | None:
        return self.alignment.text_rotation

    @text_rotation.setter
    def text_rotation(self, value: int | None) -> None:
        self.alignment.text_rotation = value

    @property
    def wrap_text(self) -> bool | None:
        return self.alignment.wrap_text

    @wrap_text.setter
    def wrap_text(self, value: bool | None) -> None:
        self.alignment.wrap_text = value

    @property
    def shrink_to_fit(self) -> bool | None:
        return self.alignment.shrink_to_fit

    @shrink_to_fit.setter
    def shrink_to_fit(self, value: bool | None) -> None:
        self.alignment.shrink_to_fit = value

    @property
    def indent(self) -> int | None:
        return self.alignment.indent

    @indent.setter
    def indent(self, value: int | None) -> None:
        self.alignment.indent = value

    @property
    def reading_order(self) -> int | None:
        return self.alignment.reading_order

    @reading_order.setter
    def reading_order(self, value: int | None) -> None:
        self.alignment.reading_order = value

    # 保护属性的向后兼容访问器
    @property
    def locked(self) -> bool | None:
        return self.protection.locked

    @locked.setter
    def locked(self, value: bool | None) -> None:
        self.protection.locked = value

    @property
    def hidden(self) -> bool | None:
        return self.protection.hidden

    @hidden.setter
    def hidden(self, value: bool | None) -> None:
        self.protection.hidden = value

    # 数字格式的向后兼容访问器
    @property
    def number_format(self) -> str | None:
        """获取数字格式代码"""
        return self._number_format.format_code

    @number_format.setter
    def number_format(self, value: str | None) -> None:
        """设置数字格式代码"""
        self._number_format.format_code = value

    # ===== 向后兼容的便捷方法 =====

    def set_font(
        self,
        name: str | None = None,
        size: float | None = None,
        bold: bool | None = None,
        italic: bool | None = None,
        underline: str | None = None,
        color: str | Color | None = None,
        strikethrough: bool | None = None,
        vert_align: str | None = None,
    ) -> CellStyle:
        """
        设置字体属性

        参数:
            name: 字体名称
            size: 字体大小
            bold: 粗体标志
            italic: 斜体标志
            underline: 下划线样式
            color: 字体颜色
            strikethrough: 删除线标志
            vert_align: 垂直对齐方式

        返回:
            Self,用于链式调用
        """
        self.font.set(
            name=name,
            size=size,
            bold=bold,
            italic=italic,
            underline=underline,
            color=color,
            strikethrough=strikethrough,
            vert_align=vert_align,
        )
        return self

    def set_font_color(self, color: str | Color | None) -> CellStyle:
        """
        设置字体颜色

        参数:
            color: 字体颜色

        返回:
            Self,用于链式调用
        """
        if isinstance(color, str):
            self.font.color = Color.from_hex(color)
        else:
            self.font.color = color
        return self

    def set_fill(
        self,
        pattern: str | None = None,
        fg_color: str | Color | None = None,
        bg_color: str | Color | None = None,
    ) -> CellStyle:
        """
        设置填充属性

        参数:
            pattern: 填充图案
            fg_color: 前景色
            bg_color: 背景色

        返回:
            Self,用于链式调用
        """
        self.fill.set(pattern=pattern, fg_color=fg_color, bg_color=bg_color)
        return self

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

        参数:
            color: 背景颜色

        返回:
            Self,用于链式调用
        """
        self.fill.set_background_color(color)
        return self

    def set_border(
        self,
        left: str | None = None,
        right: str | None = None,
        top: str | None = None,
        bottom: str | None = None,
        diagonal: str | None = None,
        diagonal_direction: 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,
    ) -> CellStyle:
        """
        设置边框属性

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

        返回:
            Self,用于链式调用
        """
        self.border.set(
            left=left,
            right=right,
            top=top,
            bottom=bottom,
            diagonal=diagonal,
            left_color=left_color,
            right_color=right_color,
            top_color=top_color,
            bottom_color=bottom_color,
            diagonal_color=diagonal_color,
            diagonal_direction=diagonal_direction,
        )
        return self

    def set_alignment(
        self,
        horizontal: str | None = None,
        vertical: str | None = None,
        text_rotation: int | None = None,
        wrap_text: bool | None = None,
        shrink_to_fit: bool | None = None,
        indent: int | None = None,
    ) -> CellStyle:
        """
        设置对齐属性

        参数:
            horizontal: 水平对齐
            vertical: 垂直对齐
            text_rotation: 文本旋转角度
            wrap_text: 自动换行标志
            shrink_to_fit: 缩小字体以适应标志
            indent: 缩进级别

        返回:
            Self,用于链式调用
        """
        self.alignment.set(
            horizontal=horizontal,
            vertical=vertical,
            text_rotation=text_rotation,
            wrap_text=wrap_text,
            shrink_to_fit=shrink_to_fit,
            indent=indent,
        )
        return self

    def set_number_format(self, format_code: str) -> CellStyle:
        """
        设置数字格式

        参数:
            format_code: 数字格式代码

        返回:
            Self,用于链式调用
        """
        self._number_format.set(format_code)
        return self

    def set_protection(
        self, locked: bool | None = None, hidden: bool | None = None
    ) -> CellStyle:
        """
        设置保护属性

        参数:
            locked: 锁定标志
            hidden: 隐藏标志

        返回:
            Self,用于链式调用
        """
        self.protection.set(locked=locked, hidden=hidden)
        return self

    # ===== 核心方法 =====

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

        参数:
            cell: openpyxl单元格对象
        """
        # 应用各组件样式
        self.font.apply_to_cell(cell)
        self.fill.apply_to_cell(cell)
        self.border.apply_to_cell(cell)
        self.alignment.apply_to_cell(cell)
        self._number_format.apply_to_cell(cell)
        self.protection.apply_to_cell(cell)

    def copy(self) -> CellStyle:
        """
        深拷贝样式

        返回:
            新的CellStyle实例
        """
        new_style = CellStyle(name=self.name)
        new_style.font = self.font.copy()
        new_style.fill = self.fill.copy()
        new_style.border = self.border.copy()
        new_style.alignment = self.alignment.copy()
        new_style._number_format = self._number_format.copy()
        new_style.protection = self.protection.copy()
        return new_style

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

        返回:
            样式配置字典
        """
        result: dict[str, Any] = {}

        if self.name is not None:
            result["name"] = self.name

        # 获取各组件字典
        font_dict = self.font.to_dict()
        if font_dict:
            result["font"] = font_dict

        fill_dict = self.fill.to_dict()
        if fill_dict:
            result["fill"] = fill_dict

        border_dict = self.border.to_dict()
        if border_dict:
            result["border"] = border_dict

        alignment_dict = self.alignment.to_dict()
        if alignment_dict:
            result["alignment"] = alignment_dict

        number_format_dict = self._number_format.to_dict()
        if number_format_dict:
            result["number_format"] = number_format_dict["format_code"]

        protection_dict = self.protection.to_dict()
        if protection_dict:
            result["protection"] = protection_dict

        return result

    @classmethod
    def from_dict(cls, style_dict: dict[str, Any]) -> CellStyle:
        """
        从字典反序列化

        参数:
            style_dict: 样式配置字典

        返回:
            CellStyle对象
        """
        style = cls(name=style_dict.get("name"))

        # 加载各组件数据
        if "font" in style_dict:
            style.font.from_dict(style_dict["font"])

        if "fill" in style_dict:
            style.fill.from_dict(style_dict["fill"])

        if "border" in style_dict:
            style.border.from_dict(style_dict["border"])

        if "alignment" in style_dict:
            style.alignment.from_dict(style_dict["alignment"])

        if "number_format" in style_dict:
            style._number_format.from_dict({"format_code": style_dict["number_format"]})

        if "protection" in style_dict:
            style.protection.from_dict(style_dict["protection"])

        return style

    # ===== 向后兼容的辅助方法 (私有方法,用于保持兼容性) =====

    def _get_font_dict(self) -> dict[str, Any]:
        """获取字体配置字典 (向后兼容)"""
        return self.font.to_dict()

    def _get_fill_dict(self) -> dict[str, Any]:
        """获取填充配置字典 (向后兼容)"""
        return self.fill.to_dict()

    def _get_border_dict(self) -> dict[str, Any]:
        """获取边框配置字典 (向后兼容)"""
        return self.border.to_dict()

    def _get_alignment_dict(self) -> dict[str, Any]:
        """获取对齐配置字典 (向后兼容)"""
        return self.alignment.to_dict()

    def _get_protection_dict(self) -> dict[str, Any]:
        """获取保护配置字典 (向后兼容)"""
        return self.protection.to_dict()

    def _apply_font_to_cell(self, cell: OpenpyxlCell) -> None:
        """应用字体到单元格 (向后兼容)"""
        self.font.apply_to_cell(cell)

    def _apply_fill_to_cell(self, cell: OpenpyxlCell) -> None:
        """应用填充到单元格 (向后兼容)"""
        self.fill.apply_to_cell(cell)

    def _apply_border_to_cell(self, cell: OpenpyxlCell) -> None:
        """应用边框到单元格 (向后兼容)"""
        self.border.apply_to_cell(cell)

    def _apply_alignment_to_cell(self, cell: OpenpyxlCell) -> None:
        """应用对齐到单元格 (向后兼容)"""
        self.alignment.apply_to_cell(cell)

    def _apply_protection_to_cell(self, cell: OpenpyxlCell) -> None:
        """应用保护到单元格 (向后兼容)"""
        self.protection.apply_to_cell(cell)
