"""
LifeSmart Integration API endpoints
"""
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, update
from typing import List, Optional
from pydantic import BaseModel
from datetime import datetime
import logging

from app.database import get_db
from app.api.deps import get_current_user
from app.models.user import User
from app.models.tenant import Tenant
from app.models.device import Device
from app.services.lifesmart_client import LifeSmartClient, AuthResult

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/lifesmart", tags=["LifeSmart Integration"])


# Request/Response Models
class LifeSmartCredentials(BaseModel):
    app_key: str
    app_token: str
    region: str = "global"


class LifeSmartAuthRequest(BaseModel):
    app_key: str
    app_token: str
    username: str
    password: str
    region: str = "global"


class LifeSmartTokenRequest(BaseModel):
    app_key: str
    app_token: str
    user_token: str
    user_id: str
    region: str = "global"


class LifeSmartConnectionResponse(BaseModel):
    success: bool
    message: str
    user_id: Optional[str] = None
    devices_count: Optional[int] = None


class LifeSmartDeviceResponse(BaseModel):
    device_id: str
    hub_id: str
    name: str
    device_type: str
    device_model: str
    is_online: bool
    data: dict
    controls: list


class SyncResultResponse(BaseModel):
    success: bool
    message: str
    total_devices: int
    synced_devices: int
    new_devices: int
    updated_devices: int
    failed_devices: int
    devices: List[LifeSmartDeviceResponse]


class DeviceControlRequest(BaseModel):
    hub_id: str
    device_id: str
    idx: str
    value: int
    control_type: str = "0x81"


class TenantLifeSmartConfig(BaseModel):
    lifesmart_app_key: Optional[str] = None
    lifesmart_app_token: Optional[str] = None
    lifesmart_user_id: Optional[str] = None
    lifesmart_user_token: Optional[str] = None
    lifesmart_region: str = "global"


