"""Tests for Company Profile extension (Phase 2: Stammdaten).

Verifies:
- New JSONB fields in request/response models
- template-context endpoint returns flat dict
- Regulatory booleans default correctly
"""

import pytest
from compliance.api.company_profile_routes import (
    CompanyProfileRequest,
    CompanyProfileResponse,
    row_to_response,
)


# =============================================================================
# Schema Tests — Request Model
# =============================================================================

class TestCompanyProfileRequestExtended:
    def test_default_new_fields(self):
        req = CompanyProfileRequest(company_name="Acme GmbH")
        assert req.repos == []
        assert req.document_sources == []
        assert req.processing_systems == []
        assert req.ai_systems == []
        assert req.technical_contacts == []
        assert req.subject_to_nis2 is False
        assert req.subject_to_ai_act is False
        assert req.subject_to_iso27001 is False
        assert req.supervisory_authority is None
        assert req.review_cycle_months == 12

    def test_full_new_fields(self):
        req = CompanyProfileRequest(
            company_name="Test AG",
            repos=[{"name": "backend", "url": "https://git.example.com/backend", "language": "Python", "has_personal_data": True}],
            processing_systems=[{"name": "SAP HR", "vendor": "SAP", "hosting": "cloud", "personal_data_categories": ["Mitarbeiter"]}],
            ai_systems=[{"name": "Chatbot", "purpose": "Kundenservice", "risk_category": "limited", "vendor": "OpenAI", "has_human_oversight": True}],
            technical_contacts=[{"role": "CISO", "name": "Max Muster", "email": "ciso@example.com"}],
            subject_to_nis2=True,
            subject_to_ai_act=True,
            supervisory_authority="LfDI Baden-Württemberg",
            review_cycle_months=6,
        )
        assert len(req.repos) == 1
        assert req.repos[0]["language"] == "Python"
        assert len(req.ai_systems) == 1
        assert req.subject_to_nis2 is True
        assert req.review_cycle_months == 6

    def test_serialization_includes_new_fields(self):
        req = CompanyProfileRequest(company_name="Test")
        data = req.model_dump()
        assert "repos" in data
        assert "processing_systems" in data
        assert "ai_systems" in data
        assert "subject_to_nis2" in data
        assert "review_cycle_months" in data

    def test_backward_compatible(self):
        """Old-format requests (without new fields) still work."""
        req = CompanyProfileRequest(
            company_name="Legacy Corp",
            legal_form="GmbH",
            industry="Manufacturing",
        )
        assert req.company_name == "Legacy Corp"
        assert req.repos == []
        assert req.subject_to_ai_act is False


# =============================================================================
# Schema Tests — Response Model
# =============================================================================

class TestCompanyProfileResponseExtended:
    def test_response_includes_new_fields(self):
        resp = CompanyProfileResponse(
            id="test-id",
            tenant_id="test-tenant",
            company_name="Test",
            legal_form="GmbH",
            industry="IT",
            founded_year=2020,
            business_model="B2B",
            offerings=[],
            company_size="small",
            employee_count="10-49",
            annual_revenue="< 2 Mio",
            headquarters_country="DE",
            headquarters_city="Berlin",
            has_international_locations=False,
            international_countries=[],
            target_markets=["DE"],
            primary_jurisdiction="DE",
            is_data_controller=True,
            is_data_processor=False,
            uses_ai=True,
            ai_use_cases=["chatbot"],
            dpo_name="DSB",
            dpo_email="dsb@test.de",
            legal_contact_name=None,
            legal_contact_email=None,
            machine_builder=None,
            is_complete=True,
            completed_at="2026-01-01",
            created_at="2025-12-01",
            updated_at="2026-01-01",
            repos=[{"name": "main"}],
            ai_systems=[{"name": "Bot"}],
            subject_to_ai_act=True,
            review_cycle_months=6,
        )
        assert resp.repos == [{"name": "main"}]
        assert resp.ai_systems == [{"name": "Bot"}]
        assert resp.subject_to_ai_act is True
        assert resp.review_cycle_months == 6

    def test_response_defaults(self):
        resp = CompanyProfileResponse(
            id="x", tenant_id="t", company_name="X", legal_form="GmbH",
            industry="", founded_year=None, business_model="B2B", offerings=[],
            company_size="small", employee_count="1-9", annual_revenue="< 2 Mio",
            headquarters_country="DE", headquarters_city="",
            has_international_locations=False, international_countries=[],
            target_markets=["DE"], primary_jurisdiction="DE",
            is_data_controller=True, is_data_processor=False,
            uses_ai=False, ai_use_cases=[], dpo_name=None, dpo_email=None,
            legal_contact_name=None, legal_contact_email=None,
            machine_builder=None, is_complete=False,
            completed_at=None, created_at="2026-01-01", updated_at="2026-01-01",
        )
        assert resp.repos == []
        assert resp.processing_systems == []
        assert resp.subject_to_nis2 is False
        assert resp.review_cycle_months == 12


# =============================================================================
# row_to_response — extended column mapping
# =============================================================================

