"""
Direct sync script using already obtained credentials
"""
import asyncio
import sys
import os
import httpx
import hashlib
import time
import json
import uuid
from datetime import datetime

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
from sqlalchemy import select

# Already authenticated credentials
APP_KEY = "FzpsFOpzbGfGfeSSbdYefg"
APP_TOKEN = "jmsPdehjIzhkvKht7ggEaA"
USER_ID = "8467906"
USER_TOKEN = "j2tqEbZbZAGMlC9wYu7uzA"
API_URL = "https://api.us.ilifesmart.com/app"
TENANT_EMAIL = "ithelpdesk@ic.gov.sa"

DATABASE_URL = "mysql+aiomysql://root:@localhost:3306/smartlife_db?charset=utf8mb4"

# Device type mapping
DEVICE_TYPE_MAP = {
    "SL_SC_BE": "environment_sensor",
    "SL_SC_THL": "environment_sensor",
    "V_SI": "virtual_device",
    "SL_SC_G": "gas_sensor",
    "SL_SC_WA": "water_leak_sensor",
    "SL_SC_MHW": "motion_sensor",
    "SL_SC_B1": "door_sensor",
    "SL_SW_ND1": "switch_1gang",
    "SL_SW_ND2": "switch_2gang",
    "SL_SW_ND3": "switch_3gang",
}


async def fetch_devices():
    """Fetch devices from LifeSmart API"""
    method = 'EpGetAll'
    tick = int(time.time())
    
    sdata_parts = [f'method:{method}']
    sdata_parts.extend([
        f'time:{tick}',
        f'userid:{USER_ID}',
        f'usertoken:{USER_TOKEN}',
        f'appkey:{APP_KEY}',
        f'apptoken:{APP_TOKEN}',
    ])
    sdata = ','.join(sdata_parts)
    sign = hashlib.md5(sdata.encode()).hexdigest()
    
    body = {
        'id': tick,
        'method': method,
        'system': {
            'ver': '1.0',
            'lang': 'en',
            'userid': USER_ID,
            'appkey': APP_KEY,
            'time': tick,
            'sign': sign,
        }
    }
    
    url = f'{API_URL}/api.{method}'
    headers = {'Content-Type': 'application/json'}
    
    async with httpx.AsyncClient(timeout=30) as client:
        response = await client.post(url, json=body, headers=headers)
        return response.json()


