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

use super::{BaseFields, DeliveryStatus, NotificationChannel, NotificationStatus};

/// Admin-defined rule for triggering notifications
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct NotificationRule {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub name: String,
    pub description: Option<String>,
    pub is_active: bool,
    /// Event types that trigger this rule (stored as JSONB array of strings)
    pub event_types: JsonValue,
    /// Channels to deliver through (stored as JSONB array of strings)
    pub channels: JsonValue,
    /// Target roles (stored as JSONB array of strings)
    pub target_roles: Option<JsonValue>,
    /// Custom conditions for triggering (JSONB)
    pub conditions: Option<JsonValue>,
    /// Notification subject template
    pub subject_template: Option<String>,
    /// Notification body template
    pub body_template: Option<String>,
}

/// Individual notification instance
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct Notification {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    /// Recipient type (team_profile or customer_profile)
    pub recipient_type: String,
    pub recipient_id: Uuid,
    /// The rule that triggered this notification (optional for system notifications)
    pub rule_id: Option<Uuid>,
    /// The event that triggered this notification
    pub event_id: Option<Uuid>,
    pub status: NotificationStatus,
    pub subject: String,
    pub body: String,
    /// URL to navigate to when notification is clicked
    pub action_url: Option<String>,
    pub read_at: Option<DateTime<Utc>>,
    pub metadata: Option<JsonValue>,
}

/// Tracks delivery attempts per channel
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct NotificationDelivery {
    #[sqlx(flatten)]
    #[serde(flatten)]
    pub base: BaseFields,
    pub notification_id: Uuid,
    pub channel: NotificationChannel,
    pub status: DeliveryStatus,
    pub attempts: i32,
    pub last_attempt_at: Option<DateTime<Utc>>,
    pub sent_at: Option<DateTime<Utc>>,
    pub delivered_at: Option<DateTime<Utc>>,
    pub error_message: Option<String>,
    /// External service ID (e.g., email provider message ID)
    pub external_id: Option<String>,
    pub metadata: Option<JsonValue>,
}

/// Many-to-many: NotificationRule targets specific TeamProfiles
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct NotificationRuleTeamProfile {
    pub id: Uuid,
    pub rule_id: Uuid,
    pub team_profile_id: Uuid,
    pub created_at: DateTime<Utc>,
}

/// Many-to-many: NotificationRule targets specific CustomerProfiles
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct NotificationRuleCustomerProfile {
    pub id: Uuid,
    pub rule_id: Uuid,
    pub customer_profile_id: Uuid,
    pub created_at: DateTime<Utc>,
}
