use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
use sqlx::FromRow;
use uuid::Uuid;

use super::{BaseFields, ConversationType};

/// Message thread/conversation
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct Conversation {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub subject: Option<String>,
    pub conversation_type: ConversationType,
    /// Entity this conversation is about (polymorphic)
    pub entity_type: Option<String>,
    pub entity_id: Option<Uuid>,
    /// Who created the conversation (polymorphic)
    pub created_by_type: Option<String>,
    pub created_by_id: Option<Uuid>,
    pub last_message_at: Option<DateTime<Utc>>,
    pub is_archived: bool,
    pub metadata: Option<JsonValue>,
}

/// User participation in a conversation
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct ConversationParticipant {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub conversation_id: Uuid,
    /// Participant type (team_profile or customer_profile)
    pub participant_type: String,
    pub participant_id: Uuid,
    pub last_read_at: Option<DateTime<Utc>>,
    /// Count of unread messages for this participant
    pub unread_count: i32,
    /// Whether notifications are muted
    pub is_muted: bool,
    /// User-specific archive (separate from conversation.is_archived)
    pub is_archived: bool,
    /// When the participant joined the conversation
    pub joined_at: DateTime<Utc>,
}

impl ConversationParticipant {
    /// Check if participant has unread messages
    pub fn has_unread(&self) -> bool {
        self.unread_count > 0
    }
}

/// Individual message in a conversation
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct Message {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub conversation_id: Uuid,
    /// Author type (team_profile or customer_profile)
    pub author_type: String,
    pub author_id: Uuid,
    pub content: String,
    pub is_deleted: bool,
    /// For threaded replies
    pub reply_to_id: Option<Uuid>,
    /// File attachments (JSONB array of attachment metadata)
    pub attachments: Option<JsonValue>,
    /// System-generated message (e.g., "User joined conversation")
    pub is_system_message: bool,
    /// Additional metadata (formatting, mentions, etc.)
    pub metadata: Option<JsonValue>,
}

/// Tracks when specific messages are read by specific participants
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct MessageReadReceipt {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub message_id: Uuid,
    /// Reader type (team_profile or customer_profile)
    pub reader_type: String,
    pub reader_id: Uuid,
    pub read_at: DateTime<Utc>,
}