async def main():
    from app.models.tenant import Tenant
    from app.models.device import Device
    from app.models.alert import AlertRule
    
    engine = create_async_engine(DATABASE_URL, echo=False)
    async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
    
    async with async_session() as session:
        try:
            # Get tenant
            result = await session.execute(
                select(Tenant).where(Tenant.email == TENANT_EMAIL)
            )
            tenant = result.scalar_one_or_none()
            
            if not tenant:
                print("❌ Tenant not found!")
                return
            
            print(f"✅ Found tenant: {tenant.name}")
            
            # Update tenant with LifeSmart credentials
            tenant.lifesmart_user_id = USER_ID
            tenant.lifesmart_user_token = USER_TOKEN
            tenant.lifesmart_region = "sa"
            
            # Fetch devices from API
            print("\n📱 Fetching devices from LifeSmart API...")
            data = await fetch_devices()
            
            if data.get("code") != 0:
                print(f"❌ API Error: {data.get('message')}")
                return
            
            devices_data = data.get("message", [])
            print(f"✅ Found {len(devices_data)} devices")
            
            # Sync devices
            new_count = 0
            updated_count = 0
            
            for dev in devices_data:
                device_id = dev.get("me")
                hub_id = dev.get("agt")
                name = dev.get("name", device_id)
                devtype = dev.get("devtype", "unknown")
                mapped_type = DEVICE_TYPE_MAP.get(devtype, "unknown")
                is_online = dev.get("stat") == 1
                device_data = dev.get("data", {})
                
                # Skip virtual devices
                if devtype == "V_SI":
                    continue
                
                # Check if device exists
                result = await session.execute(
                    select(Device).where(
                        Device.tenant_id == tenant.id,
                        Device.lifesmart_device_id == device_id
                    )
                )
                existing = result.scalar_one_or_none()
                
                # Extract sensor values
                readings = {}
                if "T" in device_data:
                    readings["temperature"] = device_data["T"].get("v")
                if "H" in device_data:
                    readings["humidity"] = device_data["H"].get("v")
                if "V" in device_data:
                    readings["battery"] = device_data["V"].get("v")
                if "Z" in device_data:
                    readings["illuminance"] = device_data["Z"].get("v")
                
                metadata = {
                    "hub_id": hub_id,
                    "model": devtype,
                    "full_class": dev.get("fullCls"),
                    "version": dev.get("ver"),
                    "readings": readings,
                    "raw_data": device_data,
                    "last_sync": datetime.utcnow().isoformat()
                }
                
                if existing:
                    existing.name = name
                    existing.device_type = mapped_type
                    existing.is_online = is_online
                    existing.device_metadata = metadata
                    updated_count += 1
                    status = "🟢 Online" if is_online else "🔴 Offline"
                    print(f"   🔄 Updated: {name} ({mapped_type}) - {status}")
                    if readings:
                        print(f"      📊 {readings}")
                else:
                    new_device = Device(
                        id=uuid.uuid4(),
                        tenant_id=tenant.id,
                        name=name,
                        name_ar=name,
                        device_type=mapped_type,
                        lifesmart_device_id=device_id,
                        lifesmart_hub_id=hub_id,
                        device_model=devtype,
                        is_online=is_online,
                        device_metadata=metadata
                    )
                    session.add(new_device)
                    new_count += 1
                    status = "🟢 Online" if is_online else "🔴 Offline"
                    print(f"   ✨ Added: {name} ({mapped_type}) - {status}")
                    if readings:
                        print(f"      📊 {readings}")
            
            await session.commit()
            
            print(f"\n📊 Sync Summary:")
            print(f"   ✨ New devices: {new_count}")
            print(f"   🔄 Updated devices: {updated_count}")
            
            # Create alert rules for sensors
            print("\n🔔 Creating smart alerts...")
            
            # Get all environment sensors
            result = await session.execute(
                select(Device).where(
                    Device.tenant_id == tenant.id,
                    Device.device_type == "environment_sensor"
                )
            )
            sensors = result.scalars().all()
            
            alert_count = 0
            for sensor in sensors:
                # Check if alerts exist
                result = await session.execute(
                    select(AlertRule).where(AlertRule.device_id == sensor.id)
                )
                existing_alerts = result.scalars().all()
                
                if len(existing_alerts) == 0:
                    # High temperature alert
                    alert1 = AlertRule(
                        id=uuid.uuid4(),
                        tenant_id=tenant.id,
                        device_id=sensor.id,
                        name=f"High Temperature - {sensor.name}",
                        name_ar=f"درجة حرارة عالية - {sensor.name}",
                        reading_type="temperature",
                        condition_type="greater_than",
                        threshold_value=30.0,
                        severity="warning"
                    )
                    session.add(alert1)
                    
                    # Low temperature alert
                    alert2 = AlertRule(
                        id=uuid.uuid4(),
                        tenant_id=tenant.id,
                        device_id=sensor.id,
                        name=f"Low Temperature - {sensor.name}",
                        name_ar=f"درجة حرارة منخفضة - {sensor.name}",
                        reading_type="temperature",
                        condition_type="less_than",
                        threshold_value=10.0,
                        severity="warning"
                    )
                    session.add(alert2)
                    
                    # High humidity alert
                    alert3 = AlertRule(
                        id=uuid.uuid4(),
                        tenant_id=tenant.id,
                        device_id=sensor.id,
                        name=f"High Humidity - {sensor.name}",
                        name_ar=f"رطوبة عالية - {sensor.name}",
                        reading_type="humidity",
                        condition_type="greater_than",
                        threshold_value=70.0,
                        severity="warning"
                    )
                    session.add(alert3)
                    
                    alert_count += 3
                    print(f"   ✅ Created 3 alerts for: {sensor.name}")
            
            await session.commit()
            print(f"\n🔔 Created {alert_count} alert rules")
            
            print("\n✅ Sync completed successfully!")
            
        except Exception as e:
            print(f"❌ Error: {e}")
            import traceback
            traceback.print_exc()
        finally:
            await engine.dispose()


if __name__ == "__main__":
    asyncio.run(main())
