# app/modules/dev_tools/tests/unit/test_isolation_audit_service.py
"""Unit tests for isolation_audit_service."""

from types import SimpleNamespace

import pytest

from app.modules.dev_tools.services.isolation_audit_service import (
    _check_contact_inheritance,
    _check_language_config,
    _check_locale_fallback,
    _check_merchant_active,
    _check_merchant_domain_primary,
    _check_theme_fallback,
    _finding,
)


def _make_store(**kwargs):
    """Create a minimal fake store for testing."""
    defaults = {
        "contact_email": None,
        "contact_phone": None,
        "website": None,
        "business_address": None,
        "tax_number": None,
        "merchant": None,
        "store_platforms": [],
        "domains": [],
        "store_theme": None,
        "storefront_locale": None,
        "storefront_languages": None,
    }
    defaults.update(kwargs)
    return SimpleNamespace(**defaults)


def _make_merchant(**kwargs):
    defaults = {"name": "TestMerchant", "is_active": True}
    defaults.update({k: None for k in ["contact_email", "contact_phone", "website", "business_address", "tax_number"]})
    defaults.update(kwargs)
    return SimpleNamespace(**defaults)


@pytest.mark.unit
@pytest.mark.dev
class TestFinding:
    """Tests for the _finding helper."""

    def test_finding_structure(self):
        result = _finding(
            check="test",
            check_label="Test",
            risk="high",
            resolved_value="val",
            source="store",
            source_label="Store value",
            is_explicit=True,
            note="a note",
        )
        assert result["check"] == "test"
        assert result["risk"] == "high"
        assert result["is_explicit"] is True
        assert result["note"] == "a note"


@pytest.mark.unit
@pytest.mark.dev
class TestCheckContactInheritance:
    """Tests for _check_contact_inheritance."""

    def test_no_findings_when_store_has_values(self):
        store = _make_store(
            contact_email="shop@test.com",
            contact_phone="+352123",
            website="https://test.com",
            business_address="123 Main St",
            tax_number="LU12345",
            merchant=_make_merchant(),
        )
        assert _check_contact_inheritance(store) == []

    def test_critical_when_inheriting_from_merchant(self):
        merchant = _make_merchant(contact_email="merchant@test.com")
        store = _make_store(merchant=merchant)
        findings = _check_contact_inheritance(store)
        email_findings = [f for f in findings if f["check"] == "contact_email"]
        assert len(email_findings) == 1
        assert email_findings[0]["risk"] == "critical"
        assert email_findings[0]["source"] == "merchant"

    def test_critical_when_no_value_anywhere(self):
        store = _make_store(merchant=_make_merchant())
        findings = _check_contact_inheritance(store)
        email_findings = [f for f in findings if f["check"] == "contact_email"]
        assert len(email_findings) == 1
        assert email_findings[0]["source"] == "none"


@pytest.mark.unit
@pytest.mark.dev
class TestCheckMerchantActive:
    """Tests for _check_merchant_active."""

    def test_no_finding_when_active(self):
        store = _make_store(merchant=_make_merchant(is_active=True))
        assert _check_merchant_active(store) == []

    def test_finding_when_inactive(self):
        store = _make_store(merchant=_make_merchant(is_active=False))
        findings = _check_merchant_active(store)
        assert len(findings) == 1
        assert findings[0]["risk"] == "high"


@pytest.mark.unit
@pytest.mark.dev
class TestCheckMerchantDomainPrimary:
    """Tests for _check_merchant_domain_primary."""

    def test_no_finding_single_primary(self):
        domains = [SimpleNamespace(domain="test.com", is_primary=True, is_active=True)]
        assert _check_merchant_domain_primary(domains) == []

    def test_finding_multiple_primaries(self):
        domains = [
            SimpleNamespace(domain="a.com", is_primary=True, is_active=True),
            SimpleNamespace(domain="b.com", is_primary=True, is_active=True),
        ]
        findings = _check_merchant_domain_primary(domains)
        assert len(findings) == 1
        assert findings[0]["risk"] == "high"


@pytest.mark.unit
@pytest.mark.dev
class TestCheckThemeFallback:
    """Tests for _check_theme_fallback."""

    def test_no_finding_with_active_theme(self):
        store = _make_store(store_theme=SimpleNamespace(is_active=True))
        assert _check_theme_fallback(store) == []

    def test_finding_no_theme(self):
        store = _make_store(store_theme=None)
        findings = _check_theme_fallback(store)
        assert len(findings) == 1
        assert findings[0]["risk"] == "medium"


@pytest.mark.unit
@pytest.mark.dev
class TestCheckLocaleFallback:
    """Tests for _check_locale_fallback."""

    def test_no_finding_with_locale(self):
        store = _make_store(storefront_locale="de-LU")
        assert _check_locale_fallback(store, "fr-LU") == []

    def test_finding_platform_default(self):
        store = _make_store(storefront_locale=None)
        findings = _check_locale_fallback(store, "de-LU")
        assert len(findings) == 1
        assert findings[0]["resolved_value"] == "de-LU"
        assert findings[0]["source"] == "platform_default"

    def test_finding_hardcoded_fallback(self):
        store = _make_store(storefront_locale=None)
        findings = _check_locale_fallback(store, None)
        assert len(findings) == 1
        assert findings[0]["resolved_value"] == "fr-LU"
        assert findings[0]["source"] == "hardcoded"


@pytest.mark.unit
@pytest.mark.dev
class TestCheckLanguageConfig:
    """Tests for _check_language_config."""

    def test_no_finding_custom_languages(self):
        store = _make_store(storefront_languages=["fr", "en"])
        assert _check_language_config(store) == []

    def test_finding_default_languages(self):
        store = _make_store(storefront_languages=["fr", "de", "en", "lb"])
        findings = _check_language_config(store)
        assert len(findings) == 1
        assert findings[0]["risk"] == "medium"

    def test_finding_none_languages(self):
        store = _make_store(storefront_languages=None)
        findings = _check_language_config(store)
        assert len(findings) == 1
