"""
Worktable Tests - API Tests.
"""
import pytest
from django.urls import reverse
from rest_framework import status

from apps.services.worktable.models import (
    TableDefinition,
    TableColumn,
    TableRecord,
    SavedFilter,
    CustomView,
    FieldType,
    RecordStatus,
)


@pytest.mark.django_db
class TestTableDefinitionAPI:
    """Tests for TableDefinition API endpoints."""

    def test_list_tables_unauthenticated(self, api_client, tenant):
        """Test that unauthenticated requests are rejected."""
        # Ensure we have a table
        TableDefinition.objects.create(
            tenant=tenant,
            slug='test-table',
            name='Test Table',
        )
        response = api_client.get('/api/v1/worktable/tables/')
        assert response.status_code == status.HTTP_401_UNAUTHORIZED

    def test_list_tables(self, authenticated_client, table_definition):
        """Test listing tables."""
        response = authenticated_client.get('/api/v1/worktable/tables/')
        assert response.status_code == status.HTTP_200_OK
        assert len(response.data['results']) >= 1

    def test_get_table_by_slug(self, authenticated_client, table_definition):
        """Test getting table by slug."""
        response = authenticated_client.get(
            f'/api/v1/worktable/tables/{table_definition.slug}/'
        )
        assert response.status_code == status.HTTP_200_OK
        assert response.data['name'] == 'محصولات'

    def test_create_table(self, authenticated_client, tenant):
        """Test creating a table."""
        response = authenticated_client.post('/api/v1/worktable/tables/', {
            'slug': 'new-table',
            'name': 'جدول جدید',
        }, format='json')
        assert response.status_code == status.HTTP_201_CREATED
        assert response.data['slug'] == 'new-table'

    def test_filter_active_tables(self, authenticated_client, table_definition, tenant):
        """Test filtering active tables."""
        # Create an inactive table
        TableDefinition.objects.create(
            tenant=tenant,
            slug='inactive-table',
            name='غیرفعال',
            is_active=False,
        )
        
        response = authenticated_client.get('/api/v1/worktable/tables/?active=true')
        assert response.status_code == status.HTTP_200_OK
        # Only active tables should be returned
        for table in response.data['results']:
            assert table['is_active'] is True

    def test_deactivate_table(self, authenticated_client, table_definition):
        """Test deactivating a table."""
        response = authenticated_client.post(
            f'/api/v1/worktable/tables/{table_definition.slug}/deactivate/'
        )
        assert response.status_code == status.HTTP_200_OK
        
        table_definition.refresh_from_db()
        assert table_definition.is_active is False

    def test_activate_table(self, authenticated_client, table_definition):
        """Test activating a table."""
        table_definition.is_active = False
        table_definition.save()
        
        response = authenticated_client.post(
            f'/api/v1/worktable/tables/{table_definition.slug}/activate/'
        )
        assert response.status_code == status.HTTP_200_OK
        
        table_definition.refresh_from_db()
        assert table_definition.is_active is True


@pytest.mark.django_db
class TestTableRecordAPI:
    """Tests for TableRecord API endpoints."""

    def test_list_records_unauthenticated(self, api_client, table_definition):
        """Test that unauthenticated requests are rejected."""
        response = api_client.get(
            f'/api/v1/worktable/tables/{table_definition.slug}/records/'
        )
        assert response.status_code == status.HTTP_401_UNAUTHORIZED

    def test_list_records(self, authenticated_client, table_definition, table_record):
        """Test listing records."""
        response = authenticated_client.get(
            f'/api/v1/worktable/tables/{table_definition.slug}/records/'
        )
        assert response.status_code == status.HTTP_200_OK
        assert len(response.data['results']) >= 1

    def test_get_record_detail(self, authenticated_client, table_definition, table_record):
        """Test getting record details."""
        response = authenticated_client.get(
            f'/api/v1/worktable/tables/{table_definition.slug}/records/{table_record.id}/'
        )
        assert response.status_code == status.HTTP_200_OK
        assert response.data['data']['name'] == 'محصول تست'

    def test_create_record(self, authenticated_client, table_definition, table_columns):
        """Test creating a record."""
        response = authenticated_client.post(
            f'/api/v1/worktable/tables/{table_definition.slug}/records/',
            {
                'data': {
                    'name': 'محصول جدید',
                    'price': 200000,
                    'quantity': 5,
                    'is_active': True,
                    'category': 'electronics',
                }
            },
            format='json',
        )
        assert response.status_code == status.HTTP_201_CREATED
        assert response.data['data']['name'] == 'محصول جدید'
        assert response.data['status'] == RecordStatus.DRAFT

    def test_update_record(self, authenticated_client, table_definition, table_columns, table_record):
        """Test updating a record."""
        response = authenticated_client.patch(
            f'/api/v1/worktable/tables/{table_definition.slug}/records/{table_record.id}/',
            {
                'data': {
                    'name': 'محصول آپدیت شده',
                }
            },
            format='json',
        )
        assert response.status_code == status.HTTP_200_OK
        
        # Check response has updated data
        assert response.data['data']['name'] == 'محصول آپدیت شده'

    def test_delete_record(self, authenticated_client, table_definition, table_record):
        """Test soft deleting a record."""
        response = authenticated_client.delete(
            f'/api/v1/worktable/tables/{table_definition.slug}/records/{table_record.id}/'
        )
        assert response.status_code == status.HTTP_204_NO_CONTENT
        
        # Verify soft delete
        table_record.refresh_from_db()
        assert table_record.is_deleted is True

    def test_filter_records(self, authenticated_client, table_definition, table_columns, user, tenant):
        """Test filtering records."""
        # Create multiple records
        TableRecord.objects.create(
            tenant=tenant,
            table=table_definition,
            data={'name': 'محصول ۱', 'price': 100000, 'is_active': True, 'category': 'electronics'},
            owner=user,
        )
        TableRecord.objects.create(
            tenant=tenant,
            table=table_definition,
            data={'name': 'محصول ۲', 'price': 200000, 'is_active': False, 'category': 'clothing'},
            owner=user,
        )
        
        response = authenticated_client.get(
            f'/api/v1/worktable/tables/{table_definition.slug}/records/'
        )
        assert response.status_code == status.HTTP_200_OK
        assert len(response.data['results']) >= 2

    def test_search_records(self, authenticated_client, table_definition, table_record):
        """Test searching records."""
        response = authenticated_client.get(
            f'/api/v1/worktable/tables/{table_definition.slug}/records/',
            {'search': 'محصول'}
        )
        assert response.status_code == status.HTTP_200_OK


