//! Common types for Veza Rust services
//! 
//! This module defines shared types and data structures used across
//! all Veza Rust services.

use serde::{Deserialize, Serialize};
use uuid::Uuid;
use chrono::{DateTime, Utc};

/// User information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct User {
    pub id: Uuid,
    pub username: String,
    pub email: String,
    pub display_name: Option<String>,
    pub avatar_url: Option<String>,
    pub is_active: bool,
    pub is_verified: bool,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
    pub last_login: Option<DateTime<Utc>>,
}

/// Conversation information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Conversation {
    pub id: Uuid,
    pub name: String,
    pub description: Option<String>,
    pub is_private: bool,
    pub created_by: Uuid,
    pub participants: Vec<Uuid>,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
    pub last_message_at: Option<DateTime<Utc>>,
}

/// Message information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Message {
    pub id: Uuid,
    pub conversation_id: Uuid,
    pub user_id: Uuid,
    pub content: String,
    pub message_type: MessageType,
    pub reply_to: Option<Uuid>,
    pub attachments: Vec<Attachment>,
    pub reactions: Vec<Reaction>,
    pub is_edited: bool,
    pub is_deleted: bool,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

/// Message types
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum MessageType {
    Text,
    Image,
    Audio,
    Video,
    File,
    System,
    Call,
    CallEnded,
}

/// Attachment information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Attachment {
    pub id: Uuid,
    pub filename: String,
    pub mime_type: String,
    pub size: u64,
    pub url: String,
    pub thumbnail_url: Option<String>,
    pub metadata: Option<serde_json::Value>,
}

/// Reaction information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Reaction {
    pub emoji: String,
    pub count: u32,
    pub users: Vec<Uuid>,
}

/// Track information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Track {
    pub id: Uuid,
    pub title: String,
    pub artist: String,
    pub album: Option<String>,
    pub genre: Option<String>,
    pub duration: u32,
    pub file_size: u64,
    pub format: String,
    pub bitrate: u32,
    pub sample_rate: u32,
    pub file_path: String,
    pub cover_art_url: Option<String>,
    pub is_public: bool,
    pub uploaded_by: Uuid,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

/// Playlist information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Playlist {
    pub id: Uuid,
    pub name: String,
    pub description: Option<String>,
    pub is_public: bool,
    pub is_collaborative: bool,
    pub owner_id: Uuid,
    pub tracks: Vec<PlaylistTrack>,
    pub followers_count: u32,
    pub created_at: DateTime<Utc>,
    pub updated_at: DateTime<Utc>,
}

/// Playlist track information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PlaylistTrack {
    pub track_id: Uuid,
    pub position: u32,
    pub added_by: Uuid,
    pub added_at: DateTime<Utc>,
}

/// Session information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Session {
    pub id: Uuid,
    pub user_id: Uuid,
    pub token_hash: String,
    pub ip_address: Option<String>,
    pub user_agent: Option<String>,
    pub is_active: bool,
    pub created_at: DateTime<Utc>,
    pub expires_at: DateTime<Utc>,
    pub last_activity: DateTime<Utc>,
}

/// Audit log entry
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuditLog {
    pub id: Uuid,
    pub user_id: Option<Uuid>,
    pub action: String,
    pub resource_type: String,
    pub resource_id: Option<Uuid>,
    pub ip_address: Option<String>,
    pub user_agent: Option<String>,
    pub metadata: Option<serde_json::Value>,
    pub created_at: DateTime<Utc>,
}

/// API response wrapper
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ApiResponse<T> {
    pub success: bool,
    pub data: Option<T>,
    pub error: Option<ApiError>,
    pub meta: Option<ApiMeta>,
    pub timestamp: DateTime<Utc>,
}

/// API error information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ApiError {
    pub code: String,
    pub message: String,
    pub details: Option<serde_json::Value>,
}

/// API metadata
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ApiMeta {
    pub request_id: Option<String>,
    pub pagination: Option<PaginationMeta>,
    pub rate_limit: Option<RateLimitMeta>,
}

/// Pagination metadata
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PaginationMeta {
    pub page: u32,
    pub limit: u32,
    pub total: u64,
    pub total_pages: u32,
    pub has_next: bool,
    pub has_previous: bool,
    pub next_cursor: Option<String>,
    pub previous_cursor: Option<String>,
}

/// Rate limit metadata
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RateLimitMeta {
    pub limit: u32,
    pub remaining: u32,
    pub reset_time: u64,
    pub retry_after: Option<u64>,
}