class TestRowToResponseExtended:
    def _make_row(self, **overrides):
        """Build a 46-element tuple matching _BASE_COLUMNS_LIST order."""
        base = [
            "uuid-1",      # 0: id
            "tenant-1",    # 1: tenant_id
            "Acme GmbH",  # 2: company_name
            "GmbH",        # 3: legal_form
            "IT",           # 4: industry
            2020,           # 5: founded_year
            "B2B",          # 6: business_model
            ["SaaS"],       # 7: offerings
            "medium",       # 8: company_size
            "50-249",       # 9: employee_count
            "2-10 Mio",    # 10: annual_revenue
            "DE",           # 11: headquarters_country
            "München",     # 12: headquarters_city
            False,          # 13: has_international_locations
            [],             # 14: international_countries
            ["DE", "AT"],   # 15: target_markets
            "DE",           # 16: primary_jurisdiction
            True,           # 17: is_data_controller
            False,          # 18: is_data_processor
            True,           # 19: uses_ai
            ["chatbot"],    # 20: ai_use_cases
            "DSB Person",   # 21: dpo_name
            "dsb@acme.de",  # 22: dpo_email
            None,           # 23: legal_contact_name
            None,           # 24: legal_contact_email
            None,           # 25: machine_builder
            True,           # 26: is_complete
            "2026-01-15",   # 27: completed_at
            "2025-12-01",   # 28: created_at
            "2026-01-15",   # 29: updated_at
            # Phase 2 fields
            [{"name": "repo1"}],              # 30: repos
            [{"type": "policy", "title": "Privacy Policy"}],  # 31: document_sources
            [{"name": "SAP", "vendor": "SAP"}],  # 32: processing_systems
            [{"name": "Bot", "risk_category": "limited"}],    # 33: ai_systems
            [{"role": "CISO", "name": "Max"}],  # 34: technical_contacts
            True,           # 35: subject_to_nis2
            True,           # 36: subject_to_ai_act
            False,          # 37: subject_to_iso27001
            "LfDI BW",     # 38: supervisory_authority
            6,              # 39: review_cycle_months
            # Additional fields
            None,           # 40: project_id
            {},             # 41: offering_urls
            "",             # 42: headquarters_country_other
            "",             # 43: headquarters_street
            "",             # 44: headquarters_zip
            "",             # 45: headquarters_state
        ]
        return tuple(base)

    def test_maps_new_fields(self):
        row = self._make_row()
        resp = row_to_response(row)
        assert resp.repos == [{"name": "repo1"}]
        assert resp.document_sources[0]["type"] == "policy"
        assert resp.processing_systems[0]["name"] == "SAP"
        assert resp.ai_systems[0]["risk_category"] == "limited"
        assert resp.technical_contacts[0]["role"] == "CISO"
        assert resp.subject_to_nis2 is True
        assert resp.subject_to_ai_act is True
        assert resp.subject_to_iso27001 is False
        assert resp.supervisory_authority == "LfDI BW"
        assert resp.review_cycle_months == 6

    def test_null_new_fields_default_gracefully(self):
        base = list(self._make_row())
        # Set new fields to None
        for i in range(30, 40):
            base[i] = None
        row = tuple(base)
        resp = row_to_response(row)
        assert resp.repos == []
        assert resp.processing_systems == []
        assert resp.ai_systems == []
        assert resp.subject_to_nis2 is False
        assert resp.supervisory_authority is None
        assert resp.review_cycle_months == 12

    def test_old_fields_still_work(self):
        row = self._make_row()
        resp = row_to_response(row)
        assert resp.company_name == "Acme GmbH"
        assert resp.industry == "IT"
        assert resp.is_complete is True
        assert resp.dpo_name == "DSB Person"


# =============================================================================
# Template Context Tests
# =============================================================================

class TestTemplateContext:
    def test_template_context_from_response(self):
        """Simulate what template-context endpoint returns."""
        resp = CompanyProfileResponse(
            id="x", tenant_id="t", company_name="Test Corp", legal_form="AG",
            industry="Finance", founded_year=2015, business_model="B2C",
            offerings=["Banking"], company_size="large", employee_count="1000+",
            annual_revenue="> 50 Mio", headquarters_country="DE",
            headquarters_city="Frankfurt", has_international_locations=True,
            international_countries=["CH", "AT"], target_markets=["DE", "CH", "AT"],
            primary_jurisdiction="DE", is_data_controller=True,
            is_data_processor=True, uses_ai=True, ai_use_cases=["scoring"],
            dpo_name="Dr. Privacy", dpo_email="dpo@test.de",
            legal_contact_name="Legal Team", legal_contact_email="legal@test.de",
            machine_builder=None, is_complete=True,
            completed_at="2026-01-01", created_at="2025-06-01",
            updated_at="2026-01-01",
            ai_systems=[{"name": "Scoring Engine", "risk_category": "high"}],
            subject_to_ai_act=True, subject_to_nis2=True,
            review_cycle_months=3,
        )
        # Build context dict same as endpoint does
        ctx = {
            "company_name": resp.company_name,
            "dpo_name": resp.dpo_name or "",
            "uses_ai": resp.uses_ai,
            "ai_systems": resp.ai_systems,
            "has_ai_systems": len(resp.ai_systems) > 0,
            "subject_to_ai_act": resp.subject_to_ai_act,
            "review_cycle_months": resp.review_cycle_months,
        }
        assert ctx["company_name"] == "Test Corp"
        assert ctx["has_ai_systems"] is True
        assert ctx["subject_to_ai_act"] is True
        assert ctx["review_cycle_months"] == 3
