"""
Tests for Data Export API

Run with:
    docker compose -f docker-compose.local.yml exec django python manage.py test schedule.test_export
"""
from django.test import TestCase, Client
from django.contrib.auth import get_user_model
from django.utils import timezone
from datetime import timedelta
from core.models import Tenant, Domain
from schedule.models import Event, Resource, Service
from smoothschedule.users.models import User as CustomUser

User = get_user_model()


class DataExportAPITestCase(TestCase):
    """Test suite for data export API endpoints"""

    def setUp(self):
        """Set up test fixtures"""
        # Create tenant with export permission
        self.tenant = Tenant.objects.create(
            name="Test Business",
            schema_name="test_business",
            can_export_data=True,  # Enable export permission
        )

        # Create domain for tenant
        self.domain = Domain.objects.create(
            tenant=self.tenant,
            domain="test.lvh.me",
            is_primary=True
        )

        # Create test user (owner)
        self.user = CustomUser.objects.create_user(
            username="testowner",
            email="owner@test.com",
            password="testpass123",
            role=CustomUser.Role.TENANT_OWNER,
            tenant=self.tenant
        )

        # Create test customer
        self.customer = CustomUser.objects.create_user(
            username="customer1",
            email="customer@test.com",
            first_name="John",
            last_name="Doe",
            role=CustomUser.Role.CUSTOMER,
            tenant=self.tenant
        )

        # Create test resource
        self.resource = Resource.objects.create(
            name="Test Resource",
            type=Resource.Type.STAFF,
            max_concurrent_events=1
        )

        # Create test service
        self.service = Service.objects.create(
            name="Test Service",
            description="Test service description",
            duration=60,
            price=50.00
        )

        # Create test event
        now = timezone.now()
        self.event = Event.objects.create(
            title="Test Appointment",
            start_time=now,
            end_time=now + timedelta(hours=1),
            status=Event.Status.SCHEDULED,
            notes="Test notes",
            created_by=self.user
        )

        # Set up authenticated client
        self.client = Client()
        self.client.force_login(self.user)

    def test_appointments_export_json(self):
        """Test exporting appointments in JSON format"""
        response = self.client.get('/export/appointments/?format=json')

        self.assertEqual(response.status_code, 200)
        self.assertIn('application/json', response['Content-Type'])

        # Check response structure
        data = response.json()
        self.assertIn('count', data)
        self.assertIn('data', data)
        self.assertIn('exported_at', data)
        self.assertIn('filters', data)

        # Verify data
        self.assertEqual(data['count'], 1)
        self.assertEqual(len(data['data']), 1)

        appointment = data['data'][0]
        self.assertEqual(appointment['title'], 'Test Appointment')
        self.assertEqual(appointment['status'], 'SCHEDULED')

    def test_appointments_export_csv(self):
        """Test exporting appointments in CSV format"""
        response = self.client.get('/export/appointments/?format=csv')

        self.assertEqual(response.status_code, 200)
        self.assertIn('text/csv', response['Content-Type'])
        self.assertIn('attachment', response['Content-Disposition'])

        # Check CSV content
        content = response.content.decode('utf-8')
        self.assertIn('id,title,start_time', content)
        self.assertIn('Test Appointment', content)

    def test_customers_export_json(self):
        """Test exporting customers in JSON format"""
        response = self.client.get('/export/customers/?format=json')

        self.assertEqual(response.status_code, 200)
        data = response.json()

        self.assertEqual(data['count'], 1)
        customer = data['data'][0]
        self.assertEqual(customer['email'], 'customer@test.com')
        self.assertEqual(customer['first_name'], 'John')
        self.assertEqual(customer['last_name'], 'Doe')

    def test_customers_export_csv(self):
        """Test exporting customers in CSV format"""
        response = self.client.get('/export/customers/?format=csv')

        self.assertEqual(response.status_code, 200)
        self.assertIn('text/csv', response['Content-Type'])

        content = response.content.decode('utf-8')
        self.assertIn('customer@test.com', content)
        self.assertIn('John', content)

    def test_resources_export_json(self):
        """Test exporting resources in JSON format"""
        response = self.client.get('/export/resources/?format=json')

        self.assertEqual(response.status_code, 200)
        data = response.json()

        self.assertEqual(data['count'], 1)
        resource = data['data'][0]
        self.assertEqual(resource['name'], 'Test Resource')
        self.assertEqual(resource['type'], 'STAFF')

    def test_services_export_json(self):
        """Test exporting services in JSON format"""
        response = self.client.get('/export/services/?format=json')

        self.assertEqual(response.status_code, 200)
        data = response.json()

        self.assertEqual(data['count'], 1)
        service = data['data'][0]
        self.assertEqual(service['name'], 'Test Service')
        self.assertEqual(service['duration'], 60)
        self.assertEqual(service['price'], '50.00')

    def test_date_range_filter(self):
        """Test filtering appointments by date range"""
        # Create appointment in the past
        past_time = timezone.now() - timedelta(days=30)
        Event.objects.create(
            title="Past Appointment",
            start_time=past_time,
            end_time=past_time + timedelta(hours=1),
            status=Event.Status.COMPLETED,
            created_by=self.user
        )

        # Filter for recent appointments only
        start_date = (timezone.now() - timedelta(days=7)).isoformat()
        response = self.client.get(f'/export/appointments/?format=json&start_date={start_date}')

        data = response.json()
        # Should only get the recent appointment, not the past one
        self.assertEqual(data['count'], 1)
        self.assertEqual(data['data'][0]['title'], 'Test Appointment')

    def test_no_permission_denied(self):
        """Test that export fails when tenant doesn't have permission"""
        # Disable export permission
        self.tenant.can_export_data = False
        self.tenant.save()

        response = self.client.get('/export/appointments/?format=json')

        self.assertEqual(response.status_code, 403)
        self.assertIn('not available', response.json()['detail'])

    def test_unauthenticated_denied(self):
        """Test that unauthenticated requests are denied"""
        client = Client()  # Not authenticated
        response = client.get('/export/appointments/?format=json')

        self.assertEqual(response.status_code, 401)
        self.assertIn('Authentication', response.json()['detail'])

    def test_active_filter(self):
        """Test filtering by active status"""
        # Create inactive service
        Service.objects.create(
            name="Inactive Service",
            duration=30,
            price=25.00,
            is_active=False
        )

        # Export only active services
        response = self.client.get('/export/services/?format=json&is_active=true')
        data = response.json()

        # Should only get the active service
        self.assertEqual(data['count'], 1)
        self.assertEqual(data['data'][0]['name'], 'Test Service')