@router.post("/connect", response_model=LifeSmartConnectionResponse)
async def connect_lifesmart_account(
    auth_data: LifeSmartAuthRequest,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Connect tenant's LifeSmart account using email/password authentication
    """
    try:
        # Create LifeSmart client
        client = LifeSmartClient(
            app_key=auth_data.app_key,
            app_token=auth_data.app_token,
            region=auth_data.region
        )
        
        # Authenticate with LifeSmart
        auth_result = await client.authenticate(
            username=auth_data.username,
            password=auth_data.password
        )
        
        if not auth_result.success:
            await client.close()
            raise HTTPException(
                status_code=status.HTTP_401_UNAUTHORIZED,
                detail=f"LifeSmart authentication failed: {auth_result.error}"
            )
        
        # Update tenant with LifeSmart credentials
        if current_user.tenant_id:
            await db.execute(
                update(Tenant)
                .where(Tenant.id == current_user.tenant_id)
                .values(
                    lifesmart_app_key=auth_data.app_key,
                    lifesmart_app_token=auth_data.app_token,
                    lifesmart_user_id=auth_result.user_id,
                    lifesmart_user_token=auth_result.user_token,
                    lifesmart_region=auth_data.region,
                    updated_at=datetime.utcnow()
                )
            )
            await db.commit()
        
        # Get devices count
        devices = await client.get_devices()
        await client.close()
        
        return LifeSmartConnectionResponse(
            success=True,
            message="Successfully connected to LifeSmart account",
            user_id=auth_result.user_id,
            devices_count=len(devices)
        )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to connect LifeSmart account: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to connect: {str(e)}"
        )


@router.post("/connect-token", response_model=LifeSmartConnectionResponse)
async def connect_with_token(
    token_data: LifeSmartTokenRequest,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Connect tenant's LifeSmart account using pre-obtained user token
    """
    try:
        # Create LifeSmart client with token
        client = LifeSmartClient(
            app_key=token_data.app_key,
            app_token=token_data.app_token,
            user_id=token_data.user_id,
            user_token=token_data.user_token,
            region=token_data.region
        )
        
        # Test connection by fetching devices
        devices = await client.get_devices()
        
        # Update tenant with LifeSmart credentials
        if current_user.tenant_id:
            await db.execute(
                update(Tenant)
                .where(Tenant.id == current_user.tenant_id)
                .values(
                    lifesmart_app_key=token_data.app_key,
                    lifesmart_app_token=token_data.app_token,
                    lifesmart_user_id=token_data.user_id,
                    lifesmart_user_token=token_data.user_token,
                    lifesmart_region=token_data.region,
                    updated_at=datetime.utcnow()
                )
            )
            await db.commit()
        
        await client.close()
        
        return LifeSmartConnectionResponse(
            success=True,
            message="Successfully connected to LifeSmart account",
            user_id=token_data.user_id,
            devices_count=len(devices)
        )
        
    except Exception as e:
        logger.error(f"Failed to connect with token: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to connect: {str(e)}"
        )


@router.get("/devices", response_model=List[LifeSmartDeviceResponse])
async def get_lifesmart_devices(
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Fetch all devices from connected LifeSmart account
    """
    try:
        # Get tenant's LifeSmart credentials
        if not current_user.tenant_id:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="User is not associated with a tenant"
            )
        
        result = await db.execute(
            select(Tenant).where(Tenant.id == current_user.tenant_id)
        )
        tenant = result.scalar_one_or_none()
        
        if not tenant or not tenant.lifesmart_app_key:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="LifeSmart account not connected. Please connect first."
            )
        
        # Create client and fetch devices
        client = LifeSmartClient(
            app_key=tenant.lifesmart_app_key,
            app_token=tenant.lifesmart_app_token,
            user_id=tenant.lifesmart_user_id,
            user_token=tenant.lifesmart_user_token,
            region=tenant.lifesmart_region or "global"
        )
        
        devices = await client.get_devices()
        await client.close()
        
        return [
            LifeSmartDeviceResponse(
                device_id=d.device_id,
                hub_id=d.hub_id,
                name=d.name,
                device_type=d.device_type,
                device_model=d.device_model,
                is_online=d.is_online,
                data=d.data,
                controls=d.controls
            )
            for d in devices
        ]
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to fetch LifeSmart devices: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to fetch devices: {str(e)}"
        )


@router.post("/sync", response_model=SyncResultResponse)
async def sync_devices(
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Sync devices from LifeSmart to the local database
    """
    try:
        # Get tenant's LifeSmart credentials
        if not current_user.tenant_id:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="User is not associated with a tenant"
            )
        
        result = await db.execute(
            select(Tenant).where(Tenant.id == current_user.tenant_id)
        )
        tenant = result.scalar_one_or_none()
        
        if not tenant or not tenant.lifesmart_app_key:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="LifeSmart account not connected"
            )
        
        # Fetch devices from LifeSmart
        client = LifeSmartClient(
            app_key=tenant.lifesmart_app_key,
            app_token=tenant.lifesmart_app_token,
            user_id=tenant.lifesmart_user_id,
            user_token=tenant.lifesmart_user_token,
            region=tenant.lifesmart_region or "global"
        )
        
        lifesmart_devices = await client.get_devices()
        await client.close()
        
        # Get existing devices
        existing_result = await db.execute(
            select(Device).where(Device.tenant_id == current_user.tenant_id)
        )
        existing_devices = {d.lifesmart_device_id: d for d in existing_result.scalars().all()}
        
        new_devices = 0
        updated_devices = 0
        failed_devices = 0
        synced_devices = []
        
        for ls_device in lifesmart_devices:
            try:
                if ls_device.device_id in existing_devices:
                    # Update existing device
                    device = existing_devices[ls_device.device_id]
                    device.name = ls_device.name
                    device.device_type = ls_device.device_type
                    device.is_online = ls_device.is_online
                    device.device_metadata = {
                        "hub_id": ls_device.hub_id,
                        "model": ls_device.device_model,
                        "data": ls_device.data,
                        "controls": ls_device.controls,
                        "last_sync": datetime.utcnow().isoformat()
                    }
                    device.updated_at = datetime.utcnow()
                    updated_devices += 1
                else:
                    # Create new device
                    new_device = Device(
                        tenant_id=current_user.tenant_id,
                        name=ls_device.name,
                        name_ar=ls_device.name,  # Can be updated later
                        device_type=ls_device.device_type,
                        lifesmart_device_id=ls_device.device_id,
                        is_online=ls_device.is_online,
                        device_metadata={
                            "hub_id": ls_device.hub_id,
                            "model": ls_device.device_model,
                            "data": ls_device.data,
                            "controls": ls_device.controls,
                            "last_sync": datetime.utcnow().isoformat()
                        }
                    )
                    db.add(new_device)
                    new_devices += 1
                
                synced_devices.append(LifeSmartDeviceResponse(
                    device_id=ls_device.device_id,
                    hub_id=ls_device.hub_id,
                    name=ls_device.name,
                    device_type=ls_device.device_type,
                    device_model=ls_device.device_model,
                    is_online=ls_device.is_online,
                    data=ls_device.data,
                    controls=ls_device.controls
                ))
                
            except Exception as e:
                logger.error(f"Failed to sync device {ls_device.device_id}: {str(e)}")
                failed_devices += 1
        
        await db.commit()
        
        # فحص التنبيهات بعد تحديث بيانات الأجهزة
        try:
            from app.tasks.alert_tasks import check_device_alerts
            alert_result = check_device_alerts()
            logger.info(f"Alert check after sync: {alert_result}")
        except Exception as alert_error:
            logger.error(f"Error checking alerts after sync: {alert_error}")
        
        return SyncResultResponse(
            success=True,
            message=f"Sync completed: {new_devices} new, {updated_devices} updated, {failed_devices} failed",
            total_devices=len(lifesmart_devices),
            synced_devices=new_devices + updated_devices,
            new_devices=new_devices,
            updated_devices=updated_devices,
            failed_devices=failed_devices,
            devices=synced_devices
        )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to sync devices: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to sync devices: {str(e)}"
        )


