"""
Routes API pour la synchronisation des configurations Admin -> Mobile
Permet aux applications mobiles de récupérer les configurations à jour
"""

from fastapi import APIRouter, Depends, HTTPException, WebSocket, WebSocketDisconnect
from sqlalchemy.orm import Session
from typing import Dict, Any
from datetime import datetime

from core.database import get_db
from core.websocket_manager import manager

router = APIRouter()


# ==================== WebSocket Endpoint ====================

@router.websocket("/ws/mobile/{client_id}")
async def websocket_mobile_endpoint(websocket: WebSocket, client_id: str):
    """
    WebSocket pour les applications mobiles
    Permet de recevoir les notifications de mise à jour en temps réel
    """
    await manager.connect(websocket, "mobile")
    
    try:
        # Envoyer les versions actuelles des configurations
        versions = manager.get_all_config_versions()
        await websocket.send_json({
            "type": "connection_established",
            "client_id": client_id,
            "config_versions": versions,
            "timestamp": datetime.now().isoformat()
        })
        
        # Maintenir la connexion ouverte
        while True:
            # Recevoir les messages du client (heartbeat, etc.)
            data = await websocket.receive_text()
            
            # Répondre au heartbeat
            if data == "ping":
                await websocket.send_text("pong")
    
    except WebSocketDisconnect:
        manager.disconnect(websocket, "mobile")
        print(f"Client {client_id} déconnecté")


# ==================== Configuration Endpoints ====================

@router.get("/config/versions")
async def get_config_versions():
    """
    Récupérer les versions de toutes les configurations
    Permet à l'app mobile de vérifier si elle doit mettre à jour
    """
    return {
        "success": True,
        "versions": manager.get_all_config_versions(),
        "timestamp": datetime.now().isoformat()
    }


@router.get("/config/commissions")
async def get_commission_config(db: Session = Depends(get_db)):
    """
    Récupérer la configuration des commissions
    - Commission TIM BUSINESS sur recharges
    - Commission CinetPay
    - Commission déblocage compte
    - Taux d'intérêt prêts SOS
    """
    # TODO: Récupérer depuis la base de données
    config = {
        "tim_business_commission": 2.0,  # 2% sur recharges
        "cinetpay_commission": 0.5,      # 0.5% sur recharges CinetPay
        "account_unlock_commission": 15.0,  # 15% déblocage compte
        "loan_interest_rate": 6.0,       # 6% intérêt prêt SOS
        "loan_penalty_rate": 2.0,        # 2% pénalité retard par jour
        "updated_at": datetime.now().isoformat()
    }
    
    version_data = manager.get_config_version("commissions")
    
    return {
        "success": True,
        "data": config,
        "version": version_data.get("version", datetime.now().isoformat())
    }


@router.get("/config/advertisements")
async def get_active_advertisements(db: Session = Depends(get_db)):
    """
    Récupérer toutes les publicités actives pour l'application mobile
    Filtrées par pays/ville de l'utilisateur
    """
    # TODO: Récupérer depuis la base de données
    # Filtrer par is_active = True et dates valides
    
    advertisements = []
    
    return {
        "success": True,
        "data": advertisements,
        "count": len(advertisements),
        "version": manager.get_config_version("advertisements").get("version", datetime.now().isoformat())
    }


@router.get("/config/loan-settings")
async def get_loan_settings(db: Session = Depends(get_db)):
    """
    Récupérer les paramètres des prêts SOS
    - Montants min/max par type de compte
    - Durées de remboursement
    - Taux d'intérêt
    """
    config = {
        "tim_mini": {
            "min_amount": 5000,
            "max_amount": 25000,
            "duration_days": 3,
            "interest_rate": 6.0
        },
        "tim_maxi": {
            "min_amount": 10000,
            "max_amount": 100000,
            "duration_days": 3,
            "interest_rate": 6.0
        },
        "tim_business": {
            "min_amount": 50000,
            "max_amount": 500000,
            "duration_days": 7,
            "interest_rate": 6.0
        },
        "penalty_rate_per_day": 2.0,
        "max_active_loans": 1,
        "updated_at": datetime.now().isoformat()
    }
    
    return {
        "success": True,
        "data": config,
        "version": manager.get_config_version("loan_settings").get("version", datetime.now().isoformat())
    }


@router.get("/config/account-limits")
async def get_account_limits(db: Session = Depends(get_db)):
    """
    Récupérer les limites de compte par type
    """
    config = {
        "tim_mini": {
            "max_balance": 2000000,  # 2M FCFA
            "daily_transaction_limit": 100000,
            "monthly_transaction_limit": 2000000,
            "nfc_daily_limit": 50000
        },
        "tim_maxi": {
            "max_balance": 2000000,  # 2M FCFA
            "daily_transaction_limit": 1000000,
            "monthly_transaction_limit": 20000000,
            "nfc_daily_limit": 500000
        },
        "tim_business": {
            "max_balance": -1,  # Illimité
            "daily_transaction_limit": -1,
            "monthly_transaction_limit": -1,
            "nfc_daily_limit": 2000000
        },
        "updated_at": datetime.now().isoformat()
    }
    
    return {
        "success": True,
        "data": config,
        "version": manager.get_config_version("account_limits").get("version", datetime.now().isoformat())
    }


