"""
مهام التنبيهات - Celery Tasks
"""
import asyncio
from datetime import datetime, timedelta, timezone
from app.celery_app import celery_app
import logging
import pytz

# توقيت الرياض
RIYADH_TZ = pytz.timezone('Asia/Riyadh')

def get_local_time():
    """الحصول على التوقيت المحلي (الرياض)"""
    return datetime.now(RIYADH_TZ)

logger = logging.getLogger(__name__)


@celery_app.task
def check_device_alerts():
    """فحص تنبيهات الأجهزة وإرسال إيميلات"""
    try:
        from app.database import AsyncSessionLocal
        from app.models.device import Device
        from app.models.alert import AlertRule, AlertLog
        from app.models.settings import TenantSettings
        from app.services.email_service import EmailService
        from sqlalchemy import select, and_
        
        print(f"\n{'='*50}")
        print(f"[{datetime.now()}] CHECKING DEVICE ALERTS...")
        print(f"{'='*50}")
        
        async def _check_alerts():
            async with AsyncSessionLocal() as session:
                # جلب قواعد التنبيهات النشطة
                result = await session.execute(
                    select(AlertRule).where(AlertRule.is_active == True)
                )
                rules = result.scalars().all()
                print(f"Found {len(rules)} active alert rules")
                
                triggered_count = 0
                emails_sent = 0
                resolved_count = 0
                
                for rule in rules:
                    print(f"\n--- Checking rule: {rule.name} ---")
                    
                    # جلب الجهاز
                    device = await session.get(Device, rule.device_id)
                    if not device:
                        print(f"  Device not found: {rule.device_id}")
                        continue
                    if not device.device_metadata:
                        print(f"  Device has no metadata: {device.name}")
                        continue
                    
                    readings = device.device_metadata.get('readings', {})
                    current_value = readings.get(rule.reading_type)
                    
                    print(f"  Device: {device.name}")
                    print(f"  Reading type: {rule.reading_type}")
                    print(f"  Current value: {current_value}")
                    print(f"  Threshold: {rule.condition_type} {rule.threshold_value}")
                    
                    if current_value is None:
                        print(f"  No reading for type: {rule.reading_type}")
                        continue
                    
                    # التحقق من الشرط
                    condition_met = False
                    threshold = float(rule.threshold_value) if rule.threshold_value else 0
                    
                    if rule.condition_type == 'greater_than' and current_value > threshold:
                        condition_met = True
                    elif rule.condition_type == 'less_than' and current_value < threshold:
                        condition_met = True
                    elif rule.condition_type == 'equals' and current_value == threshold:
                        condition_met = True
                    
                    print(f"  Condition met: {condition_met}")
                    
                    # جلب إعدادات المستأجر
                    settings_result = await session.execute(
                        select(TenantSettings).where(TenantSettings.tenant_id == rule.tenant_id)
                    )
                    settings = settings_result.scalar_one_or_none()
                    
                    if not settings:
                        print(f"  No settings found for tenant")
                        continue
                    
                    # جلب آخر تنبيه غير محلول لهذه القاعدة
                    last_unresolved = await session.execute(
                        select(AlertLog).where(
                            and_(
                                AlertLog.alert_rule_id == rule.id,
                                AlertLog.is_resolved == False
                            )
                        ).order_by(AlertLog.triggered_at.desc()).limit(1)
                    )
                    last_alert = last_unresolved.scalar_one_or_none()
                    
                    if condition_met:
                        # الشرط متحقق - نحتاج إرسال تنبيه أو تذكير
                        should_send_email = False
                        is_reminder = False
                        
                        # الحصول على القيم من الإعدادات
                        dashboard_refresh_seconds = settings.dashboard_refresh_interval or 30
                        cooldown_minutes = settings.alert_cooldown_minutes or 1
                        
                        now = get_local_time().replace(tzinfo=None)
                        
                        if last_alert is None:
                            # لا يوجد تنبيه سابق - تحقق من وقت أول اكتشاف للشرط
                            if rule.condition_first_detected is None:
                                # أول اكتشاف للشرط - سجّل الوقت
                                rule.condition_first_detected = now
                                print(f"  First detection - waiting {dashboard_refresh_seconds}s before alert")
                            else:
                                # تحقق إذا مرّ وقت dashboard_refresh_interval
                                time_since_detection = now - rule.condition_first_detected
                                if time_since_detection >= timedelta(seconds=dashboard_refresh_seconds):
                                    should_send_email = True
                                    print(f"  First alert after {time_since_detection.total_seconds():.0f}s (threshold: {dashboard_refresh_seconds}s)")
                                else:
                                    print(f"  Waiting - {time_since_detection.total_seconds():.0f}s < {dashboard_refresh_seconds}s")
                        else:
                            # تحقق من cooldown للتذكير
                            time_since_last = now - last_alert.triggered_at
                            
                            if time_since_last >= timedelta(minutes=cooldown_minutes):
                                should_send_email = True
                                is_reminder = True
                                print(f"  Reminder - {time_since_last.total_seconds()/60:.1f} min since last (cooldown: {cooldown_minutes} min)")
                            else:
                                print(f"  In cooldown - {time_since_last.total_seconds()/60:.1f} min < {cooldown_minutes} min")
                        
                        if should_send_email:
                            # إنشاء سجل تنبيه
                            alert_log = AlertLog(
                                tenant_id=rule.tenant_id,
                                alert_rule_id=rule.id,
                                device_id=device.id,
                                title=f"{'[تذكير] ' if is_reminder else ''}{rule.name}",
                                message=f"{rule.reading_type}: {current_value} {'أكبر من' if rule.condition_type == 'greater_than' else 'أصغر من' if rule.condition_type == 'less_than' else 'يساوي'} {threshold}",
                                severity=rule.severity,
                                reading_value=float(current_value),
                                triggered_at=get_local_time().replace(tzinfo=None)
                            )
                            session.add(alert_log)
                            
                            # تحديث last_triggered
                            rule.last_triggered = get_local_time().replace(tzinfo=None)
                            triggered_count += 1
                            
                            # إرسال إيميل
                            if settings.alert_email_enabled and settings.alert_email_recipients:
                                try:
                                    email_service = EmailService(settings)
                                    recipients = [e.strip() for e in settings.alert_email_recipients.split(',') if e.strip()]
                                    print(f"  Sending email to: {recipients}")
                                    
                                    condition_map = {
                                        'greater_than': 'أكبر من',
                                        'less_than': 'أصغر من',
                                        'equals': 'يساوي'
                                    }
                                    
                                    sent = email_service.send_alert_email(
                                        to_emails=recipients,
                                        alert_type="reminder" if is_reminder else "threshold",
                                        device_name=device.name,
                                        device_id=str(device.id),
                                        reading_type=rule.reading_type,
                                        current_value=current_value,
                                        threshold_value=threshold,
                                        condition=condition_map.get(rule.condition_type, rule.condition_type),
                                        severity=rule.severity,
                                        location=device.location
                                    )
                                    emails_sent += sent
                                    print(f"  ✓ Email sent successfully!")
                                except Exception as email_error:
                                    print(f"  ✗ Error sending email: {email_error}")
                            else:
                                print(f"  Email disabled or no recipients")
                    
                    else:
                        # الشرط غير متحقق - إعادة ضبط وقت أول اكتشاف
                        if rule.condition_first_detected is not None:
                            rule.condition_first_detected = None
                            print(f"  Condition cleared - reset first detection time")
                        
                        # تحقق إذا كان هناك تنبيه يحتاج حل
                        if last_alert and not last_alert.is_resolved:
                            print(f"  Condition resolved - marking alert as resolved")
                            
                            # تحديث جميع التنبيهات غير المحلولة لهذه القاعدة
                            unresolved_result = await session.execute(
                                select(AlertLog).where(
                                    and_(
                                        AlertLog.alert_rule_id == rule.id,
                                        AlertLog.is_resolved == False
                                    )
                                )
                            )
                            unresolved_alerts = unresolved_result.scalars().all()
                            
                            for alert in unresolved_alerts:
                                alert.is_resolved = True
                                alert.resolved_at = get_local_time().replace(tzinfo=None)
                            
                            resolved_count += len(unresolved_alerts)
                            
                            # إرسال إيميل حل المشكلة
                            if settings.alert_email_enabled and settings.alert_email_recipients:
                                try:
                                    email_service = EmailService(settings)
                                    recipients = [e.strip() for e in settings.alert_email_recipients.split(',') if e.strip()]
                                    print(f"  Sending resolved email to: {recipients}")
                                    
                                    sent = email_service.send_alert_resolved_email(
                                        to_emails=recipients,
                                        device_name=device.name,
                                        device_id=str(device.id),
                                        reading_type=rule.reading_type,
                                        current_value=current_value
                                    )
                                    emails_sent += sent
                                    print(f"  ✓ Resolved email sent!")
                                except Exception as email_error:
                                    print(f"  ✗ Error sending resolved email: {email_error}")
                
                await session.commit()
                print(f"\n{'='*50}")
                print(f"SUMMARY: triggered={triggered_count}, emails={emails_sent}, resolved={resolved_count}")
                print(f"{'='*50}\n")
                return {"triggered": triggered_count, "emails_sent": emails_sent, "resolved": resolved_count}
        
        try:
            import nest_asyncio
            nest_asyncio.apply()
        except ImportError:
            pass

        try:
            import asyncio
            loop = asyncio.get_running_loop()
            import concurrent.futures
            with concurrent.futures.ThreadPoolExecutor() as pool:
                result = pool.submit(asyncio.run, _check_alerts()).result()
        except RuntimeError:
            import asyncio
            result = asyncio.run(_check_alerts())
        
        return {"status": "success", **result, "timestamp": datetime.now().isoformat()}
        
    except Exception as e:
        import traceback
        print(f"ERROR in check_device_alerts: {e}")
        print(traceback.format_exc())
        return {"status": "error", "error": str(e)}


