"""
样式组件单元测试

测试所有样式组件的功能和行为:
- FontStyle
- FillStyle
- BorderStyle
- AlignmentStyle
- NumberFormatStyle
- ProtectionStyle
"""

from openpyxl import Workbook

from symphra_excel.styles.color import Color
from symphra_excel.styles.components import (
    AlignmentStyle,
    BorderStyle,
    FillStyle,
    FontStyle,
    NumberFormatStyle,
    ProtectionStyle,
)


class TestFontStyle:
    """FontStyle组件测试"""

    def test_font_style_init(self):
        """测试FontStyle初始化"""
        font = FontStyle()
        assert font.name == "Calibri"
        assert font.size == 11
        assert font.bold is None
        assert font.italic is None

    def test_font_style_set(self):
        """测试FontStyle批量设置"""
        font = FontStyle()
        font.set(name="Arial", size=14, bold=True, color=Color.RED)

        assert font.name == "Arial"
        assert font.size == 14
        assert font.bold is True
        assert font.color == Color.RED

    def test_font_style_set_with_hex_color(self):
        """测试使用十六进制字符串设置颜色"""
        font = FontStyle()
        font.set(color="#FF0000")

        assert font.color is not None
        assert font.color.rgb == "FFFF0000"

    def test_font_style_to_dict(self):
        """测试FontStyle序列化"""
        font = FontStyle()
        font.set(name="宋体", size=12, bold=True, italic=True, color=Color.RED)

        font_dict = font.to_dict()
        assert font_dict["name"] == "宋体"
        assert font_dict["size"] == 12
        assert font_dict["bold"] is True
        assert font_dict["italic"] is True
        assert font_dict["color"] == "FFFF0000"

    def test_font_style_from_dict(self):
        """测试FontStyle反序列化"""
        font = FontStyle()
        font.from_dict({"name": "Arial", "size": 14, "bold": True, "color": "FFFF0000"})

        assert font.name == "Arial"
        assert font.size == 14
        assert font.bold is True
        assert font.color is not None
        assert font.color.rgb == "FFFF0000"

    def test_font_style_copy(self):
        """测试FontStyle深拷贝"""
        font1 = FontStyle()
        font1.set(name="Arial", size=14, bold=True, color=Color.RED)

        font2 = font1.copy()
        assert font2.name == "Arial"
        assert font2.size == 14
        assert font2.bold is True

        # 修改副本不影响原对象
        font2.name = "宋体"
        assert font1.name == "Arial"

    def test_font_style_apply_to_cell(self):
        """测试FontStyle应用到单元格"""
        wb = Workbook()
        ws = wb.active
        cell = ws["A1"]

        font = FontStyle()
        font.set(name="Arial", size=14, bold=True, color=Color.RED)
        font.apply_to_cell(cell)

        assert cell.font.name == "Arial"
        assert cell.font.size == 14
        assert cell.font.bold is True

    def test_font_style_has_settings(self):
        """测试has_settings方法"""
        font1 = FontStyle(name=None, size=None)
        assert not font1.has_settings()

        font2 = FontStyle(name="Arial")
        assert font2.has_settings()


class TestFillStyle:
    """FillStyle组件测试"""

    def test_fill_style_init(self):
        """测试FillStyle初始化"""
        fill = FillStyle()
        assert fill.pattern is None
        assert fill.fg_color is None
        assert fill.bg_color is None

    def test_fill_style_set(self):
        """测试FillStyle批量设置"""
        fill = FillStyle()
        fill.set(pattern="solid", fg_color=Color.YELLOW)

        assert fill.pattern == "solid"
        assert fill.fg_color == Color.YELLOW

    def test_fill_style_set_background_color(self):
        """测试便捷方法set_background_color"""
        fill = FillStyle()
        fill.set_background_color("#FFFF00")

        assert fill.fg_color is not None
        assert fill.fg_color.rgb == "FFFFFF00"  # FFFF00 = 黄色
        assert fill.pattern == "solid"  # 自动设置为solid

    def test_fill_style_to_dict(self):
        """测试FillStyle序列化"""
        fill = FillStyle()
        fill.set(pattern="solid", fg_color=Color.YELLOW)

        fill_dict = fill.to_dict()
        assert fill_dict["pattern"] == "solid"
        assert fill_dict["fg_color"] == "FFFFFF00"

    def test_fill_style_from_dict(self):
        """测试FillStyle反序列化"""
        fill = FillStyle()
        fill.from_dict({"pattern": "solid", "fg_color": "FFFFFF00"})

        assert fill.pattern == "solid"
        assert fill.fg_color is not None
        assert fill.fg_color.rgb == "FFFFFF00"

    def test_fill_style_copy(self):
        """测试FillStyle深拷贝"""
        fill1 = FillStyle()
        fill1.set(pattern="solid", fg_color=Color.YELLOW)

        fill2 = fill1.copy()
        assert fill2.pattern == "solid"

        # 修改副本不影响原对象
        fill2.pattern = "gray"
        assert fill1.pattern == "solid"

    def test_fill_style_apply_to_cell(self):
        """测试FillStyle应用到单元格"""
        wb = Workbook()
        ws = wb.active
        cell = ws["A1"]

        fill = FillStyle()
        fill.set(pattern="solid", fg_color=Color.YELLOW)
        fill.apply_to_cell(cell)

        assert cell.fill.patternType == "solid"