@pytest.mark.django_db
class TestBulkOperationsAPI:
    """Tests for bulk operations API."""

    def test_bulk_delete(self, authenticated_client, table_definition, table_columns, user, tenant):
        """Test bulk delete operation."""
        # Create multiple records
        record_ids = []
        for i in range(3):
            record = TableRecord.objects.create(
                tenant=tenant,
                table=table_definition,
                data={'name': f'محصول {i}', 'price': i * 10000},
                owner=user,
            )
            record_ids.append(str(record.id))
        
        response = authenticated_client.post(
            f'/api/v1/worktable/tables/{table_definition.slug}/records/bulk_delete/',
            {
                'ids': record_ids,
            },
            format='json',
        )
        assert response.status_code == status.HTTP_200_OK
        assert response.data['deleted_count'] == 3


@pytest.mark.django_db
class TestSavedFilterAPI:
    """Tests for SavedFilter API endpoints."""

    def test_list_filters(self, authenticated_client, table_definition, user):
        """Test listing saved filters."""
        SavedFilter.objects.create(
            table=table_definition,
            user=user,
            name='فیلتر تست',
            filters={'conditions': []},
        )
        
        response = authenticated_client.get(
            f'/api/v1/worktable/tables/{table_definition.slug}/filters/'
        )
        assert response.status_code == status.HTTP_200_OK

    def test_create_filter(self, authenticated_client, table_definition):
        """Test creating a saved filter."""
        response = authenticated_client.post(
            f'/api/v1/worktable/tables/{table_definition.slug}/filters/',
            {
                'name': 'فیلتر جدید',
                'filters': {
                    'conditions': [
                        {'field': 'is_active', 'operator': 'eq', 'value': True}
                    ]
                }
            },
            format='json',
        )
        assert response.status_code == status.HTTP_201_CREATED


@pytest.mark.django_db
class TestCustomViewAPI:
    """Tests for CustomView API endpoints."""

    def test_list_views(self, authenticated_client, table_definition, user):
        """Test listing custom views."""
        CustomView.objects.create(
            table=table_definition,
            user=user,
            name='نمایش تست',
            columns=['name', 'price'],
        )
        
        response = authenticated_client.get(
            f'/api/v1/worktable/tables/{table_definition.slug}/views/'
        )
        assert response.status_code == status.HTTP_200_OK

    def test_create_view(self, authenticated_client, table_definition):
        """Test creating a custom view."""
        response = authenticated_client.post(
            f'/api/v1/worktable/tables/{table_definition.slug}/views/',
            {
                'name': 'نمایش جدید',
                'columns': [
                    {'slug': 'name', 'visible': True, 'width': 150},
                    {'slug': 'price', 'visible': True, 'width': 100},
                ],
            },
            format='json',
        )
        assert response.status_code == status.HTTP_201_CREATED
        assert response.status_code == status.HTTP_201_CREATED


@pytest.mark.django_db
class TestRecordAuditLogAPI:
    """Tests for Record Audit Log API endpoints."""

    def test_list_record_logs(self, authenticated_client, table_definition, table_record):
        """Test listing audit logs for a record."""
        response = authenticated_client.get(
            f'/api/v1/worktable/tables/{table_definition.slug}/records/{table_record.id}/logs/'
        )
        assert response.status_code == status.HTTP_200_OK


@pytest.mark.django_db  
class TestTableColumnAPI:
    """Tests for TableColumn API endpoints."""

    def test_list_columns(self, authenticated_client, table_definition, table_columns):
        """Test listing columns for a table."""
        response = authenticated_client.get(
            f'/api/v1/worktable/tables/{table_definition.slug}/columns/'
        )
        assert response.status_code == status.HTTP_200_OK
        assert len(response.data['results']) >= 1

    def test_create_column(self, authenticated_client, table_definition):
        """Test creating a column."""
        response = authenticated_client.post(
            f'/api/v1/worktable/tables/{table_definition.slug}/columns/',
            {
                'slug': 'new_column',
                'name': 'ستون جدید',
                'field_type': 'text',
                'order': 10,
            },
            format='json',
        )
        assert response.status_code == status.HTTP_201_CREATED
        assert response.data['slug'] == 'new_column'

    def test_update_column(self, authenticated_client, table_definition, table_columns):
        """Test updating a column."""
        column = table_columns[0]
        response = authenticated_client.patch(
            f'/api/v1/worktable/tables/{table_definition.slug}/columns/{column.id}/',
            {
                'name': 'نام آپدیت شده',
            },
            format='json',
        )
        assert response.status_code == status.HTTP_200_OK
        
        column.refresh_from_db()
        assert column.name == 'نام آپدیت شده'