@celery_app.task
def cleanup_old_alerts(days: int = 90):
    """تنظيف التنبيهات القديمة"""
    try:
        from app.database import AsyncSessionLocal
        from app.models.alert import AlertLog
        from sqlalchemy import delete
        
        async def _cleanup():
            async with AsyncSessionLocal() as session:
                cutoff_date = get_local_time().replace(tzinfo=None) - timedelta(days=days)
                result = await session.execute(
                    delete(AlertLog).where(
                        AlertLog.triggered_at < cutoff_date,
                        AlertLog.is_resolved == True
                    )
                )
                await session.commit()
                return result.rowcount
        
        try:
            import nest_asyncio
            nest_asyncio.apply()
        except ImportError:
            pass

        try:
            import asyncio
            loop = asyncio.get_running_loop()
            import concurrent.futures
            with concurrent.futures.ThreadPoolExecutor() as pool:
                deleted = pool.submit(asyncio.run, _cleanup()).result()
        except RuntimeError:
            import asyncio
            deleted = asyncio.run(_cleanup())
        
        return {"status": "success", "deleted_count": deleted, "timestamp": datetime.now().isoformat()}
        
    except Exception as e:
        return {"status": "error", "error": str(e)}


@celery_app.task
def send_alert_notification(alert_id: int):
    """إرسال إشعار تنبيه"""
    try:
        return {"status": "success", "alert_id": alert_id}
    except Exception as e:
        return {"status": "error", "error": str(e)}