@router.post("/control")
async def control_device(
    control: DeviceControlRequest,
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Send control command to a LifeSmart device
    """
    try:
        # Get tenant's LifeSmart credentials
        if not current_user.tenant_id:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="User is not associated with a tenant"
            )
        
        result = await db.execute(
            select(Tenant).where(Tenant.id == current_user.tenant_id)
        )
        tenant = result.scalar_one_or_none()
        
        if not tenant or not tenant.lifesmart_app_key:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="LifeSmart account not connected"
            )
        
        # Create client and send command
        client = LifeSmartClient(
            app_key=tenant.lifesmart_app_key,
            app_token=tenant.lifesmart_app_token,
            user_id=tenant.lifesmart_user_id,
            user_token=tenant.lifesmart_user_token,
            region=tenant.lifesmart_region or "global"
        )
        
        success = await client.control_device(
            hub_id=control.hub_id,
            device_id=control.device_id,
            command={
                "idx": control.idx,
                "value": control.value,
                "type": control.control_type
            }
        )
        await client.close()
        
        if success:
            return {"success": True, "message": "Command sent successfully"}
        else:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Failed to send command to device"
            )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to control device: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to control device: {str(e)}"
        )


@router.get("/status")
async def get_connection_status(
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Get LifeSmart connection status for current tenant
    """
    try:
        if not current_user.tenant_id:
            return {
                "connected": False,
                "message": "User is not associated with a tenant"
            }
        
        result = await db.execute(
            select(Tenant).where(Tenant.id == current_user.tenant_id)
        )
        tenant = result.scalar_one_or_none()
        
        if not tenant:
            return {
                "connected": False,
                "message": "Tenant not found"
            }
        
        is_connected = bool(tenant.lifesmart_app_key and tenant.lifesmart_user_id)
        
        return {
            "connected": is_connected,
            "region": tenant.lifesmart_region if is_connected else None,
            "user_id": tenant.lifesmart_user_id if is_connected else None,
            "message": "Connected to LifeSmart" if is_connected else "Not connected"
        }
        
    except Exception as e:
        logger.error(f"Failed to get connection status: {str(e)}")
        return {
            "connected": False,
            "message": f"Error: {str(e)}"
        }


@router.delete("/disconnect")
async def disconnect_lifesmart(
    db: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """
    Disconnect LifeSmart account from tenant
    """
    try:
        if not current_user.tenant_id:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="User is not associated with a tenant"
            )
        
        await db.execute(
            update(Tenant)
            .where(Tenant.id == current_user.tenant_id)
            .values(
                lifesmart_app_key=None,
                lifesmart_app_token=None,
                lifesmart_user_id=None,
                lifesmart_user_token=None,
                lifesmart_region=None,
                updated_at=datetime.utcnow()
            )
        )
        await db.commit()
        
        return {"success": True, "message": "LifeSmart account disconnected"}
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to disconnect: {str(e)}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to disconnect: {str(e)}"
        )


@router.get("/regions")
async def get_available_regions():
    """
    Get list of available LifeSmart regions
    """
    return {
        "regions": [
            {"id": "china", "name": "China", "name_ar": "الصين"},
            {"id": "global", "name": "Global", "name_ar": "عالمي"},
            {"id": "europe", "name": "Europe", "name_ar": "أوروبا"},
            {"id": "north_america", "name": "North America", "name_ar": "أمريكا الشمالية"},
            {"id": "japan", "name": "Japan", "name_ar": "اليابان"},
            {"id": "asia_pacific", "name": "Asia Pacific", "name_ar": "آسيا والمحيط الهادئ"},
        ]
    }


