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

/// Event types for the audit trail system
/// Organized by entity category for clarity
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, sqlx::Type)]
#[sqlx(type_name = "event_type", rename_all = "SCREAMING_SNAKE_CASE")]
pub enum EventType {
    // ==================== CUSTOMER EVENTS ====================
    CustomerCreated,
    CustomerUpdated,
    CustomerDeleted,
    CustomerStatusChanged,
    CustomerAddressCreated,
    CustomerAddressUpdated,
    CustomerAddressDeleted,
    CustomerContactCreated,
    CustomerContactUpdated,
    CustomerContactDeleted,

    // ==================== ACCOUNT EVENTS ====================
    AccountCreated,
    AccountUpdated,
    AccountDeleted,
    AccountStatusChanged,
    AccountAddressCreated,
    AccountAddressUpdated,
    AccountAddressDeleted,
    AccountAddressPrimaryChanged,
    AccountContactCreated,
    AccountContactUpdated,
    AccountContactDeleted,
    AccountContactPrimaryChanged,

    // ==================== SERVICE EVENTS ====================
    ServiceCreated,
    ServiceUpdated,
    ServiceDeleted,
    ServiceStatusChanged,
    ServiceAssigned,
    ServiceUnassigned,
    ServiceRescheduled,

    // ==================== PROJECT EVENTS ====================
    ProjectCreated,
    ProjectUpdated,
    ProjectDeleted,
    ProjectStatusChanged,
    ProjectAssigned,
    ProjectUnassigned,
    ProjectRescheduled,
    ProjectAmountChanged,

    // ==================== SCHEDULE EVENTS ====================
    ScheduleCreated,
    ScheduleUpdated,
    ScheduleDeleted,
    ScheduleFrequencyChanged,

    // ==================== SESSION EVENTS ====================
    ServiceSessionStarted,
    ServiceSessionEnded,
    ServiceSessionReverted,
    ProjectSessionStarted,
    ProjectSessionEnded,
    ProjectSessionReverted,

    // ==================== SESSION MEDIA EVENTS ====================
    SessionNoteCreated,
    SessionNoteUpdated,
    SessionNoteDeleted,
    SessionImageUploaded,
    SessionImageUpdated,
    SessionImageDeleted,
    SessionVideoUploaded,
    SessionVideoUpdated,
    SessionVideoDeleted,
    SessionMediaInternalFlagged,

    // ==================== TASK EVENTS ====================
    ServiceTaskCompleted,
    ServiceTaskUncompleted,
    ProjectTaskCompleted,
    ProjectTaskUncompleted,

    // ==================== SCOPE EVENTS ====================
    ServiceScopeCreated,
    ServiceScopeUpdated,
    ServiceScopeDeleted,
    ServiceScopeActivated,
    ServiceScopeDeactivated,
    ServiceScopeAreaCreated,
    ServiceScopeAreaUpdated,
    ServiceScopeAreaDeleted,
    ServiceScopeTaskCreated,
    ServiceScopeTaskUpdated,
    ServiceScopeTaskDeleted,

    ProjectScopeCreated,
    ProjectScopeUpdated,
    ProjectScopeDeleted,
    ProjectScopeActivated,
    ProjectScopeDeactivated,
    ProjectScopeCategoryCreated,
    ProjectScopeCategoryUpdated,
    ProjectScopeCategoryDeleted,
    ProjectScopeTaskCreated,
    ProjectScopeTaskUpdated,
    ProjectScopeTaskDeleted,

    // ==================== SCOPE TEMPLATE EVENTS ====================
    ScopeTemplateCreated,
    ScopeTemplateUpdated,
    ScopeTemplateDeleted,
    ScopeTemplateActivated,
    ScopeTemplateDeactivated,
    ScopeTemplateInstantiated,

    // ==================== PROFILE EVENTS ====================
    TeamProfileCreated,
    TeamProfileUpdated,
    TeamProfileDeleted,
    TeamProfileRoleChanged,
    TeamProfileStatusChanged,
    CustomerProfileCreated,
    CustomerProfileUpdated,
    CustomerProfileDeleted,
    CustomerProfileStatusChanged,
    CustomerProfileAccessGranted,
    CustomerProfileAccessRevoked,

    // ==================== FINANCIAL EVENTS ====================
    LaborCreated,
    LaborUpdated,
    LaborDeleted,
    LaborRateChanged,
    RevenueCreated,
    RevenueUpdated,
    RevenueDeleted,
    RevenueAmountChanged,
    InvoiceCreated,
    InvoiceUpdated,
    InvoiceDeleted,
    InvoiceStatusChanged,
    InvoiceSent,
    InvoicePaid,
    InvoiceOverdue,

    // ==================== REPORT EVENTS ====================
    ReportCreated,
    ReportUpdated,
    ReportDeleted,
    ReportSubmitted,
    ReportApproved,

    // ==================== CONVERSATION EVENTS ====================
    ConversationCreated,
    ConversationUpdated,
    ConversationArchived,
    ConversationUnarchived,
    ConversationParticipantAdded,
    ConversationParticipantRemoved,

    // ==================== MESSAGE EVENTS ====================
    MessageSent,
    MessageUpdated,
    MessageDeleted,
    MessageRead,

    // ==================== NOTIFICATION EVENTS ====================
    NotificationRuleCreated,
    NotificationRuleUpdated,
    NotificationRuleDeleted,
    NotificationRuleActivated,
    NotificationRuleDeactivated,
    NotificationCreated,
    NotificationSent,
    NotificationRead,
    NotificationFailed,
    NotificationDeliveryAttempted,
    NotificationDeliverySucceeded,
    NotificationDeliveryFailed,

    // ==================== SYSTEM EVENTS ====================
    SystemStartup,
    SystemShutdown,
    MonitoringTaskRun,
    MonitoringAlertTriggered,
    BackgroundJobStarted,
    BackgroundJobCompleted,
    BackgroundJobFailed,
}

/// Comprehensive audit trail event
/// Note: Event uses explicit fields instead of BaseFields since it has
/// a `timestamp` field that serves a different purpose than `created_at`
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct Event {
    pub id: Uuid,
    pub event_type: EventType,
    /// Entity type (e.g., "customer", "service", "project")
    pub entity_type: String,
    pub entity_id: Uuid,
    /// Actor type (team_profile or customer_profile, or "system")
    pub actor_type: Option<String>,
    pub actor_id: Option<Uuid>,
    /// Additional context (old_status, new_status, changed_fields, etc.)
    pub metadata: Option<JsonValue>,
    /// When the event occurred (business timestamp)
    pub timestamp: DateTime<Utc>,
    /// When the record was created (system timestamp)
    pub created_at: DateTime<Utc>,
}

impl Event {
    /// Create a new event
    pub fn new(
        event_type: EventType,
        entity_type: impl Into<String>,
        entity_id: Uuid,
        actor_type: Option<String>,
        actor_id: Option<Uuid>,
        metadata: Option<JsonValue>,
    ) -> Self {
        let now = Utc::now();
        Self {
            id: Uuid::new_v4(),
            event_type,
            entity_type: entity_type.into(),
            entity_id,
            actor_type,
            actor_id,
            metadata,
            timestamp: now,
            created_at: now,
        }
    }

    /// Create a system event (no actor)
    pub fn system(
        event_type: EventType,
        entity_type: impl Into<String>,
        entity_id: Uuid,
        metadata: Option<JsonValue>,
    ) -> Self {
        Self::new(
            event_type,
            entity_type,
            entity_id,
            Some("system".to_string()),
            None,
            metadata,
        )
    }
}