/// WebSocket message types
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum WebSocketMessage {
    /// Text message
    Message {
        conversation_id: Uuid,
        content: String,
        message_type: MessageType,
        reply_to: Option<Uuid>,
    },
    /// Typing indicator
    Typing {
        conversation_id: Uuid,
        is_typing: bool,
    },
    /// Read receipt
    ReadReceipt {
        conversation_id: Uuid,
        message_id: Uuid,
    },
    /// User presence
    Presence {
        status: PresenceStatus,
        last_seen: DateTime<Utc>,
    },
    /// Call invitation
    CallInvite {
        conversation_id: Uuid,
        call_type: CallType,
    },
    /// Call response
    CallResponse {
        conversation_id: Uuid,
        accepted: bool,
    },
    /// Call end
    CallEnd {
        conversation_id: Uuid,
        duration: u32,
    },
    /// Error message
    Error {
        code: String,
        message: String,
    },
    /// Ping/Pong for keepalive
    Ping,
    Pong,
}

/// Presence status
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum PresenceStatus {
    Online,
    Away,
    Busy,
    Offline,
}

/// Call types
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CallType {
    Audio,
    Video,
    ScreenShare,
}

/// Streaming request
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StreamingRequest {
    pub track_id: Uuid,
    pub user_id: Uuid,
    pub quality: StreamingQuality,
    pub start_position: Option<u32>,
    pub token: String,
    pub expires_at: DateTime<Utc>,
}

/// Streaming quality
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum StreamingQuality {
    Low,    // 128kbps
    Medium, // 256kbps
    High,   // 320kbps
    Lossless, // FLAC
}

/// Streaming response
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StreamingResponse {
    pub stream_url: String,
    pub expires_at: DateTime<Utc>,
    pub quality: StreamingQuality,
    pub bitrate: u32,
    pub sample_rate: u32,
    pub duration: u32,
}

/// Audio chunk information
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AudioChunk {
    pub track_id: Uuid,
    pub chunk_index: u32,
    pub data: Vec<u8>,
    pub duration: u32,
    pub is_last: bool,
}

/// Cache entry
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CacheEntry<T> {
    pub key: String,
    pub value: T,
    pub expires_at: Option<DateTime<Utc>>,
    pub created_at: DateTime<Utc>,
}

/// Health check response
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HealthCheck {
    pub status: HealthStatus,
    pub service: String,
    pub version: String,
    pub uptime: u64,
    pub dependencies: Vec<DependencyHealth>,
    pub timestamp: DateTime<Utc>,
}

/// Health status
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum HealthStatus {
    Healthy,
    Degraded,
    Unhealthy,
}

/// Dependency health
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DependencyHealth {
    pub name: String,
    pub status: HealthStatus,
    pub response_time: Option<u64>,
    pub error: Option<String>,
}

/// Metrics data
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Metrics {
    pub counters: std::collections::HashMap<String, u64>,
    pub gauges: std::collections::HashMap<String, f64>,
    pub histograms: std::collections::HashMap<String, Vec<f64>>,
    pub timestamp: DateTime<Utc>,
}

/// Configuration validation error
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConfigValidationError {
    pub field: String,
    pub message: String,
    pub value: Option<serde_json::Value>,
}

/// Database migration
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Migration {
    pub version: String,
    pub name: String,
    pub up_sql: String,
    pub down_sql: String,
    pub applied_at: Option<DateTime<Utc>>,
}

/// File upload request
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileUploadRequest {
    pub filename: String,
    pub mime_type: String,
    pub size: u64,
    pub content: Vec<u8>,
    pub metadata: Option<serde_json::Value>,
}

/// File upload response
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileUploadResponse {
    pub file_id: Uuid,
    pub url: String,
    pub thumbnail_url: Option<String>,
    pub metadata: FileMetadata,
}

/// File metadata
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileMetadata {
    pub id: Uuid,
    pub filename: String,
    pub mime_type: String,
    pub size: u64,
    pub hash: String,
    pub url: String,
    pub thumbnail_url: Option<String>,
    pub uploaded_by: Uuid,
    pub created_at: DateTime<Utc>,
}

/// Search request
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SearchRequest {
    pub query: String,
    pub filters: Option<SearchFilters>,
    pub pagination: Option<PaginationRequest>,
    pub sort: Option<SearchSort>,
}

/// Search filters
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SearchFilters {
    pub types: Option<Vec<String>>,
    pub date_range: Option<DateRange>,
    pub user_id: Option<Uuid>,
    pub tags: Option<Vec<String>>,
}

/// Date range
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DateRange {
    pub start: DateTime<Utc>,
    pub end: DateTime<Utc>,
}

/// Pagination request
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PaginationRequest {
    pub page: u32,
    pub limit: u32,
    pub cursor: Option<String>,
}

/// Search sort
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SearchSort {
    pub field: String,
    pub order: SortOrder,
}

/// Sort order
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SortOrder {
    Asc,
    Desc,
}

/// Search response
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SearchResponse<T> {
    pub results: Vec<T>,
    pub total: u64,
    pub pagination: PaginationMeta,
    pub facets: Option<serde_json::Value>,
    pub suggestions: Option<Vec<String>>,
}
