import os
import pathlib
import pytest
from openpyxl import load_workbook
from openpyxl.worksheet.worksheet import Worksheet

from backend.ecmk_fetcher.excel_writer import write_row


@pytest.fixture
def xlsx_path(tmp_path: pathlib.Path) -> str:
    return str(tmp_path / "output.xlsx")


def _active_sheet(file_path: str) -> Worksheet:
    ws = load_workbook(file_path).active
    assert isinstance(ws, Worksheet)
    return ws


def test_write_row_creates_file(xlsx_path: str):
    # arrange
    row = {
        "address": "1 Fake Avenue, AB24 5CD",
        "property_type": "House",
        "main_dwelling_floor_1_area_m2": 43.61,
    }

    # act
    write_row(xlsx_path, row)

    # assert
    assert os.path.exists(xlsx_path)
    ws = _active_sheet(xlsx_path)
    assert [c.value for c in ws[1]] == list(row.keys())
    assert [c.value for c in ws[2]] == list(row.values())


def test_write_row_appends_to_existing(xlsx_path: str):
    # arrange
    row_a = {
        "address": "1 Fake Avenue, AB24 5CD",
        "property_type": "House",
        "main_dwelling_floor_1_area_m2": 43.61,
    }
    row_b = {
        "address": "2 Other Street, XY1 2AB",
        "property_type": "Flat",
        "main_dwelling_floor_1_area_m2": 30.0,
    }

    # act
    write_row(xlsx_path, row_a)
    write_row(xlsx_path, row_b)

    # assert
    ws = _active_sheet(xlsx_path)
    assert ws.max_row == 3  # 1 header + 2 data rows
    assert [c.value for c in ws[1]] == list(row_a.keys())
    assert [c.value for c in ws[2]] == list(row_a.values())
    assert [c.value for c in ws[3]] == list(row_b.values())


def test_write_row_inserts_new_columns_at_logical_positions(xlsx_path: str):
    # arrange
    # First row: main_dwelling floor 1 + roof
    # Second row: also has main_dwelling floor 2 — should be inserted between floor 1 and roof,
    # not appended to the end
    row_a = {
        "address": "1 Fake Avenue, AB24 5CD",
        "property_type": "House",
        "main_dwelling_floor_1_area_m2": 43.61,
        "main_dwelling_floor_1_height_m": 2.46,
        "main_dwelling_roof_construction": 4,
    }
    row_b = {
        "address": "2 Other Street, XY1 2AB",
        "property_type": "House",
        "main_dwelling_floor_1_area_m2": 50.0,
        "main_dwelling_floor_1_height_m": 2.5,
        "main_dwelling_floor_2_area_m2": 48.0,
        "main_dwelling_floor_2_height_m": 2.4,
        "main_dwelling_roof_construction": 4,
    }

    # act
    write_row(xlsx_path, row_a)
    write_row(xlsx_path, row_b)

    # assert
    ws = _active_sheet(xlsx_path)

    assert [c.value for c in ws[1]] == [
        "address",
        "property_type",
        "main_dwelling_floor_1_area_m2",
        "main_dwelling_floor_1_height_m",
        "main_dwelling_floor_2_area_m2",  # inserted before roof, not at end
        "main_dwelling_floor_2_height_m",
        "main_dwelling_roof_construction",
    ]

    # row_a had no floor_2 data — those cells should be empty
    assert [c.value for c in ws[2]] == [
        "1 Fake Avenue, AB24 5CD",
        "House",
        43.61,
        2.46,
        None,  # main_dwelling_floor_2_area_m2
        None,  # main_dwelling_floor_2_height_m
        4,
    ]

    # row_b should be fully populated
    assert [c.value for c in ws[3]] == [
        "2 Other Street, XY1 2AB",
        "House",
        50.0,
        2.5,
        48.0,
        2.4,
        4,
    ]
