"""
Endpoints API pour le suivi d'équipements (Wake-on-LAN, shutdown, etc.)
"""
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import List, Optional
from datetime import datetime
from pydantic import BaseModel

from backend.app.core.database import get_db
from backend.app.models.ip import IP

router = APIRouter(prefix="/api/tracking", tags=["Tracking"])


# Schémas Pydantic
class IPTrackingResponse(BaseModel):
    """Schéma de réponse pour les IPs suivies"""
    ip: str
    name: Optional[str]
    known: bool
    tracked: bool
    location: Optional[str]
    host: Optional[str]
    last_status: Optional[str]
    mac: Optional[str]
    vendor: Optional[str]
    hostname: Optional[str]
    link: Optional[str]
    last_seen: Optional[datetime]
    open_ports: List[int]

    class Config:
        from_attributes = True


class WOLResponse(BaseModel):
    """Réponse après envoi Wake-on-LAN"""
    message: str
    ip: str
    mac: str
    success: bool


class ShutdownResponse(BaseModel):
    """Réponse après commande d'arrêt"""
    message: str
    ip: str
    success: bool


@router.get("/", response_model=List[IPTrackingResponse])
async def get_tracked_ips(db: Session = Depends(get_db)):
    """
    Récupère toutes les IPs marquées comme suivies
    Retourne la liste des équipements avec leur état actuel
    """
    tracked_ips = db.query(IP).filter(IP.tracked == True).order_by(IP.name, IP.ip).all()
    return tracked_ips


@router.post("/wol/{ip_address}", response_model=WOLResponse)
async def wake_on_lan(ip_address: str, db: Session = Depends(get_db)):
    """
    Envoie un paquet Magic Packet Wake-on-LAN à l'équipement
    Nécessite que l'IP ait une adresse MAC enregistrée
    """
    # Récupérer l'IP depuis la base
    ip_obj = db.query(IP).filter(IP.ip == ip_address).first()

    if not ip_obj:
        raise HTTPException(
            status_code=404,
            detail=f"IP {ip_address} non trouvée dans la base de données"
        )

    if not ip_obj.mac:
        raise HTTPException(
            status_code=400,
            detail=f"Adresse MAC manquante pour {ip_address}. Impossible d'envoyer le paquet WOL."
        )

    try:
        # Importer la bibliothèque wakeonlan
        from wakeonlan import send_magic_packet

        # Envoyer le paquet Magic Packet
        send_magic_packet(ip_obj.mac)

        return WOLResponse(
            message=f"Paquet Wake-on-LAN envoyé avec succès",
            ip=ip_address,
            mac=ip_obj.mac,
            success=True
        )

    except ImportError:
        raise HTTPException(
            status_code=500,
            detail="La bibliothèque 'wakeonlan' n'est pas installée. Exécutez: pip install wakeonlan"
        )
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Erreur lors de l'envoi du paquet WOL: {str(e)}"
        )


@router.post("/shutdown/{ip_address}", response_model=ShutdownResponse)
async def shutdown_device(ip_address: str, db: Session = Depends(get_db)):
    """
    Envoie une commande shutdown via MQTT à l'équipement
    """
    # Récupérer l'IP depuis la base
    ip_obj = db.query(IP).filter(IP.ip == ip_address).first()

    if not ip_obj:
        raise HTTPException(
            status_code=404,
            detail=f"IP {ip_address} non trouvée dans la base de données"
        )

    if ip_obj.last_status != "online":
        raise HTTPException(
            status_code=400,
            detail=f"L'équipement {ip_address} est déjà hors ligne"
        )

    try:
        from backend.app.services.mqtt_client import send_mqtt_command

        # Envoyer commande shutdown via MQTT
        success = send_mqtt_command(ip_address, "shutdown")

        if success:
            return ShutdownResponse(
                message=f"Commande shutdown envoyée à {ip_address} via MQTT",
                ip=ip_address,
                success=True
            )
        else:
            raise HTTPException(
                status_code=500,
                detail="Échec de l'envoi de la commande MQTT"
            )

    except ImportError:
        raise HTTPException(
            status_code=500,
            detail="Le service MQTT n'est pas configuré. Consultez mqtt/docs/README.md"
        )
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Erreur lors de l'envoi de la commande: {str(e)}"
        )


@router.post("/reboot/{ip_address}", response_model=ShutdownResponse)
async def reboot_device(ip_address: str, db: Session = Depends(get_db)):
    """
    Envoie une commande reboot via MQTT à l'équipement
    """
    # Récupérer l'IP depuis la base
    ip_obj = db.query(IP).filter(IP.ip == ip_address).first()

    if not ip_obj:
        raise HTTPException(
            status_code=404,
            detail=f"IP {ip_address} non trouvée"
        )

    if ip_obj.last_status != "online":
        raise HTTPException(
            status_code=400,
            detail=f"L'équipement {ip_address} est hors ligne"
        )

    try:
        from backend.app.services.mqtt_client import send_mqtt_command

        # Envoyer commande reboot via MQTT
        success = send_mqtt_command(ip_address, "reboot")

        if success:
            return ShutdownResponse(
                message=f"Commande reboot envoyée à {ip_address} via MQTT",
                ip=ip_address,
                success=True
            )
        else:
            raise HTTPException(
                status_code=500,
                detail="Échec de l'envoi de la commande MQTT"
            )

    except ImportError:
        raise HTTPException(
            status_code=500,
            detail="Le service MQTT n'est pas configuré"
        )
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"Erreur: {str(e)}"
        )


@router.patch("/{ip_address}/toggle", response_model=IPTrackingResponse)
async def toggle_tracking(ip_address: str, db: Session = Depends(get_db)):
    """
    Bascule l'état de suivi d'une IP (tracked true/false)
    """
    ip_obj = db.query(IP).filter(IP.ip == ip_address).first()

    if not ip_obj:
        raise HTTPException(
            status_code=404,
            detail=f"IP {ip_address} non trouvée"
        )

    # Inverser l'état tracked
    ip_obj.tracked = not ip_obj.tracked
    db.commit()
    db.refresh(ip_obj)

    return ip_obj
