import pytest

from excellikeuno.connection import connect_calc
from excellikeuno.typing.structs import BorderLine, BorderLine2


def _connect_or_skip():
    try:
        return connect_calc()
    except RuntimeError as exc:
        pytest.skip(f"UNO runtime not available: {exc}")


def test_cellproperties_get_set_property_methods():
    _, _, sheet = _connect_or_skip()
    cell = sheet.cell(0, 2)
    original_color = cell.props.CellBackColor
    new_color = 0x778899 if original_color != 0x778899 else 0x99aabb
    try:
        cell.CellBackColor = new_color
        assert cell.props.CellBackColor == new_color
    finally:
        cell.props.CellBackColor = original_color


def test_cellproperties_uno_method_aliases():
    _, _, sheet = _connect_or_skip()
    cell = sheet.cell(1, 2)
    props = cell.props
    original_color = props.getPropertyValue("CellBackColor")
    new_color = 0xaabbcc if original_color != 0xaabbcc else 0xccbbaa
    try:
        props.setPropertyValue("CellBackColor", new_color)
        assert cell.CellBackColor == new_color
    finally:
        props.setPropertyValue("CellBackColor", original_color)


def test_cellproperties_attribute_passthrough():
    _, _, sheet = _connect_or_skip()
    cell = sheet.cell(2, 2)
    original_wrap = cell.props.IsTextWrapped
    new_wrap = not original_wrap
    try:
        cell.props.IsTextWrapped = new_wrap
        assert cell.props.IsTextWrapped is new_wrap
    finally:
        cell.props.IsTextWrapped = original_wrap


def test_cell_topborder_roundtrip():
    _, _, sheet = _connect_or_skip()
    cell = sheet.cell(3, 2)

    # capture original border and prepare a new one
    original_border = cell.borders.top.line
    new_border = BorderLine(Color=0x123456, OuterLineWidth=50)

    try:
        cell.borders.apply(top=new_border)
        updated = cell.borders.top.line
        assert int(getattr(updated, "Color", 0)) == 0x123456
        # LibreOffice may normalize width; allow small drift.
        assert abs(int(getattr(updated, "OuterLineWidth", 0)) - 50) <= 2
    finally:
        cell.borders.apply(top=original_border)


def test_cell_topborder2_roundtrip():
    _, _, sheet = _connect_or_skip()
    cell = sheet.cell(4, 2)

    original_border = getattr(cell, "TopBorder2", None)
    new_border = BorderLine2(Color=0x654321, OuterLineWidth=60, LineWidth=60)

    try:
        cell.TopBorder2 = new_border
        updated = cell.TopBorder2
        assert updated.Color == 0x654321
        assert abs(int(updated.OuterLineWidth) - 60) <= 2
        assert abs(int(updated.LineWidth) - 60) <= 2
    finally:
        if original_border is not None:
            cell.TopBorder2 = original_border


def test_cell_horijustify_enum_roundtrip():
    _, _, sheet = _connect_or_skip()
    from excellikeuno.typing import CellHoriJustify

    cell = sheet.cell(5, 2)
    original = cell.HoriJustify
    new_value = CellHoriJustify.LEFT if original != CellHoriJustify.LEFT else CellHoriJustify.RIGHT
    try:
        cell.HoriJustify = new_value
        # UNO enums do not match the Python IntEnum type; compare by name instead.
        enum_value = getattr(cell.HoriJustify, "value", None) or str(cell.HoriJustify)
        assert str(enum_value) == new_value.name
    finally:
        cell.HoriJustify = original


def test_cell_vertjustify_enum_roundtrip():
    _, _, sheet = _connect_or_skip()
    from excellikeuno.typing import CellVertJustify

    cell = sheet.cell(5, 3)
    original = cell.VertJustify
    new_value = CellVertJustify.TOP if original != CellVertJustify.TOP else CellVertJustify.BOTTOM
    try:
        cell.VertJustify = new_value
        assert cell.VertJustify == new_value
    finally:
        cell.VertJustify = original
