"""
Calendar Sync API Views

Provides endpoints for managing calendar integrations (Google Calendar, Outlook Calendar).
Handles OAuth credential creation, calendar selection, and event syncing.

Features:
- List connected calendars
- Sync calendar events
- Delete calendar integrations
- Permission checking via HasFeaturePermission
"""

import logging
from rest_framework import status, viewsets
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import action

from smoothschedule.identity.core.models import OAuthCredential, Tenant
from smoothschedule.identity.core.permissions import HasFeaturePermission

logger = logging.getLogger(__name__)


class CalendarSyncPermission(IsAuthenticated):
    """
    Custom permission that checks for calendar sync feature access.
    Combines authentication check with feature permission check.
    """
    def has_permission(self, request, view):
        # First check authentication
        if not super().has_permission(request, view):
            return False

        # Then check calendar sync feature permission
        tenant = getattr(request, 'tenant', None)
        if not tenant:
            return False

        return tenant.has_feature('can_use_calendar_sync')


class CalendarListView(APIView):
    """
    List OAuth credentials for calendar sync.

    GET /api/calendar/list/

    Returns list of connected calendars (Google Calendar, Outlook, etc.)
    """
    permission_classes = [CalendarSyncPermission]

    def get(self, request):
        """
        Get all calendar integrations for the current tenant.

        Returns:
            List of calendar credentials with details (tokens masked for security)
        """
        try:
            tenant = getattr(request, 'tenant', None)
            if not tenant:
                return Response({
                    'success': False,
                    'error': 'No tenant found in request',
                }, status=status.HTTP_400_BAD_REQUEST)

            # Get calendar purpose OAuth credentials for this tenant
            credentials = OAuthCredential.objects.filter(
                tenant=tenant,
                purpose='calendar',
            ).order_by('-created_at')

            calendar_list = []
            for cred in credentials:
                calendar_list.append({
                    'id': cred.id,
                    'provider': cred.get_provider_display(),
                    'email': cred.email,
                    'is_valid': cred.is_valid,
                    'is_expired': cred.is_expired(),
                    'last_used_at': cred.last_used_at,
                    'created_at': cred.created_at,
                })

            return Response({
                'success': True,
                'calendars': calendar_list,
            })

        except Exception as e:
            logger.error(f"Error listing calendars: {e}")
            return Response({
                'success': False,
                'error': f'Error listing calendars: {str(e)[:100]}',
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class CalendarSyncView(APIView):
    """
    Sync events from a connected calendar.

    POST /api/calendar/sync/
    Body: {
        "credential_id": <int>,
        "calendar_id": "<optional google calendar id>",
        "start_date": "2025-01-01",
        "end_date": "2025-12-31"
    }

    Syncs events from the specified calendar into the schedule.
    """
    permission_classes = [CalendarSyncPermission]

    def post(self, request):
        """
        Trigger calendar sync for a specific calendar credential.

        Permission Check: Requires can_use_calendar_sync feature permission
        """
        try:
            credential_id = request.data.get('credential_id')
            calendar_id = request.data.get('calendar_id')
            start_date = request.data.get('start_date')
            end_date = request.data.get('end_date')

            if not credential_id:
                return Response({
                    'success': False,
                    'error': 'credential_id is required',
                }, status=status.HTTP_400_BAD_REQUEST)

            tenant = getattr(request, 'tenant', None)
            if not tenant:
                return Response({
                    'success': False,
                    'error': 'No tenant found in request',
                }, status=status.HTTP_400_BAD_REQUEST)

            # Verify credential belongs to this tenant
            try:
                credential = OAuthCredential.objects.get(
                    id=credential_id,
                    tenant=tenant,
                    purpose='calendar',
                )
            except OAuthCredential.DoesNotExist:
                return Response({
                    'success': False,
                    'error': 'Calendar credential not found',
                }, status=status.HTTP_404_NOT_FOUND)

            # Check if credential is still valid
            if not credential.is_valid:
                return Response({
                    'success': False,
                    'error': 'Calendar credential is no longer valid. Please reconnect.',
                }, status=status.HTTP_400_BAD_REQUEST)

            # TODO: Implement actual calendar sync logic
            # This would use the credential's access_token to fetch events
            # from Google Calendar API or Microsoft Graph API
            # and create Event records in the schedule

            logger.info(
                f"Calendar sync initiated for tenant {tenant.name}, "
                f"credential {credential.email} ({credential.get_provider_display()})"
            )

            return Response({
                'success': True,
                'message': f'Calendar sync started for {credential.email}',
                'credential_id': credential_id,
            })

        except Exception as e:
            logger.error(f"Error syncing calendar: {e}")
            return Response({
                'success': False,
                'error': f'Error syncing calendar: {str(e)[:100]}',
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class CalendarDeleteView(APIView):
    """
    Delete/disconnect a calendar integration.

    DELETE /api/calendar/disconnect/
    Body: { "credential_id": <int> }

    Revokes the OAuth credential and removes the calendar integration.
    """
    permission_classes = [CalendarSyncPermission]

    def delete(self, request):
        """
        Delete a calendar credential for the current tenant.

        Permission Check: Requires can_use_calendar_sync feature permission
        """
        try:
            credential_id = request.data.get('credential_id')

            if not credential_id:
                return Response({
                    'success': False,
                    'error': 'credential_id is required',
                }, status=status.HTTP_400_BAD_REQUEST)

            tenant = getattr(request, 'tenant', None)
            if not tenant:
                return Response({
                    'success': False,
                    'error': 'No tenant found in request',
                }, status=status.HTTP_400_BAD_REQUEST)

            # Verify credential belongs to this tenant
            try:
                credential = OAuthCredential.objects.get(
                    id=credential_id,
                    tenant=tenant,
                    purpose='calendar',
                )
            except OAuthCredential.DoesNotExist:
                return Response({
                    'success': False,
                    'error': 'Calendar credential not found',
                }, status=status.HTTP_404_NOT_FOUND)

            email = credential.email
            provider = credential.get_provider_display()

            # Delete the credential
            credential.delete()

            logger.info(
                f"Calendar credential deleted for tenant {tenant.name}: "
                f"{email} ({provider})"
            )

            return Response({
                'success': True,
                'message': f'Calendar integration for {email} has been disconnected',
            })

        except Exception as e:
            logger.error(f"Error deleting calendar credential: {e}")
            return Response({
                'success': False,
                'error': f'Error deleting calendar: {str(e)[:100]}',
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class CalendarStatusView(APIView):
    """
    Get calendar sync status and information.

    GET /api/calendar/status/

    Returns information about calendar sync capability and connected calendars.
    """
    permission_classes = [IsAuthenticated]

    def get(self, request):
        """
        Get calendar sync status for the tenant.

        Returns:
            - can_use_calendar_sync: Boolean indicating if feature is enabled
            - total_connected: Number of connected calendars
            - total_synced_events: Count of events synced (placeholder)
        """
        try:
            tenant = getattr(request, 'tenant', None)
            if not tenant:
                return Response({
                    'success': False,
                    'error': 'No tenant found in request',
                }, status=status.HTTP_400_BAD_REQUEST)

            has_permission = tenant.has_feature('can_use_calendar_sync')

            if not has_permission:
                return Response({
                    'success': True,
                    'can_use_calendar_sync': False,
                    'message': 'Calendar Sync feature is not available for your plan',
                    'total_connected': 0,
                })

            # Count connected calendars
            total_connected = OAuthCredential.objects.filter(
                tenant=tenant,
                purpose='calendar',
                is_valid=True,
            ).count()

            return Response({
                'success': True,
                'can_use_calendar_sync': True,
                'total_connected': total_connected,
                'feature_enabled': True,
            })

        except Exception as e:
            logger.error(f"Error getting calendar status: {e}")
            return Response({
                'success': False,
                'error': f'Error getting status: {str(e)[:100]}',
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