@router.get("/config/nfc-settings")
async def get_nfc_settings(db: Session = Depends(get_db)):
    """
    Récupérer les paramètres NFC
    """
    config = {
        "enabled": True,
        "security_level": "high",  # low, medium, high
        "require_pin_above": 50000,  # Montant nécessitant PIN
        "daily_limit_default": 500000,
        "transaction_timeout_seconds": 30,
        "max_retry_attempts": 3,
        "updated_at": datetime.now().isoformat()
    }
    
    return {
        "success": True,
        "data": config,
        "version": manager.get_config_version("nfc_settings").get("version", datetime.now().isoformat())
    }


@router.get("/config/app-settings")
async def get_app_settings(db: Session = Depends(get_db)):
    """
    Récupérer les paramètres généraux de l'application
    """
    config = {
        "maintenance_mode": False,
        "force_update": False,
        "min_app_version": "1.0.0",
        "latest_app_version": "1.0.0",
        "features": {
            "nfc_payments": True,
            "loan_sos": True,
            "tim_business": True,
            "cinetpay_recharge": True,
            "bank_transfer": True
        },
        "support": {
            "phone": "+225 07 00 00 00 00",
            "email": "support@timcash.ci",
            "whatsapp": "+225 07 00 00 00 00"
        },
        "updated_at": datetime.now().isoformat()
    }
    
    return {
        "success": True,
        "data": config,
        "version": manager.get_config_version("app_settings").get("version", datetime.now().isoformat())
    }


# ==================== Admin Endpoints (Trigger Updates) ====================

@router.post("/admin/update-commissions")
async def admin_update_commissions(commission_data: Dict[str, Any], db: Session = Depends(get_db)):
    """
    [ADMIN] Mettre à jour les taux de commission
    Notifie automatiquement toutes les apps mobiles
    """
    # TODO: Sauvegarder dans la base de données
    
    # Notifier toutes les applications mobiles
    await manager.notify_commission_update(commission_data)
    
    return {
        "success": True,
        "message": "Commissions mises à jour et diffusées aux applications mobiles",
        "notified_clients": len(manager.active_connections.get("mobile", set()))
    }


@router.post("/admin/update-advertisement")
async def admin_update_advertisement(ad_data: Dict[str, Any], action: str = "create", db: Session = Depends(get_db)):
    """
    [ADMIN] Créer/Modifier/Supprimer une publicité
    Notifie automatiquement toutes les apps mobiles
    
    Actions: create, update, delete, activate, deactivate
    """
    # TODO: Sauvegarder dans la base de données
    
    # Notifier toutes les applications mobiles
    await manager.notify_advertisement_update(ad_data, action)
    
    return {
        "success": True,
        "message": f"Publicité {action} et diffusée aux applications mobiles",
        "notified_clients": len(manager.active_connections.get("mobile", set()))
    }


@router.post("/admin/update-loan-settings")
async def admin_update_loan_settings(loan_data: Dict[str, Any], db: Session = Depends(get_db)):
    """
    [ADMIN] Mettre à jour les paramètres de prêt
    Notifie automatiquement toutes les apps mobiles
    """
    # TODO: Sauvegarder dans la base de données
    
    # Notifier toutes les applications mobiles
    await manager.notify_loan_settings_update(loan_data)
    
    return {
        "success": True,
        "message": "Paramètres de prêt mis à jour et diffusés aux applications mobiles",
        "notified_clients": len(manager.active_connections.get("mobile", set()))
    }


@router.post("/admin/update-account-limits")
async def admin_update_account_limits(limits_data: Dict[str, Any], db: Session = Depends(get_db)):
    """
    [ADMIN] Mettre à jour les limites de compte
    Notifie automatiquement toutes les apps mobiles
    """
    # TODO: Sauvegarder dans la base de données
    
    # Notifier toutes les applications mobiles
    await manager.notify_account_limits_update(limits_data)
    
    return {
        "success": True,
        "message": "Limites de compte mises à jour et diffusées aux applications mobiles",
        "notified_clients": len(manager.active_connections.get("mobile", set()))
    }


@router.post("/admin/update-nfc-settings")
async def admin_update_nfc_settings(nfc_data: Dict[str, Any], db: Session = Depends(get_db)):
    """
    [ADMIN] Mettre à jour les paramètres NFC
    Notifie automatiquement toutes les apps mobiles
    """
    # TODO: Sauvegarder dans la base de données
    
    # Notifier toutes les applications mobiles
    await manager.notify_nfc_settings_update(nfc_data)
    
    return {
        "success": True,
        "message": "Paramètres NFC mis à jour et diffusés aux applications mobiles",
        "notified_clients": len(manager.active_connections.get("mobile", set()))
    }
