from unittest.mock import AsyncMock

from openpyxl import Workbook

from src.services.export_service import ExportService
from src.services.export_service.export_mappings import (
    FORM1_FLAT_COLUMNS,
    SMETA_COLUMNS,
)
from src.services.export_service.export_writers import TabularSheetWriter


def test_tabular_sheet_writer_writes_headers_and_rows():
    writer = TabularSheetWriter(
        columns=[("a", "A"), ("b", "B")],
        row_normalizer=lambda row: row,
        value_serializer=lambda value: value,
    )
    wb = Workbook()
    ws = wb.active

    rows = [(None, None, None, {"a": 1, "b": 2})]
    writer.write(ws, rows)

    assert ws.cell(row=1, column=1).value == "A"
    assert ws.cell(row=1, column=2).value == "B"
    assert ws.cell(row=2, column=1).value == 1
    assert ws.cell(row=2, column=2).value == 2


def test_sheet_column_contracts_are_stable():
    assert len(FORM1_FLAT_COLUMNS) == 17
    assert len(SMETA_COLUMNS) == 41
    assert FORM1_FLAT_COLUMNS[0] == ("section", "Код раздела")
    assert SMETA_COLUMNS[0] == ("section_code", "Код раздела")


def test_export_service_uses_sheet_writer_strategy():
    service = ExportService(AsyncMock())

    class Recorder:
        def __init__(self):
            self.calls = 0

        def write(self, worksheet, rows):
            self.calls += 1
            worksheet.append(["ok"])

    default_writer = Recorder()
    smeta_writer = Recorder()
    service.sheet_writers = {"__default__": default_writer, "SMETA": smeta_writer}

    wb = Workbook()
    ws_default = wb.active
    ws_smeta = wb.create_sheet("smeta")
    service._write_sheet_rows(ws_default, [], "AHR")
    service._write_sheet_rows(ws_smeta, [], "SMETA")

    assert default_writer.calls == 1
    assert smeta_writer.calls == 1
