from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from django.utils import timezone
from .models import UserFCMToken, UserPattern, MLModel, AnomalyAlert, ScheduledNotification, BurnoutAnalysis, BurnoutNotification, ComplianceNotification
from .serializers import (
    UserFCMTokenSerializer, UserPatternSerializer, MLModelSerializer, 
    AnomalyAlertSerializer, ScheduledNotificationSerializer
)
from .push_service import PushNotificationService
from .tasks import schedule_user_notifications_for_today
import logging

logger = logging.getLogger(__name__)

class MLViewSet(viewsets.ModelViewSet):
    """API endpoints for ML functionality"""
    
    @action(detail=False, methods=['post'])
    def register_fcm_token(self, request):
        """Register user's FCM token for push notifications"""
        try:
            fcm_token = request.data.get('fcm_token')
            user_id = request.data.get('user_id')
            
            if not fcm_token:
                return Response(
                    {'error': 'FCM token is required'}, 
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            if not user_id:
                return Response(
                    {'error': 'user_id is required'}, 
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            # Update or create FCM token
            token_obj, created = UserFCMToken.objects.update_or_create(
                user_id=user_id,
                fcm_token=fcm_token,
                defaults={
                    'device_type': 'mobile',
                    'is_active': True
                }
            )
            
            # Schedule notifications for this user
            try:
                schedule_user_notifications_for_today(user_id)
            except Exception as e:
                logger.warning(f"Could not schedule notifications for user {user_id}: {e}")
            
            return Response({
                'status': 'success',
                'message': 'FCM token registered successfully',
                'created': created,
                'token_id': str(token_obj.id)
            })
            
        except Exception as e:
            logger.error(f"Error registering FCM token: {e}")
            return Response(
                {'error': str(e)}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['get'])
    def get_user_patterns(self, request):
        """Get user's learned patterns"""
        try:
            patterns = UserPattern.objects.filter(user_id=request.user.id)
            serializer = UserPatternSerializer(patterns, many=True)
            
            return Response({
                'patterns': serializer.data,
                'last_updated': patterns.first().last_updated if patterns.exists() else None,
                'total_patterns': patterns.count()
            })
            
        except Exception as e:
            logger.error(f"Error getting user patterns: {e}")
            return Response(
                {'error': str(e)}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['get'])
    def get_scheduled_notifications(self, request):
        """Get user's scheduled notifications"""
        try:
            notifications = ScheduledNotification.objects.filter(
                user_id=request.user.id,
                scheduled_time__gte=timezone.now()
            ).order_by('scheduled_time')
            
            serializer = ScheduledNotificationSerializer(notifications, many=True)
            
            return Response({
                'scheduled_notifications': serializer.data,
                'total_scheduled': notifications.count()
            })
            
        except Exception as e:
            logger.error(f"Error getting scheduled notifications: {e}")
            return Response(
                {'error': str(e)}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['post'])
    def test_notification(self, request):
        """Test push notification for user"""
        try:
            # Get user_id from request body
            user_id = request.data.get('user_id')
            
            if not user_id:
                return Response(
                    {'error': 'user_id is required'}, 
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            # Convert to string if it's not already
            user_id = str(user_id)
            
            push_service = PushNotificationService()
            
            # Check if user has FCM token
            fcm_token_obj = UserFCMToken.objects.filter(
                user_id=user_id,
                is_active=True
            ).first()
            
            if not fcm_token_obj:
                return Response({
                    'status': 'no_token',
                    'message': 'User has no FCM token registered',
                    'user_id': user_id,
                    'hint': 'Open the app to register FCM token'
                }, status=status.HTTP_404_NOT_FOUND)
            
            # Create a test burnout notification in database
            test_notification = BurnoutNotification.objects.create(
                user_id=user_id,
                notification_type='burnout_alert',
                title='🧪 Test Burnout Alert',
                message='This is a test burnout notification from Flexwise. Your work patterns show signs of burnout.',
                risk_score=85.5,
                recommendation={'action': 'Consider using flex time or vacation', 'balance': 'flex_time'}
            )
            
            # Send test push notification
            success = push_service.send_notification(
                user_id=user_id,
                title='🧪 Test Burnout Alert',
                body='This is a test burnout notification from Flexwise. Your work patterns show signs of burnout.',
                data={
                    'test': 'true',
                    'notification_id': str(test_notification.id),
                    'notification_type': 'burnout',
                    'risk_score': '85.5'
                }
            )
            
            if success:
                return Response({
                    'status': 'success',
                    'message': 'Test notification sent successfully',
                    'user_id': user_id,
                    'notification_id': str(test_notification.id),
                    'delivered_to': fcm_token_obj.fcm_token[:20] + '...'
                })
            else:
                return Response({
                    'status': 'failed',
                    'message': 'Failed to send test notification - check server logs',
                    'user_id': user_id
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
                
        except Exception as e:
            logger.error(f"Error sending test notification: {e}")
            return Response(
                {'error': str(e)}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['get'])
    def get_notification_status(self, request):
        """Get user's notification status"""
        try:
            # Check if user has FCM token
            fcm_token = UserFCMToken.objects.filter(
                user_id=request.user.id,
                is_active=True
            ).first()
            
            # Check if user has patterns
            patterns = UserPattern.objects.filter(user_id=request.user.id)
            
            # Check scheduled notifications
            scheduled_count = ScheduledNotification.objects.filter(
                user_id=request.user.id,
                scheduled_time__gte=timezone.now(),
                is_sent=False
            ).count()
            
            return Response({
                'fcm_token_registered': fcm_token is not None,
                'patterns_learned': patterns.count(),
                'notifications_scheduled': scheduled_count,
                'push_service_available': PushNotificationService().firebase_initialized
            })
            
        except Exception as e:
            logger.error(f"Error getting notification status: {e}")
            return Response(
                {'error': str(e)}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['get'])
    def get_burnout_notifications(self, request):
        """Get user's burnout notifications"""
        try:
            user_id = request.GET.get('user_id', request.user.id if hasattr(request, 'user') else None)
            
            if not user_id:
                return Response(
                    {'error': 'user_id is required'}, 
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            notifications = BurnoutNotification.objects.filter(
                user_id=user_id
            ).order_by('-sent_at')
            
            # Format response
            notification_data = []
            for notif in notifications:
                notification_data.append({
                    'id': str(notif.id),
                    'type': notif.notification_type,
                    'title': notif.title,
                    'message': notif.message,
                    'risk_score': notif.risk_score,
                    'recommendation': notif.recommendation,
                    'is_read': notif.is_read,
                    'sent_at': notif.sent_at.isoformat(),
                    'read_at': notif.read_at.isoformat() if notif.read_at else None,
                })
            
            unread_count = notifications.filter(is_read=False).count()
            
            return Response({
                'notifications': notification_data,
                'unread_count': unread_count,
                'total_count': notifications.count()
            })
            
        except Exception as e:
            logger.error(f"Error getting burnout notifications: {e}")
            return Response(
                {'error': str(e)}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['post'])
    def mark_burnout_notification_read(self, request):
        """Mark burnout notification as read"""
        try:
            notification_id = request.data.get('notification_id')
            user_id = request.data.get('user_id', request.user.id if hasattr(request, 'user') else None)
            
            if not notification_id:
                return Response(
                    {'error': 'notification_id is required'}, 
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            notification = BurnoutNotification.objects.get(
                id=notification_id,
                user_id=user_id
            )
            
            notification.mark_as_read()
            
            return Response({
                'status': 'success',
                'message': 'Notification marked as read'
            })
            
        except BurnoutNotification.DoesNotExist:
            return Response(
                {'error': 'Notification not found'}, 
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            logger.error(f"Error marking notification as read: {e}")
            return Response(
                {'error': str(e)}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['get'])
    def get_burnout_analysis(self, request):
        """Get user's burnout analysis"""
        try:
            user_id = request.GET.get('user_id', request.user.id if hasattr(request, 'user') else None)
            
            if not user_id:
                return Response(
                    {'error': 'user_id is required'}, 
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            # Get latest analysis
            analysis = BurnoutAnalysis.objects.filter(
                user_id=user_id
            ).order_by('-date', '-created_at').first()
            
            if not analysis:
                return Response({
                    'status': 'no_analysis',
                    'message': 'No burnout analysis available yet'
                })
            
            return Response({
                'risk_score': analysis.risk_score,
                'severity': analysis.severity,
                'risk_factors': analysis.risk_factors,
                'recommendations': analysis.recommendations,
                'date': analysis.date.isoformat(),
                'created_at': analysis.created_at.isoformat()
            })
            
        except Exception as e:
            logger.error(f"Error getting burnout analysis: {e}")
            return Response(
                {'error': str(e)}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['post'])
    def delete_burnout_notification(self, request):
        """Delete a burnout notification"""
        try:
            notification_id = request.data.get('notification_id')
            user_id = request.data.get('user_id', request.user.id if hasattr(request, 'user') else None)
            
            if not notification_id:
                return Response(
                    {'error': 'notification_id is required'}, 
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            notification = BurnoutNotification.objects.get(
                id=notification_id,
                user_id=user_id
            )
            
            notification.delete()
            
            return Response({
                'status': 'success',
                'message': 'Notification deleted successfully'
            })
            
        except BurnoutNotification.DoesNotExist:
            return Response(
                {'error': 'Notification not found'}, 
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            logger.error(f"Error deleting notification: {e}")
            return Response(
                {'error': str(e)}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['get'])
    def get_compliance_notifications(self, request):
        """Get user's compliance notifications"""
        try:
            user_id = request.GET.get('user_id', request.user.id if hasattr(request, 'user') else None)
            
            if not user_id:
                return Response(
                    {'error': 'user_id is required'}, 
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            # Get all compliance notifications for user
            notifications = ComplianceNotification.objects.filter(user_id=user_id)
            
            # Get unread count
            unread_count = notifications.filter(is_read=False).count()
            
            notification_data = [{
                'id': str(n.id),
                'type': n.alert_type,
                'title': n.title,
                'message': n.message,
                'severity': n.severity,
                'time_remaining': n.time_remaining,
                'is_read': n.is_read,
                'sent_at': n.sent_at.isoformat(),
                'read_at': n.read_at.isoformat() if n.read_at else None,
            } for n in notifications]
            
            return Response({
                'notifications': notification_data,
                'unread_count': unread_count,
                'total_count': notifications.count()
            })
            
        except Exception as e:
            logger.error(f"Error getting compliance notifications: {e}")
            return Response(
                {'error': str(e)}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['post'])
    def mark_compliance_notification_read(self, request):
        """Mark compliance notification as read"""
        try:
            notification_id = request.data.get('notification_id')
            user_id = request.data.get('user_id')
            
            if not notification_id:
                return Response(
                    {'error': 'notification_id is required'}, 
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            notification = ComplianceNotification.objects.get(
                id=notification_id,
                user_id=user_id
            )
            
            notification.mark_as_read()
            
            return Response({
                'status': 'success',
                'message': 'Notification marked as read'
            })
            
        except ComplianceNotification.DoesNotExist:
            return Response(
                {'error': 'Notification not found'}, 
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            logger.error(f"Error marking notification as read: {e}")
            return Response(
                {'error': str(e)}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
    
    @action(detail=False, methods=['post'])
    def delete_compliance_notification(self, request):
        """Delete a compliance notification"""
        try:
            notification_id = request.data.get('notification_id')
            user_id = request.data.get('user_id')
            
            if not notification_id:
                return Response(
                    {'error': 'notification_id is required'}, 
                    status=status.HTTP_400_BAD_REQUEST
                )
            
            notification = ComplianceNotification.objects.get(
                id=notification_id,
                user_id=user_id
            )
            
            notification.delete()
            
            return Response({
                'status': 'success',
                'message': 'Notification deleted successfully'
            })
            
        except ComplianceNotification.DoesNotExist:
            return Response(
                {'error': 'Notification not found'}, 
                status=status.HTTP_404_NOT_FOUND
            )
        except Exception as e:
            logger.error(f"Error deleting notification: {e}")
            return Response(
                {'error': str(e)}, 
                status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )
