#!/usr/bin/env python
"""
Cleanup script for removing test/UAT requests and processed payment requests.
This script should be run on the production server with caution.

Usage:
    python cleanup_test_requests.py --dry-run  # To see what would be deleted without actually deleting
    python cleanup_test_requests.py  # To perform the actual deletion
"""

import os
import sys
import django
import argparse
from datetime import datetime, timedelta

# Setup Django environment
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'wtlms.settings')
django.setup()

from django.db.models import Q
from django.contrib.auth.models import User
from leave.models import LeaveRequest
from overtime.models import OvertimeRequest

def parse_args():
    parser = argparse.ArgumentParser(description='Clean up test requests and processed payment requests')
    parser.add_argument('--dry-run', action='store_true', help='Run without actually deleting anything')
    parser.add_argument('--before-date', type=str, help='Delete requests before this date (YYYY-MM-DD)')
    parser.add_argument('--test-users', action='store_true', help='Delete requests from test users only')
    parser.add_argument('--processed-only', action='store_true', help='Delete only processed payment requests')
    return parser.parse_args()

def get_test_users():
    """Identify test users based on common patterns or specific usernames"""
    test_patterns = ['test', 'demo', 'uat', 'training']
    
    # Find users with test patterns in their username or email
    test_users = User.objects.filter(
        Q(username__icontains='test') | 
        Q(email__icontains='test') |
        Q(username__icontains='demo') |
        Q(email__icontains='demo') |
        Q(username__icontains='uat') |
        Q(email__icontains='uat') |
        Q(username__icontains='training') |
        Q(email__icontains='training')
    )
    
    # You can also add specific known test users
    specific_test_usernames = []  # Add specific usernames here if needed
    if specific_test_usernames:
        test_users = test_users | User.objects.filter(username__in=specific_test_usernames)
    
    return test_users

def cleanup_leave_requests(args):
    """Clean up leave requests based on specified criteria"""
    query = Q()
    
    # Filter by date if specified
    if args.before_date:
        try:
            before_date = datetime.strptime(args.before_date, '%Y-%m-%d').date()
            query &= Q(date_requested__lt=before_date)
        except ValueError:
            print(f"Error: Invalid date format. Please use YYYY-MM-DD")
            return 0, []
    
    # Filter by test users if specified
    if args.test_users:
        test_users = get_test_users()
        query &= Q(employee__user__in=test_users)
    
    # Filter by processed status if specified
    if args.processed_only:
        query &= Q(status__in=['APPROVED', 'REJECTED'])
    
    # Get the requests to delete
    requests_to_delete = LeaveRequest.objects.filter(query)
    
    # Store request details for reporting
    request_details = [
        f"Leave Request #{req.id}: {req.employee.user.username}, {req.start_date} to {req.end_date}, Status: {req.status}"
        for req in requests_to_delete
    ]
    
    count = requests_to_delete.count()
    
    # Delete if not a dry run
    if not args.dry_run and count > 0:
        requests_to_delete.delete()
        print(f"Deleted {count} leave requests")
    
    return count, request_details

def cleanup_overtime_requests(args):
    """Clean up overtime requests based on specified criteria"""
    query = Q()
    
    # Filter by date if specified
    if args.before_date:
        try:
            before_date = datetime.strptime(args.before_date, '%Y-%m-%d').date()
            query &= Q(date_requested__lt=before_date)
        except ValueError:
            print(f"Error: Invalid date format. Please use YYYY-MM-DD")
            return 0, []
    
    # Filter by test users if specified
    if args.test_users:
        test_users = get_test_users()
        query &= Q(employee__user__in=test_users)
    
    # Filter by processed status if specified
    if args.processed_only:
        query &= Q(status__in=['APPROVED', 'REJECTED'])
    
    # Get the requests to delete
    requests_to_delete = OvertimeRequest.objects.filter(query)
    
    # Store request details for reporting
    request_details = [
        f"Overtime Request #{req.id}: {req.employee.user.username}, {req.date}, {req.start_time}-{req.end_time}, Status: {req.status}"
        for req in requests_to_delete
    ]
    
    count = requests_to_delete.count()
    
    # Delete if not a dry run
    if not args.dry_run and count > 0:
        requests_to_delete.delete()
        print(f"Deleted {count} overtime requests")
    
    return count, request_details

def main():
    args = parse_args()
    
    print("=== WTLMS Request Cleanup Tool ===")
    if args.dry_run:
        print("DRY RUN MODE: No records will be deleted")
    
    # Display filters being applied
    filters = []
    if args.before_date:
        filters.append(f"Before date: {args.before_date}")
    if args.test_users:
        filters.append("Test users only")
    if args.processed_only:
        filters.append("Processed requests only")
    
    if filters:
        print("Applying filters:", ", ".join(filters))
    else:
        print("WARNING: No filters specified. This will target ALL requests.")
        if not args.dry_run:
            confirm = input("Are you sure you want to proceed? This could delete production data. (yes/no): ")
            if confirm.lower() != 'yes':
                print("Operation cancelled.")
                return
    
    # Process leave requests
    leave_count, leave_details = cleanup_leave_requests(args)
    print(f"\nFound {leave_count} leave requests to delete")
    if args.dry_run and leave_details:
        print("\nLeave requests that would be deleted:")
        for detail in leave_details[:10]:  # Show first 10 for brevity
            print(f"  - {detail}")
        if len(leave_details) > 10:
            print(f"  ... and {len(leave_details) - 10} more")
    
    # Process overtime requests
    overtime_count, overtime_details = cleanup_overtime_requests(args)
    print(f"\nFound {overtime_count} overtime requests to delete")
    if args.dry_run and overtime_details:
        print("\nOvertime requests that would be deleted:")
        for detail in overtime_details[:10]:  # Show first 10 for brevity
            print(f"  - {detail}")
        if len(overtime_details) > 10:
            print(f"  ... and {len(overtime_details) - 10} more")
    
    total_count = leave_count + overtime_count
    
    if args.dry_run:
        print(f"\nDRY RUN SUMMARY: {total_count} total requests would be deleted")
        print("To perform the actual deletion, run the script without the --dry-run flag")
    else:
        print(f"\nDELETION COMPLETE: {total_count} total requests were deleted")

if __name__ == "__main__":
    main()
