from django.core.management.base import BaseCommand
from django.utils import timezone
from datetime import timedelta
from calls.models import Call, CallLog
from calls.tasks import check_and_update_call_statuses
import requests
from django.conf import settings


class Command(BaseCommand):
    help = 'Fix stuck calls by checking VAPI status and updating accordingly'

    def add_arguments(self, parser):
        parser.add_argument(
            '--minutes',
            type=int,
            default=10,
            help='Check calls older than this many minutes (default: 10)',
        )
        parser.add_argument(
            '--dry-run',
            action='store_true',
            help='Show what would be updated without actually updating',
        )

    def handle(self, *args, **options):
        minutes = options['minutes']
        dry_run = options['dry_run']
        
        # Find calls that might be stuck
        cutoff_time = timezone.now() - timedelta(minutes=minutes)
        potentially_stuck_calls = Call.objects.filter(
            twilio_status__in=['initiated', 'ringing', 'in-progress'],
            created_at__lt=cutoff_time
        )
        
        if not potentially_stuck_calls.exists():
            self.stdout.write(
                self.style.SUCCESS('No potentially stuck calls found.')
            )
            return
        
        self.stdout.write(f'Found {potentially_stuck_calls.count()} potentially stuck calls:')
        
        headers = {
            'Authorization': f'Bearer {settings.VAPI_API_KEY}',
            'Content-Type': 'application/json'
        }
        
        updated_count = 0
        
        for call in potentially_stuck_calls:
            self.stdout.write(f'  - Call {call.id}: {call.senior.name} - Status: {call.twilio_status} - Created: {call.created_at}')
            
            if not call.vapi_call_id:
                self.stdout.write(f'    No VAPI Call ID - marking as failed')
                if not dry_run:
                    call.twilio_status = 'failed'
                    call.vapi_status = 'failed'
                    call.save()
                    
                    CallLog.objects.create(
                        call=call,
                        event_type='status_changed',
                        message=f'Status updated to failed (no VAPI Call ID after {minutes} minutes)',
                        data={'old_status': 'initiated', 'new_status': 'failed', 'reason': 'no_vapi_id'}
                    )
                    updated_count += 1
                continue
            
            # Check VAPI status
            try:
                response = requests.get(
                    f'https://api.vapi.ai/call/{call.vapi_call_id}',
                    headers=headers
                )
                
                if response.status_code == 200:
                    call_data = response.json()
                    vapi_status = call_data.get('status', 'unknown')
                    duration = call_data.get('duration')
                    
                    self.stdout.write(f'    VAPI Status: {vapi_status}, Duration: {duration}')
                    
                    # Map Vapi status to our status
                    status_mapping = {
                        'queued': 'initiated',
                        'ringing': 'ringing', 
                        'in-progress': 'in-progress',
                        'completed': 'completed',
                        'ended': 'completed',
                        'busy': 'busy',
                        'no-answer': 'no_answer',
                        'failed': 'failed',
                        'canceled': 'cancelled'
                    }
                    
                    if vapi_status in status_mapping:
                        new_status = status_mapping[vapi_status]
                        old_status = call.twilio_status
                        
                        if old_status != new_status:
                            self.stdout.write(f'    Updating status from {old_status} to {new_status}')
                            if not dry_run:
                                call.twilio_status = new_status
                                call.vapi_status = vapi_status
                                
                                if duration:
                                    call.duration = duration
                                
                                # Update timing information for completed calls
                                if new_status == 'completed' and old_status != 'completed':
                                    call.call_end_time = timezone.now()
                                    if call.call_start_time and not call.duration:
                                        duration_seconds = (call.call_end_time - call.call_start_time).total_seconds()
                                        call.duration = int(duration_seconds)
                                
                                call.save()
                                updated_count += 1
                                
                                CallLog.objects.create(
                                    call=call,
                                    event_type='status_changed',
                                    message=f'Status updated from {old_status} to {new_status} via fix command',
                                    data={'old_status': old_status, 'new_status': new_status, 'vapi_status': vapi_status, 'duration': duration}
                                )
                        else:
                            self.stdout.write(f'    Status unchanged: {old_status}')
                    else:
                        self.stdout.write(f'    Unknown VAPI status: {vapi_status}')
                        
                else:
                    self.stdout.write(f'    VAPI API Error: {response.status_code} - {response.text}')
                    
            except Exception as e:
                self.stdout.write(f'    Error checking VAPI: {str(e)}')
        
        if dry_run:
            self.stdout.write(
                self.style.WARNING(f'Dry run mode - would update {updated_count} calls')
            )
        else:
            self.stdout.write(
                self.style.SUCCESS(f'Successfully updated {updated_count} calls')
            )

