//! Documentation OpenAPI et DTOs pour l'API ControlPoint
//!
//! Ce module fournit les types de réponse / payloads pour l'API REST du ControlPoint,
//! ainsi que la documentation OpenAPI via `utoipa`.

#[cfg(feature = "pmoserver")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "pmoserver")]
use utoipa::{OpenApi, ToSchema};

// ============================================================================
// RENDERERS
// ============================================================================

/// Résumé d'un renderer découvert
#[cfg(feature = "pmoserver")]
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct RendererSummary {
    /// ID unique du renderer
    pub id: String,
    /// Nom convivial
    pub friendly_name: String,
    /// Modèle du renderer
    pub model_name: String,
    /// Protocole (Upnp, Hybrid, etc.)
    pub protocol: String,
    /// Renderer en ligne
    pub online: bool,
}

/// État détaillé d'un renderer
#[cfg(feature = "pmoserver")]
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct RendererState {
    /// ID unique du renderer
    pub id: String,
    /// Nom convivial
    pub friendly_name: String,
    /// État de transport ("PLAYING", "PAUSED", "STOPPED", etc.)
    pub transport_state: String,
    /// Position courante en millisecondes
    pub position_ms: Option<u64>,
    /// Durée totale en millisecondes
    pub duration_ms: Option<u64>,
    /// Volume (0-100)
    pub volume: Option<u8>,
    /// Mute actif
    pub mute: Option<bool>,
    /// Nombre d'items dans la queue
    pub queue_len: usize,
    /// Playlist attachée (si applicable)
    pub attached_playlist: Option<AttachedPlaylistInfo>,
}

/// Information sur la playlist attachée
#[cfg(feature = "pmoserver")]
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct AttachedPlaylistInfo {
    /// ID du serveur de médias
    pub server_id: String,
    /// ID du container playlist
    pub container_id: String,
    /// True si au moins une mise à jour a été vue
    pub has_seen_update: bool,
}

// ============================================================================
// QUEUE
// ============================================================================

/// Item de la queue de lecture
#[cfg(feature = "pmoserver")]
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct QueueItem {
    /// Index dans la queue (0-based)
    pub index: usize,
    /// URI de la ressource
    pub uri: String,
    /// Titre du morceau
    pub title: Option<String>,
    /// Artiste
    pub artist: Option<String>,
    /// Album
    pub album: Option<String>,
    /// ID du serveur source
    pub server_id: Option<String>,
    /// ID de l'objet DIDL-Lite
    pub object_id: Option<String>,
}

/// Snapshot de la queue d'un renderer
#[cfg(feature = "pmoserver")]
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct QueueSnapshot {
    /// ID du renderer
    pub renderer_id: String,
    /// Items de la queue
    pub items: Vec<QueueItem>,
}

// ============================================================================
// MEDIA SERVERS
// ============================================================================

/// Résumé d'un serveur de médias découvert
#[cfg(feature = "pmoserver")]
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct MediaServerSummary {
    /// ID unique du serveur
    pub id: String,
    /// Nom convivial
    pub friendly_name: String,
    /// Modèle du serveur
    pub model_name: String,
    /// Serveur en ligne
    pub online: bool,
}

/// Entrée de navigation (container ou item)
#[cfg(feature = "pmoserver")]
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct ContainerEntry {
    /// ID de l'objet
    pub id: String,
    /// Titre
    pub title: String,
    /// Classe UPnP (object.container.*, object.item.*, etc.)
    pub class: String,
    /// True si c'est un container (navigable)
    pub is_container: bool,
    /// Nombre d'enfants (si container)
    pub child_count: Option<u32>,
    /// Artiste (si item audio)
    pub artist: Option<String>,
    /// Album (si item audio)
    pub album: Option<String>,
    /// URI de la pochette d'album
    pub album_art_uri: Option<String>,
}

/// Résultat de navigation dans un container
#[cfg(feature = "pmoserver")]
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct BrowseResponse {
    /// ID du container browsé
    pub container_id: String,
    /// Entrées du container
    pub entries: Vec<ContainerEntry>,
}

// ============================================================================
// PAYLOADS DE COMMANDES
// ============================================================================

/// Requête pour définir le volume
#[cfg(feature = "pmoserver")]
#[derive(Debug, Clone, Deserialize, ToSchema)]
pub struct VolumeSetRequest {
    /// Nouveau volume (0-100)
    pub volume: u8,
}