class TestBorderStyle:
    """BorderStyle组件测试"""

    def test_border_style_init(self):
        """测试BorderStyle初始化"""
        border = BorderStyle()
        assert border.left is None
        assert border.right is None
        assert border.top is None
        assert border.bottom is None

    def test_border_style_set(self):
        """测试BorderStyle批量设置"""
        border = BorderStyle()
        border.set(
            left="thin", right="thin", top="thin", bottom="thin", left_color=Color.BLACK
        )

        assert border.left == "thin"
        assert border.right == "thin"
        assert border.top == "thin"
        assert border.bottom == "thin"
        assert border.left_color == Color.BLACK

    def test_border_style_set_all(self):
        """测试便捷方法set_all"""
        border = BorderStyle()
        border.set_all("thin", Color.BLACK)

        assert border.left == "thin"
        assert border.right == "thin"
        assert border.top == "thin"
        assert border.bottom == "thin"
        assert border.left_color == Color.BLACK
        assert border.right_color == Color.BLACK

    def test_border_style_to_dict(self):
        """测试BorderStyle序列化"""
        border = BorderStyle()
        border.set(left="thin", top="thick", left_color=Color.BLACK)

        border_dict = border.to_dict()
        assert border_dict["left"] == "thin"
        assert border_dict["top"] == "thick"
        assert border_dict["left_color"] == "FF000000"

    def test_border_style_from_dict(self):
        """测试BorderStyle反序列化"""
        border = BorderStyle()
        border.from_dict({"left": "thin", "top": "thick", "left_color": "FF000000"})

        assert border.left == "thin"
        assert border.top == "thick"
        assert border.left_color is not None

    def test_border_style_copy(self):
        """测试BorderStyle深拷贝"""
        border1 = BorderStyle()
        border1.set(left="thin", left_color=Color.BLACK)

        border2 = border1.copy()
        assert border2.left == "thin"

        # 修改副本不影响原对象
        border2.left = "thick"
        assert border1.left == "thin"

    def test_border_style_apply_to_cell(self):
        """测试BorderStyle应用到单元格"""
        wb = Workbook()
        ws = wb.active
        cell = ws["A1"]

        border = BorderStyle()
        border.set(left="thin", top="thin")
        border.apply_to_cell(cell)

        assert cell.border.left.style == "thin"
        assert cell.border.top.style == "thin"


class TestAlignmentStyle:
    """AlignmentStyle组件测试"""

    def test_alignment_style_init(self):
        """测试AlignmentStyle初始化"""
        alignment = AlignmentStyle()
        assert alignment.horizontal is None
        assert alignment.vertical is None
        assert alignment.wrap_text is None

    def test_alignment_style_set(self):
        """测试AlignmentStyle批量设置"""
        alignment = AlignmentStyle()
        alignment.set(horizontal="center", vertical="center", wrap_text=True)

        assert alignment.horizontal == "center"
        assert alignment.vertical == "center"
        assert alignment.wrap_text is True

    def test_alignment_style_to_dict(self):
        """测试AlignmentStyle序列化"""
        alignment = AlignmentStyle()
        alignment.set(horizontal="center", vertical="top", wrap_text=True)

        alignment_dict = alignment.to_dict()
        assert alignment_dict["horizontal"] == "center"
        assert alignment_dict["vertical"] == "top"
        assert alignment_dict["wrap_text"] is True

    def test_alignment_style_from_dict(self):
        """测试AlignmentStyle反序列化"""
        alignment = AlignmentStyle()
        alignment.from_dict({"horizontal": "center", "wrap_text": True})

        assert alignment.horizontal == "center"
        assert alignment.wrap_text is True

    def test_alignment_style_copy(self):
        """测试AlignmentStyle深拷贝"""
        alignment1 = AlignmentStyle()
        alignment1.set(horizontal="center", wrap_text=True)

        alignment2 = alignment1.copy()
        assert alignment2.horizontal == "center"

        # 修改副本不影响原对象
        alignment2.horizontal = "left"
        assert alignment1.horizontal == "center"

    def test_alignment_style_apply_to_cell(self):
        """测试AlignmentStyle应用到单元格"""
        wb = Workbook()
        ws = wb.active
        cell = ws["A1"]

        alignment = AlignmentStyle()
        alignment.set(horizontal="center", vertical="center", wrap_text=True)
        alignment.apply_to_cell(cell)

        assert cell.alignment.horizontal == "center"
        assert cell.alignment.vertical == "center"
        assert cell.alignment.wrapText is True


