"""
Audit Log Service — Tests.
تست‌های واحد و API برای سرویس Audit Log.
"""
import pytest

pytestmark = [pytest.mark.django_db]


# ─── Model Tests ─────────────────────────────────────────────────────────


class TestAuditLogModel:
    def test_create_audit_log(self, create_user):
        from apps.services.audit_log.models import AuditLog, AuditAction
        user = create_user(email='audit@test.com')
        log = AuditLog.objects.create(
            user=user,
            user_email=user.email,
            action=AuditAction.CREATE,
            resource_type='User',
            resource_id=str(user.pk),
            module='auth',
        )
        assert str(log.action) == AuditAction.CREATE
        assert log.resource_type == 'User'

    def test_audit_log_without_user(self):
        from apps.services.audit_log.models import AuditLog, AuditAction
        log = AuditLog.objects.create(
            action=AuditAction.VIEW,
            resource_type='Document',
            resource_id='123',
            module='docs',
        )
        assert log.user is None
        assert log.module == 'docs'


# ─── Service Tests ───────────────────────────────────────────────────────


class TestAuditLogService:
    def test_log_creates_entry(self, create_user):
        from apps.services.audit_log.services import AuditLogService
        from apps.services.audit_log.models import AuditLog, AuditAction
        user = create_user(email='svc@test.com')
        entry = AuditLogService.log(
            action=AuditAction.CREATE,
            resource_type='Project',
            resource_id='abc-123',
            user=user,
            module='pm',
        )
        assert entry is not None
        assert entry.resource_type == 'Project'
        assert entry.user_email == 'svc@test.com'

    def test_compute_changes(self):
        from apps.services.audit_log.services import AuditLogService
        old = {'name': 'old', 'value': 1}
        new = {'name': 'new', 'value': 1}
        changes = AuditLogService.compute_changes(old, new)
        assert 'name' in changes
        assert changes['name']['old'] == 'old'
        assert changes['name']['new'] == 'new'
        assert 'value' not in changes

    def test_get_resource_history(self, create_user):
        from apps.services.audit_log.services import AuditLogService
        from apps.services.audit_log.models import AuditAction
        user = create_user(email='hist@test.com')
        for i in range(3):
            AuditLogService.log(
                action=AuditAction.UPDATE,
                resource_type='Task',
                resource_id='task-1',
                user=user,
                module='pm',
                changes={'field': {'old': i, 'new': i + 1}},
            )
        logs = AuditLogService.get_resource_history('Task', 'task-1')
        assert len(logs) == 3


# ─── API Tests ───────────────────────────────────────────────────────────


class TestAuditLogAPI:
    def test_list_requires_auth(self, api_client):
        response = api_client.get('/api/v1/audit/logs/')
        assert response.status_code in [401, 403]

    def test_list_returns_logs(self, authenticated_client):
        client, user = authenticated_client
        from apps.services.audit_log.services import AuditLogService
        from apps.services.audit_log.models import AuditAction
        AuditLogService.log(
            action=AuditAction.CREATE,
            resource_type='Test',
            resource_id='1',
            user=user,
            module='test',
        )
        response = client.get('/api/v1/audit/logs/')
        assert response.status_code == 200

    def test_resource_history(self, authenticated_client):
        client, user = authenticated_client
        from apps.services.audit_log.services import AuditLogService
        from apps.services.audit_log.models import AuditAction
        AuditLogService.log(
            action=AuditAction.CREATE,
            resource_type='Item',
            resource_id='item-1',
            user=user,
            module='test',
        )
        response = client.get('/api/v1/audit/logs/resource/Item/item-1/')
        assert response.status_code == 200