@router.get("/device-types")
async def get_device_types():
    """
    Get list of supported device types with their controls
    """
    return {
        "device_types": [
            {
                "type": "environment_sensor",
                "name": "Environment Sensor",
                "name_ar": "حساس بيئة",
                "icon": "Thermometer",
                "controllable": False,
                "readings": ["temperature", "humidity", "light"]
            },
            {
                "type": "motion_sensor",
                "name": "Motion Sensor",
                "name_ar": "حساس حركة",
                "icon": "Activity",
                "controllable": False,
                "readings": ["motion"]
            },
            {
                "type": "door_sensor",
                "name": "Door Sensor",
                "name_ar": "حساس باب",
                "icon": "DoorOpen",
                "controllable": False,
                "readings": ["open"]
            },
            {
                "type": "gas_sensor",
                "name": "Gas Sensor",
                "name_ar": "حساس غاز",
                "icon": "Flame",
                "controllable": False,
                "readings": ["gas_level"]
            },
            {
                "type": "smoke_sensor",
                "name": "Smoke Sensor",
                "name_ar": "حساس دخان",
                "icon": "CloudFog",
                "controllable": False,
                "readings": ["smoke_level"]
            },
            {
                "type": "water_leak_sensor",
                "name": "Water Leak Sensor",
                "name_ar": "حساس تسرب مياه",
                "icon": "Droplets",
                "controllable": False,
                "readings": ["water_leak"]
            },
            {
                "type": "switch_1gang",
                "name": "1-Gang Switch",
                "name_ar": "مفتاح 1 مخرج",
                "icon": "ToggleLeft",
                "controllable": True,
                "controls": ["on/off"]
            },
            {
                "type": "switch_2gang",
                "name": "2-Gang Switch",
                "name_ar": "مفتاح 2 مخرج",
                "icon": "ToggleLeft",
                "controllable": True,
                "controls": ["on/off x2"]
            },
            {
                "type": "switch_3gang",
                "name": "3-Gang Switch",
                "name_ar": "مفتاح 3 مخارج",
                "icon": "ToggleLeft",
                "controllable": True,
                "controls": ["on/off x3"]
            },
            {
                "type": "smart_plug",
                "name": "Smart Plug",
                "name_ar": "مقبس ذكي",
                "icon": "Plug",
                "controllable": True,
                "controls": ["on/off"],
                "readings": ["power", "voltage"]
            },
            {
                "type": "door_lock",
                "name": "Door Lock",
                "name_ar": "قفل باب ذكي",
                "icon": "Lock",
                "controllable": True,
                "controls": ["lock/unlock"]
            },
            {
                "type": "curtain_motor",
                "name": "Curtain Motor",
                "name_ar": "محرك ستائر",
                "icon": "Blinds",
                "controllable": True,
                "controls": ["open", "close", "stop", "position"]
            },
            {
                "type": "rgb_light",
                "name": "RGB Light",
                "name_ar": "إضاءة RGB",
                "icon": "Lightbulb",
                "controllable": True,
                "controls": ["on/off", "brightness", "color"]
            },
            {
                "type": "light",
                "name": "Light",
                "name_ar": "إضاءة",
                "icon": "Lightbulb",
                "controllable": True,
                "controls": ["on/off", "brightness"]
            },
            {
                "type": "dimmer",
                "name": "Dimmer",
                "name_ar": "مخفت إضاءة",
                "icon": "Sun",
                "controllable": True,
                "controls": ["on/off", "brightness"]
            },
            {
                "type": "ir_controller",
                "name": "IR Controller",
                "name_ar": "جهاز تحكم بالأشعة تحت الحمراء",
                "icon": "Radio",
                "controllable": True,
                "controls": ["send_ir"]
            },
            {
                "type": "air_conditioner",
                "name": "Air Conditioner",
                "name_ar": "مكيف هواء",
                "icon": "AirVent",
                "controllable": True,
                "controls": ["on/off", "mode", "temperature", "fan_speed"]
            },
            {
                "type": "camera",
                "name": "Camera",
                "name_ar": "كاميرا",
                "icon": "Camera",
                "controllable": False,
                "readings": ["stream"]
            }
        ]
    }
