#!/usr/bin/env python3
"""
ML Notification System - Practical Demonstration
This script shows how the system works step by step
"""

import os
import sys
import django
from datetime import datetime, time, timedelta

# Setup Django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'worktimeapp.settings')
django.setup()

from ml_service.models import UserPattern, ScheduledNotification, UserFCMToken
from ml_service.services import MLService
from ml_service.tasks import schedule_daily_notifications, send_notification_at_exact_time
from stamps.models import Stamp
from functions.models import Function
import uuid

def create_demo_data():
    """Create demo data to show how the system works"""
    print("Creating demo data...")
    
    # Create demo user
    demo_user_id = str(uuid.uuid4())
    print(f"Demo User ID: {demo_user_id}")
    
    # Create demo functions with question_type
    functions = {
        'clock_in': Function.objects.create(
            name='Clock In',
            question_type='clock_in',
            out=False,
            paycode_id=1  # Assuming paycode exists
        ),
        'lunch_out': Function.objects.create(
            name='Lunch Out',
            question_type='lunch_out',
            out=True,
            paycode_id=1
        ),
        'lunch_in': Function.objects.create(
            name='Lunch In',
            question_type='lunch_in',
            out=False,
            paycode_id=1
        ),
        'clock_out': Function.objects.create(
            name='Clock Out',
            question_type='clock_out',
            out=True,
            paycode_id=1
        )
    }
    
    # Create demo stamps (simulating 5 days of work)
    demo_stamps = []
    base_date = datetime.now().date() - timedelta(days=5)
    
    for day in range(5):
        current_date = base_date + timedelta(days=day)
        
        # Clock In (around 09:00 AM with some variation)
        clock_in_time = time(9, 0 + day, 0)  # 09:00, 09:01, 09:02, 09:03, 09:04
        demo_stamps.append(Stamp.objects.create(
            user_id=demo_user_id,
            function=functions['clock_in'],
            time=clock_in_time,
            date=current_date,
            description=f"Clock In - Day {day + 1}"
        ))
        
        # Lunch Out (around 12:00 PM with some variation)
        lunch_out_time = time(12, 0 + day, 0)  # 12:00, 12:01, 12:02, 12:03, 12:04
        demo_stamps.append(Stamp.objects.create(
            user_id=demo_user_id,
            function=functions['lunch_out'],
            time=lunch_out_time,
            date=current_date,
            description=f"Lunch Out - Day {day + 1}"
        ))
        
        # Lunch In (around 01:00 PM with some variation)
        lunch_in_time = time(13, 0 + day, 0)  # 13:00, 13:01, 13:02, 13:03, 13:04
        demo_stamps.append(Stamp.objects.create(
            user_id=demo_user_id,
            function=functions['lunch_in'],
            time=lunch_in_time,
            date=current_date,
            description=f"Lunch In - Day {day + 1}"
        ))
        
        # Clock Out (around 05:00 PM with some variation)
        clock_out_time = time(17, 0 + day, 0)  # 17:00, 17:01, 17:02, 17:03, 17:04
        demo_stamps.append(Stamp.objects.create(
            user_id=demo_user_id,
            function=functions['clock_out'],
            time=clock_out_time,
            date=current_date,
            description=f"Clock Out - Day {day + 1}"
        ))
    
    print(f"Created {len(demo_stamps)} demo stamps")
    return demo_user_id, demo_stamps

def demonstrate_pattern_learning(user_id):
    """Demonstrate how the system learns patterns"""
    print("\n🧠 Demonstrating Pattern Learning...")
    
    ml_service = MLService()
    
    # Analyze user patterns
    print("Analyzing user patterns...")
    results = ml_service.analyze_user_patterns(user_id)
    
    if 'error' in results:
        print(f"❌ Error: {results['error']}")
        return
    
    print(f"✅ Analysis complete!")
    print(f"Total stamps analyzed: {results['total_stamps']}")
    print(f"Patterns learned: {len(results['patterns'])}")
    
    # Show learned patterns
    print("\n📊 Learned Patterns:")
    for question_type, pattern_data in results['patterns'].items():
        print(f"  {question_type}:")
        print(f"    Average Time: {pattern_data['average_time']}")
        print(f"    Confidence: {pattern_data['confidence_score']:.2f}")
        print(f"    Sample Size: {pattern_data['sample_size']}")
        print(f"    Pattern Strength: {pattern_data['pattern_strength']}")
        print()
    
    return results

def demonstrate_notification_scheduling(user_id):
    """Demonstrate how notifications are scheduled"""
    print("\n⏰ Demonstrating Notification Scheduling...")
    
    # Get user patterns
    patterns = UserPattern.objects.filter(user_id=user_id)
    
    if not patterns.exists():
        print("❌ No patterns found. Run pattern learning first.")
        return
    
    print(f"Found {patterns.count()} patterns for user {user_id}")
    
    # Schedule notifications
    print("Scheduling notifications...")
    result = schedule_daily_notifications()
    
    if result.get('status') == 'success':
        print(f"✅ Scheduled {result['notifications_scheduled']} notifications")
        print(f"Processed {result['users_processed']} users")
    else:
        print(f"❌ Error: {result.get('error')}")
        return
    
    # Show scheduled notifications
    scheduled = ScheduledNotification.objects.filter(
        user_id=user_id,
        is_sent=False
    ).order_by('scheduled_time')
    
    print(f"\n📅 Scheduled Notifications:")
    for notification in scheduled:
        print(f"  {notification.question_type}: {notification.scheduled_time}")
        print(f"    Task ID: {notification.celery_task_id}")
        print()

