#!/usr/bin/env python3
"""
ML Notification System - Simple Demonstration
This script shows how the system works step by step
"""

import os
import sys
import django
from datetime import datetime, time, timedelta
from django.utils import timezone

# 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
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
    from user.models import User
    demo_user, created = User.objects.get_or_create(
        email='demo@example.com',
        defaults={
            'firstname': 'Demo',
            'lastname': 'User',
            'password': 'demo_password',
            'employee_no': 'DEMO001'
        }
    )
    demo_user_id = str(demo_user.id)
    print(f"Demo User ID: {demo_user_id}")
    
    # Get existing paycode or create one
    from paycode.models import Paycode
    paycode, created = Paycode.objects.get_or_create(
        paycode='REG',
        defaults={'name': 'Regular Work'}
    )
    
    # Create demo functions with question_type
    functions = {}
    
    # Clock In
    functions['clock_in'] = Function.objects.create(
        name='Clock In',
        question_type='clock_in',
        out=False,
        paycode=paycode
    )
    
    # Lunch Out
    functions['lunch_out'] = Function.objects.create(
        name='Lunch Out',
        question_type='lunch_out',
        out=True,
        paycode=paycode
    )
    
    # Lunch In
    functions['lunch_in'] = Function.objects.create(
        name='Lunch In',
        question_type='lunch_in',
        out=False,
        paycode=paycode
    )
    
    # Clock Out
    functions['clock_out'] = Function.objects.create(
        name='Clock Out',
        question_type='clock_out',
        out=True,
        paycode=paycode
    )
    
    # 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=demo_user,
            stamp_function='clock_in',
            time=clock_in_time,
            date=current_date,
            description=f"Clock In - Day {day + 1}",
            start_date=timezone.now()
        ))
        
        # 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=demo_user,
            stamp_function='lunch_out',
            time=lunch_out_time,
            date=current_date,
            description=f"Lunch Out - Day {day + 1}",
            start_date=timezone.now()
        ))
        
        # 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=demo_user,
            stamp_function='lunch_in',
            time=lunch_in_time,
            date=current_date,
            description=f"Lunch In - Day {day + 1}",
            start_date=timezone.now()
        ))
        
        # 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=demo_user,
            stamp_function='clock_out',
            time=clock_out_time,
            date=current_date,
            description=f"Clock Out - Day {day + 1}",
            start_date=timezone.now()
        ))
    
    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("\nDemonstrating 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("\nLearned 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("\nDemonstrating 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"\nScheduled Notifications:")
    for notification in scheduled:
        print(f"  {notification.question_type}: {notification.scheduled_time}")
        print(f"    Task ID: {notification.celery_task_id}")
        print()

def demonstrate_api_endpoints(user_id):
    """Demonstrate API endpoints"""
    print("\nDemonstrating 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=user_id,
            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("\nCleaning 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 API endpoints
        demonstrate_api_endpoints(user_id)
        
        print("\nDemonstration 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()
