"""Tests for the ICD service — normalize, validate, coding template."""

from io import BytesIO
from unittest.mock import MagicMock, PropertyMock

import pytest
from openpyxl import load_workbook

from app.services.icd_service import generate_coding_template, normalize_and_validate_icd


# ── normalize_and_validate_icd ─────────────────────────────────────


class TestNormalizeAndValidateICD:
    def test_normalize_and_validate_single(self):
        result = normalize_and_validate_icd("C50.1")
        assert result == [("C50.1", "C50")]

    def test_normalize_and_validate_multiple(self):
        result = normalize_and_validate_icd("C50.1, C79.5")
        assert result == [("C50.1", "C50"), ("C79.5", "C79")]

    def test_normalize_and_validate_semicolon(self):
        result = normalize_and_validate_icd("c50;D12.3")
        assert result == [("C50", "C50"), ("D12.3", "D12")]

    def test_normalize_and_validate_invalid(self):
        with pytest.raises(ValueError, match="Invalid ICD code format"):
            normalize_and_validate_icd("XYZ")

    def test_normalize_and_validate_empty(self):
        result = normalize_and_validate_icd("")
        assert result == []


# ── generate_coding_template ──────────────────────────────────────


class TestGenerateCodingTemplate:
    def test_generate_coding_template_returns_bytes(self):
        """Mock the DB session and verify the template is valid xlsx bytes."""
        from datetime import date

        # Create mock cases
        mock_case = MagicMock()
        mock_case.id = 1
        mock_case.fall_id = "FALL-001"
        mock_case.nachname = "Mustermann"
        mock_case.vorname = "Max"
        mock_case.fallgruppe = "onko"
        mock_case.datum = date(2026, 2, 24)

        # Build a mock query chain
        mock_db = MagicMock(spec=["query"])
        mock_query = MagicMock()
        mock_db.query.return_value = mock_query
        mock_query.filter.return_value = mock_query
        mock_query.count.return_value = 1
        mock_query.order_by.return_value = mock_query
        mock_query.offset.return_value = mock_query
        mock_query.limit.return_value = mock_query
        mock_query.all.return_value = [mock_case]

        result = generate_coding_template(mock_db, jahr=2026, fallgruppe="onko")

        # Verify it is non-empty bytes
        assert isinstance(result, bytes)
        assert len(result) > 0

        # Verify it is valid xlsx
        wb = load_workbook(BytesIO(result))
        ws = wb.active
        assert ws.title == "ICD Coding"

        # Verify header row (no patient names for DSGVO)
        headers = [cell.value for cell in ws[1]]
        assert headers == [
            "Case_ID",
            "Fall_ID",
            "Fallgruppe",
            "Datum",
            "ICD",
        ]

        # Verify data row (no nachname/vorname)
        row2 = [cell.value for cell in ws[2]]
        assert row2[0] == 1
        assert row2[1] == "FALL-001"
        assert row2[2] == "onko"
        assert row2[3] == "2026-02-24"
        assert row2[4] is None  # ICD column should be empty