def demonstrate_notification_delivery(user_id):
    """Demonstrate how notifications are delivered"""
    print("\n📱 Demonstrating Notification Delivery...")
    
    # Get scheduled notifications
    scheduled = ScheduledNotification.objects.filter(
        user_id=user_id,
        is_sent=False
    ).order_by('scheduled_time')
    
    if not scheduled.exists():
        print("❌ No scheduled notifications found.")
        return
    
    # Simulate notification delivery
    for notification in scheduled:
        print(f"Delivering notification for {notification.question_type}...")
        
        # Get pattern data
        pattern = UserPattern.objects.get(
            user_id=user_id,
            question_type=notification.question_type
        )
        
        # Create notification message
        typical_time = pattern.average_time.strftime('%H:%M')
        messages = {
            'clock_in': f"⏰ Time to Start Your Day - You usually clock in at {typical_time}",
            'lunch_out': f"🍽️ Lunch Time - You typically go to lunch at {typical_time}",
            'lunch_in': f"⏰ Lunch Break Ending - You usually return from lunch at {typical_time}",
            'clock_out': f"🏠 End of Day - You usually clock out at {typical_time}"
        }
        
        message = messages.get(notification.question_type, "Notification")
        print(f"  📨 {message}")
        
        # Mark as sent
        notification.is_sent = True
        notification.sent_at = datetime.now()
        notification.save()
        
        print(f"  ✅ Notification delivered and marked as sent")
        print()

def demonstrate_api_endpoints():
    """Demonstrate API endpoints"""
    print("\n🌐 Demonstrating API Endpoints...")
    
    print("Available endpoints:")
    print("  POST /api/ml/register_fcm_token/")
    print("  GET /api/ml/get_user_patterns/")
    print("  GET /api/ml/get_scheduled_notifications/")
    print("  POST /api/ml/test_notification/")
    print("  GET /api/ml/get_notification_status/")
    
    # Test FCM token registration
    print("\nTesting FCM token registration...")
    demo_token = "demo_fcm_token_12345"
    
    try:
        token_obj, created = UserFCMToken.objects.update_or_create(
            user_id="demo_user",
            fcm_token=demo_token,
            defaults={
                'device_type': 'mobile',
                'is_active': True
            }
        )
        
        if created:
            print(f"✅ FCM token registered: {token_obj.id}")
        else:
            print(f"✅ FCM token updated: {token_obj.id}")
            
    except Exception as e:
        print(f"❌ Error registering FCM token: {e}")

def cleanup_demo_data():
    """Clean up demo data"""
    print("\n🧹 Cleaning up demo data...")
    
    # Delete demo stamps
    Stamp.objects.filter(description__contains="Day").delete()
    
    # Delete demo functions
    Function.objects.filter(name__in=['Clock In', 'Lunch Out', 'Lunch In', 'Clock Out']).delete()
    
    # Delete demo patterns
    UserPattern.objects.all().delete()
    
    # Delete demo scheduled notifications
    ScheduledNotification.objects.all().delete()
    
    # Delete demo FCM tokens
    UserFCMToken.objects.filter(fcm_token="demo_fcm_token_12345").delete()
    
    print("✅ Demo data cleaned up")

def main():
    """Main demonstration function"""
    print("ML Notification System - Practical Demonstration")
    print("=" * 60)
    
    try:
        # Step 1: Create demo data
        user_id, stamps = create_demo_data()
        
        # Step 2: Demonstrate pattern learning
        results = demonstrate_pattern_learning(user_id)
        
        # Step 3: Demonstrate notification scheduling
        demonstrate_notification_scheduling(user_id)
        
        # Step 4: Demonstrate notification delivery
        demonstrate_notification_delivery(user_id)
        
        # Step 5: Demonstrate API endpoints
        demonstrate_api_endpoints()
        
        print("\n🎉 Demonstration Complete!")
        print("\nKey Features Demonstrated:")
        print("✅ Automatic pattern learning from user behavior")
        print("✅ Exact time notification scheduling")
        print("✅ Firebase push notification integration")
        print("✅ API endpoints for frontend integration")
        print("✅ Celery task management")
        
        # Ask if user wants to clean up
        cleanup = input("\nClean up demo data? (y/n): ").lower().strip()
        if cleanup == 'y':
            cleanup_demo_data()
        else:
            print("Demo data preserved for further testing")
            
    except Exception as e:
        print(f"❌ Error during demonstration: {e}")
        import traceback
        traceback.print_exc()

if __name__ == "__main__":
    main()
