"""Tests for Compliance Project routes (project_routes.py)."""

import json
import pytest
from unittest.mock import MagicMock, patch, PropertyMock
from datetime import datetime, timezone

from compliance.api.project_routes import (
    CreateProjectRequest,
    UpdateProjectRequest,
    _row_to_response,
)


class TestCreateProjectRequest:
    """Tests for request model validation."""

    def test_default_values(self):
        req = CreateProjectRequest(name="Test Project")
        assert req.name == "Test Project"
        assert req.description == ""
        assert req.customer_type == "new"
        assert req.copy_from_project_id is None

    def test_full_values(self):
        req = CreateProjectRequest(
            name="KI-Produkt X",
            description="DSGVO-Compliance fuer Produkt X",
            customer_type="existing",
            copy_from_project_id="uuid-123",
        )
        assert req.name == "KI-Produkt X"
        assert req.description == "DSGVO-Compliance fuer Produkt X"
        assert req.customer_type == "existing"
        assert req.copy_from_project_id == "uuid-123"

    def test_name_required(self):
        with pytest.raises(Exception):
            CreateProjectRequest()

    def test_serialization(self):
        req = CreateProjectRequest(name="Test")
        data = req.model_dump()
        assert data["name"] == "Test"
        assert data["customer_type"] == "new"


class TestUpdateProjectRequest:
    """Tests for update model."""

    def test_empty_update(self):
        req = UpdateProjectRequest()
        assert req.name is None
        assert req.description is None

    def test_partial_update(self):
        req = UpdateProjectRequest(name="New Name")
        assert req.name == "New Name"
        assert req.description is None


class TestRowToResponse:
    """Tests for DB row to response conversion."""

    def _make_row(self, **overrides):
        now = datetime.now(timezone.utc)
        defaults = {
            "id": "uuid-project-1",
            "tenant_id": "uuid-tenant-1",
            "name": "Test Project",
            "description": "A test project",
            "customer_type": "new",
            "status": "active",
            "project_version": 1,
            "completion_percentage": 0,
            "created_at": now,
            "updated_at": now,
        }
        defaults.update(overrides)
        mock = MagicMock()
        for key, value in defaults.items():
            setattr(mock, key, value)
        return mock

    def test_basic_conversion(self):
        row = self._make_row()
        result = _row_to_response(row)
        assert result["id"] == "uuid-project-1"
        assert result["tenant_id"] == "uuid-tenant-1"
        assert result["name"] == "Test Project"
        assert result["description"] == "A test project"
        assert result["customer_type"] == "new"
        assert result["status"] == "active"
        assert result["project_version"] == 1
        assert result["completion_percentage"] == 0

    def test_null_description(self):
        row = self._make_row(description=None)
        result = _row_to_response(row)
        assert result["description"] == ""

    def test_null_customer_type(self):
        row = self._make_row(customer_type=None)
        result = _row_to_response(row)
        assert result["customer_type"] == "new"

    def test_null_status(self):
        row = self._make_row(status=None)
        result = _row_to_response(row)
        assert result["status"] == "active"

    def test_created_at_iso(self):
        dt = datetime(2026, 3, 9, 12, 0, 0, tzinfo=timezone.utc)
        row = self._make_row(created_at=dt)
        result = _row_to_response(row)
        assert "2026-03-09" in result["created_at"]

    def test_archived_project(self):
        row = self._make_row(status="archived", completion_percentage=75)
        result = _row_to_response(row)
        assert result["status"] == "archived"
        assert result["completion_percentage"] == 75


class TestCreateProjectCopiesProfile:
    """Tests that creating a project with copy_from_project_id works."""

    def test_copy_request_model(self):
        req = CreateProjectRequest(
            name="Tochter GmbH",
            customer_type="existing",
            copy_from_project_id="source-uuid-123",
        )
        assert req.copy_from_project_id == "source-uuid-123"

    def test_no_copy_request_model(self):
        req = CreateProjectRequest(name="Brand New")
        assert req.copy_from_project_id is None


class TestTenantIsolation:
    """Tests verifying tenant isolation is enforced in query patterns."""

    def test_list_query_includes_tenant_filter(self):
        """Verify that our SQL queries always filter by tenant_id."""
        import inspect
        from compliance.api.project_routes import list_projects
        source = inspect.getsource(list_projects)
        assert "tenant_id" in source
        assert "WHERE" in source

    def test_get_query_includes_tenant_filter(self):
        import inspect
        from compliance.api.project_routes import get_project
        source = inspect.getsource(get_project)
        assert "tenant_id" in source
        assert "project_id" in source

    def test_archive_query_includes_tenant_filter(self):
        import inspect
        from compliance.api.project_routes import archive_project
        source = inspect.getsource(archive_project)
        assert "tenant_id" in source

    def test_update_query_includes_tenant_filter(self):
        import inspect
        from compliance.api.project_routes import update_project
        source = inspect.getsource(update_project)
        assert "tenant_id" in source


class TestStateIsolation:
    """Tests verifying state isolation between projects."""

    def test_create_project_creates_sdk_state(self):
        """Verify create_project function inserts into sdk_states."""
        import inspect
        from compliance.api.project_routes import create_project
        source = inspect.getsource(create_project)
        assert "sdk_states" in source
        assert "project_id" in source

    def test_create_project_copies_company_profile(self):
        """Verify create_project copies companyProfile when copy_from specified."""
        import inspect
        from compliance.api.project_routes import create_project
        source = inspect.getsource(create_project)
        assert "copy_from_project_id" in source
        assert "companyProfile" in source