class TestNumberFormatStyle:
    """NumberFormatStyle组件测试"""

    def test_number_format_style_init(self):
        """测试NumberFormatStyle初始化"""
        nf = NumberFormatStyle()
        assert nf.format_code is None

    def test_number_format_style_set(self):
        """测试NumberFormatStyle设置"""
        nf = NumberFormatStyle()
        nf.set("0.00%")

        assert nf.format_code == "0.00%"

    def test_number_format_style_to_dict(self):
        """测试NumberFormatStyle序列化"""
        nf = NumberFormatStyle()
        nf.set("yyyy-mm-dd")

        nf_dict = nf.to_dict()
        assert nf_dict["format_code"] == "yyyy-mm-dd"

    def test_number_format_style_from_dict(self):
        """测试NumberFormatStyle反序列化"""
        nf = NumberFormatStyle()
        nf.from_dict({"format_code": "$#,##0.00"})

        assert nf.format_code == "$#,##0.00"

    def test_number_format_style_copy(self):
        """测试NumberFormatStyle深拷贝"""
        nf1 = NumberFormatStyle()
        nf1.set("0.00%")

        nf2 = nf1.copy()
        assert nf2.format_code == "0.00%"

        # 修改副本不影响原对象
        nf2.format_code = "0.00"
        assert nf1.format_code == "0.00%"

    def test_number_format_style_apply_to_cell(self):
        """测试NumberFormatStyle应用到单元格"""
        wb = Workbook()
        ws = wb.active
        cell = ws["A1"]

        nf = NumberFormatStyle()
        nf.set("0.00%")
        nf.apply_to_cell(cell)

        assert cell.number_format == "0.00%"


class TestProtectionStyle:
    """ProtectionStyle组件测试"""

    def test_protection_style_init(self):
        """测试ProtectionStyle初始化"""
        protection = ProtectionStyle()
        assert protection.locked is None
        assert protection.hidden is None

    def test_protection_style_set(self):
        """测试ProtectionStyle设置"""
        protection = ProtectionStyle()
        protection.set(locked=True, hidden=False)

        assert protection.locked is True
        assert protection.hidden is False

    def test_protection_style_to_dict(self):
        """测试ProtectionStyle序列化"""
        protection = ProtectionStyle()
        protection.set(locked=True, hidden=False)

        protection_dict = protection.to_dict()
        assert protection_dict["locked"] is True
        assert protection_dict["hidden"] is False

    def test_protection_style_from_dict(self):
        """测试ProtectionStyle反序列化"""
        protection = ProtectionStyle()
        protection.from_dict({"locked": False, "hidden": True})

        assert protection.locked is False
        assert protection.hidden is True

    def test_protection_style_copy(self):
        """测试ProtectionStyle深拷贝"""
        protection1 = ProtectionStyle()
        protection1.set(locked=True, hidden=False)

        protection2 = protection1.copy()
        assert protection2.locked is True

        # 修改副本不影响原对象
        protection2.locked = False
        assert protection1.locked is True

    def test_protection_style_apply_to_cell(self):
        """测试ProtectionStyle应用到单元格"""
        wb = Workbook()
        ws = wb.active
        cell = ws["A1"]

        protection = ProtectionStyle()
        protection.set(locked=True, hidden=False)
        protection.apply_to_cell(cell)

        assert cell.protection.locked is True
        assert cell.protection.hidden is False