/// Requête pour attacher une playlist
#[cfg(feature = "pmoserver")]
#[derive(Debug, Clone, Deserialize, ToSchema)]
pub struct AttachPlaylistRequest {
    /// ID du serveur de médias
    pub server_id: String,
    /// ID du container playlist
    pub container_id: String,
}

/// Réponse générique de succès
#[cfg(feature = "pmoserver")]
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct SuccessResponse {
    /// Message de succès
    pub message: String,
}

/// Réponse d'erreur
#[cfg(feature = "pmoserver")]
#[derive(Debug, Clone, Serialize, ToSchema)]
pub struct ErrorResponse {
    /// Message d'erreur
    pub error: String,
}

// ============================================================================
// DOCUMENTATION OPENAPI
// ============================================================================

/// Documentation OpenAPI pour l'API ControlPoint
#[cfg(feature = "pmoserver")]
#[derive(OpenApi)]
#[openapi(
    info(
        title = "PMOMusic Control Point API",
        version = "1.0.0",
        description = r#"
# API REST pour le Control Point PMOMusic

Cette API permet de contrôler les renderers UPnP et de naviguer dans les serveurs de médias.

## Fonctionnalités

### Renderers
- **Découverte** : Liste des renderers disponibles
- **État** : Récupération de l'état détaillé d'un renderer
- **Contrôle transport** : Play, pause, stop, next
- **Contrôle volume** : Lecture et modification du volume / mute
- **Queue** : Gestion de la queue de lecture

### Playlists
- **Binding** : Attachement de la queue à un container playlist d'un serveur
- **Synchronisation automatique** : Mise à jour de la queue lors des changements côté serveur

### Serveurs de médias
- **Découverte** : Liste des serveurs disponibles
- **Navigation** : Exploration de la hiérarchie des containers

## Architecture

Le Control Point PMOMusic est un point de contrôle UPnP qui :
1. Découvre automatiquement les renderers et serveurs via SSDP
2. Maintient un registre des devices actifs
3. Permet le contrôle unifié des renderers (UPnP AV, LinkPlay, Arylic TCP)
4. Gère une queue de lecture locale avec synchronisation optionnelle

## Exemples d'utilisation

### Lister les renderers
```
GET /control/renderers
```

### Contrôler un renderer
```
POST /control/renderers/{renderer_id}/play
POST /control/renderers/{renderer_id}/pause
POST /control/renderers/{renderer_id}/volume/set
  Body: {"volume": 50}
```

### Attacher une playlist
```
POST /control/renderers/{renderer_id}/binding/attach
  Body: {
    "server_id": "uuid:...",
    "container_id": "0$/Music/MyPlaylist"
  }
```

### Naviguer dans un serveur
```
GET /control/servers/{server_id}/containers/{container_id}
```
        "#,
        contact(
            name = "PMOMusic",
        ),
        license(
            name = "MIT",
        ),
    ),
    paths(
        crate::pmoserver_ext::list_renderers,
        crate::pmoserver_ext::get_renderer_state,
        crate::pmoserver_ext::get_renderer_queue,
        crate::pmoserver_ext::get_renderer_binding,
        crate::pmoserver_ext::play_renderer,
        crate::pmoserver_ext::pause_renderer,
        crate::pmoserver_ext::stop_renderer,
        crate::pmoserver_ext::next_renderer,
        crate::pmoserver_ext::set_renderer_volume,
        crate::pmoserver_ext::volume_up_renderer,
        crate::pmoserver_ext::volume_down_renderer,
        crate::pmoserver_ext::toggle_mute_renderer,
        crate::pmoserver_ext::attach_playlist_binding,
        crate::pmoserver_ext::detach_playlist_binding,
        crate::pmoserver_ext::list_servers,
        crate::pmoserver_ext::browse_container,
        crate::sse::all_events_sse,
        crate::sse::renderer_events_sse,
        crate::sse::media_server_events_sse,
    ),
    components(schemas(
        RendererSummary,
        RendererState,
        AttachedPlaylistInfo,
        QueueItem,
        QueueSnapshot,
        MediaServerSummary,
        ContainerEntry,
        BrowseResponse,
        VolumeSetRequest,
        AttachPlaylistRequest,
        SuccessResponse,
        ErrorResponse,
    )),
    tags(
        (name = "control", description = "Contrôle des renderers et navigation des serveurs")
    )
)]
pub struct ApiDoc;
