"""Unit tests for Document enum validation in neo4j_client.

Covers:
  - VALID_DOC_STATUS constant values
  - VALID_DOC_ADMIN_LEVEL constant values
  - _validate_doc_enum() behavior for valid/invalid/empty values

These tests do NOT require a running Neo4j instance.

Run:  pytest tests/test_neo4j_enum_unit.py -v
"""

from __future__ import annotations

import pytest

from app.infrastructure.neo4j_client import (
    VALID_DOC_ADMIN_LEVEL,
    VALID_DOC_STATUS,
    _validate_doc_enum,
)


# ===========================================================================
# Test: enum constants match PRD §4.2
# ===========================================================================


class TestEnumConstants:
    """Ensure enum sets match the PRD definition exactly."""

    def test_status_enum_values(self):
        expected = {"有效", "部分失效", "已废止", "失效", "待确认"}
        assert VALID_DOC_STATUS == expected

    def test_admin_level_enum_values(self):
        expected = {"国家级", "省级", "市级", "区县级", "乡镇街道级", "其他", "未知"}
        assert VALID_DOC_ADMIN_LEVEL == expected

    def test_status_count(self):
        assert len(VALID_DOC_STATUS) == 5

    def test_admin_level_count(self):
        assert len(VALID_DOC_ADMIN_LEVEL) == 7


# ===========================================================================
# Test: _validate_doc_enum function
# ===========================================================================


class TestValidateDocEnum:
    """Test _validate_doc_enum() sanitisation logic."""

    # ── valid values pass through unchanged ────────────────────────────────

    @pytest.mark.parametrize("status", list(VALID_DOC_STATUS))
    def test_valid_status_kept(self, status):
        props = {"doc_id": "test", "status": status}
        result = _validate_doc_enum(props)
        assert result["status"] == status

    @pytest.mark.parametrize("level", list(VALID_DOC_ADMIN_LEVEL))
    def test_valid_admin_level_kept(self, level):
        props = {"doc_id": "test", "admin_level": level}
        result = _validate_doc_enum(props)
        assert result["admin_level"] == level

    # ── invalid values are removed ─────────────────────────────────────────

    @pytest.mark.parametrize("bad_status", [
        "过期", "无效", "有效的", "active", "废止", "部分有效",
    ])
    def test_invalid_status_removed(self, bad_status):
        props = {"doc_id": "test", "status": bad_status}
        result = _validate_doc_enum(props)
        assert "status" not in result
        assert result["doc_id"] == "test"  # other fields kept

    @pytest.mark.parametrize("bad_level", [
        "县级", "区级", "县区级", "中央", "national", "镇级",
    ])
    def test_invalid_admin_level_removed(self, bad_level):
        props = {"doc_id": "test", "admin_level": bad_level}
        result = _validate_doc_enum(props)
        assert "admin_level" not in result
        assert result["doc_id"] == "test"

    # ── empty / missing values are left as-is ──────────────────────────────

    def test_empty_status_not_removed(self):
        """Empty string status should pass through (not treated as invalid)."""
        props = {"doc_id": "test", "status": ""}
        result = _validate_doc_enum(props)
        assert result.get("status") == ""

    def test_empty_admin_level_not_removed(self):
        props = {"doc_id": "test", "admin_level": ""}
        result = _validate_doc_enum(props)
        assert result.get("admin_level") == ""

    def test_missing_fields_no_error(self):
        """No status / admin_level at all — should not raise."""
        props = {"doc_id": "test", "title": "测试文档"}
        result = _validate_doc_enum(props)
        assert result == {"doc_id": "test", "title": "测试文档"}

    # ── combined validation ────────────────────────────────────────────────

    def test_both_valid(self):
        props = {"status": "有效", "admin_level": "省级", "doc_id": "x"}
        result = _validate_doc_enum(props)
        assert result["status"] == "有效"
        assert result["admin_level"] == "省级"

    def test_status_invalid_admin_valid(self):
        props = {"status": "过期", "admin_level": "市级", "doc_id": "x"}
        result = _validate_doc_enum(props)
        assert "status" not in result
        assert result["admin_level"] == "市级"

    def test_status_valid_admin_invalid(self):
        props = {"status": "失效", "admin_level": "县级", "doc_id": "x"}
        result = _validate_doc_enum(props)
        assert result["status"] == "失效"
        assert "admin_level" not in result

    def test_both_invalid(self):
        props = {"status": "nope", "admin_level": "bad", "doc_id": "x"}
        result = _validate_doc_enum(props)
        assert "status" not in result
        assert "admin_level" not in result
        assert result["doc_id"] == "x"

    # ── mutation check ─────────────────────────────────────────────────────

    def test_modifies_dict_in_place(self):
        """_validate_doc_enum should modify and return the same dict object."""
        props = {"status": "过期", "doc_id": "test"}
        result = _validate_doc_enum(props)
        assert result is props
