// "2025-08-13T05:00:00-04:00"
    pub timezone: String, // "America/New_York"

/// Timezone-aware timestamp from v2 API
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct TimezoneTimestamp {
    pub utc: DateTime<Utc>,
    pub local: String,  // "2025-08-13T05:00:00-04:00"
}

fn(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
            formatter.write_str("a string timestamp or timezone object")
        }

fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
        where
            E: de::Error,
        {
            // v1 format: simple ISO string
            DateTime::parse_from_rfc3339(value)
                .map(|dt| dt.with_timezone(&Utc))
                .map_err(de::Error::custom)
        }

fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
        where
            M: de::MapAccess<'de>,
        {
            // v2 format: timezone object - extract UTC field
            let mut utc_value: Option<DateTime<Utc>> = None;
            
            while let Some(key) = map.next_key::<String>()? {
                match key.as_str() {
                    "utc" => {
                        utc_value = Some(map.next_value()?);
                    }
                    _ => {
                        // Skip other fields (local, timezone)
                        let _: serde_json::Value = map.next_value()?;
                    }
                }
            }
            
            utc_value.ok_or_else(|| de::Error::missing_field("utc"))
        }

impl<'de> Visitor<'de> for FlexibleDateTimeVisitor {
        type Value = DateTime<Utc>;
        
        fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
        }
        
        fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
        where
        {
        }
        
        fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
        where
        {
            
                    "utc" => {
                    }
                    _ => {
                    }
                }
            }
            
        }
    }

/// Custom deserializer that handles both v1 (simple string) and v2 (timezone object) formats
fn deserialize_flexible_datetime<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
where
    D: Deserializer<'de>,
{
    use serde::de::{self, Visitor};
    
    struct FlexibleDateTimeVisitor;
    
    impl<'de> Visitor<'de> for FlexibleDateTimeVisitor {
        
        }
        
        where
        {
        }
        
        where
        {
            
                    "utc" => {
                    }
                    _ => {
                    }
                }
            }
            
        }
    }
    
    deserializer.deserialize_any(FlexibleDateTimeVisitor)
}

#[serde(deserialize_with = "deserialize_flexible_datetime")]
    pub start_time: DateTime<Utc>,

    pub end_time: DateTime<Utc>,

#[serde(skip_serializing_if = "Option::is_none")]
    pub location_url: Option<String>,

    pub image: Option<String>,

    pub thumbnail: Option<String>,

    pub recurring_type: Option<RecurringType>,

    pub tags: Option<Vec<String>>,

    pub contact_email: Option<String>,

    pub contact_phone: Option<String>,

    pub registration_url: Option<String>,

    pub max_attendees: Option<u32>,

    pub current_attendees: Option<u32>,

    pub timezone: Option<String>,

    pub approved_from: Option<String>,

    pub created_at: DateTime<Utc>,

    pub updated_at: DateTime<Utc>,

pub struct Event {
    pub id: String,
    pub title: String,
    pub description: String,
    #[serde(deserialize_with = "deserialize_flexible_datetime")]
    pub location: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub category: EventCategory,
    #[serde(default)]
    pub is_featured: bool,
}

pub struct NewEvent {
}

    pub title: Option<String>,

    pub description: Option<String>,

    pub start_time: Option<DateTime<Utc>>,

    pub end_time: Option<DateTime<Utc>>,

    pub location: Option<String>,

    pub category: Option<EventCategory>,

    pub is_featured: Option<bool>,

pub struct EventUpdate {
}

#[serde(rename = "education", alias = "Education")]
    Education,

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub enum EventCategory {
    #[serde(rename = "service", alias = "Service")]
    Service,
    #[serde(rename = "ministry", alias = "Ministry")]
    Ministry,
    #[serde(rename = "social", alias = "Social")]
    Social,
    #[serde(rename = "education", alias = "Education")]
    #[serde(rename = "outreach", alias = "Outreach")]
    Outreach,
    #[serde(rename = "youth", alias = "Youth")]
    Youth,
    #[serde(rename = "music", alias = "Music")]
    Music,
    #[serde(rename = "other", alias = "Other")]
    Other,
}

#[serde(rename = "first_tuesday", alias = "FIRST_TUESDAY")]
    FirstTuesday,

#[serde(rename = "first_sabbath", alias = "FIRST_SABBATH")]
    FirstSabbath,

#[serde(rename = "last_sabbath", alias = "LAST_SABBATH")]
    LastSabbath,

#[serde(rename = "2nd/3rd Saturday Monthly")]
    SecondThirdSaturday,

pub enum RecurringType {
    #[serde(rename = "daily", alias = "DAILY")]
    Daily,
    #[serde(rename = "weekly", alias = "WEEKLY")]
    Weekly,
    #[serde(rename = "biweekly", alias = "BIWEEKLY")]
    Biweekly,
    #[serde(rename = "monthly", alias = "MONTHLY")]
    Monthly,
    #[serde(rename = "first_tuesday", alias = "FIRST_TUESDAY")]
    #[serde(rename = "first_sabbath", alias = "FIRST_SABBATH")]
    #[serde(rename = "last_sabbath", alias = "LAST_SABBATH")]
    #[serde(rename = "2nd/3rd Saturday Monthly")]
}

pub fn duration_minutes(&self) -> i64 {
        (self.end_time - self.start_time).num_minutes()
    }

pub fn has_registration(&self) -> bool {
        self.registration_url.is_some()
    }

pub fn is_full(&self) -> bool {
        match (self.max_attendees, self.current_attendees) {
            (Some(max), Some(current)) => current >= max,
            _ => false,
        }
    }

pub fn spots_remaining(&self) -> Option<u32> {
            (Some(max), Some(current)) => Some(max.saturating_sub(current)),
            _ => None,
        }
    }

impl Event {
    pub fn duration_minutes(&self) -> i64 {
    }
    
    pub fn has_registration(&self) -> bool {
    }
    
    pub fn is_full(&self) -> bool {
            _ => false,
        }
    }
    
    pub fn spots_remaining(&self) -> Option<u32> {
            _ => None,
        }
    }
}

fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            EventCategory::Service => write!(f, "Service"),
            EventCategory::Ministry => write!(f, "Ministry"),
            EventCategory::Social => write!(f, "Social"),
            EventCategory::Education => write!(f, "Education"),
            EventCategory::Outreach => write!(f, "Outreach"),
            EventCategory::Youth => write!(f, "Youth"),
            EventCategory::Music => write!(f, "Music"),
            EventCategory::Other => write!(f, "Other"),
        }
    }

impl fmt::Display for EventCategory {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        }
    }
}

pub fn formatted_date(&self) -> String {
        self.start_time.format("%A, %B %d, %Y").to_string()
    }

/// Returns formatted date range for multi-day events, single date for same-day events
    pub fn formatted_date_range(&self) -> String {
        let start_date = self.start_time.date_naive();
        let end_date = self.end_time.date_naive();
        
        if start_date == end_date {
            // Same day event
            self.start_time.format("%A, %B %d, %Y").to_string()
        } else {
            // Multi-day event
            let start_formatted = self.start_time.format("%A, %B %d, %Y").to_string();
            let end_formatted = self.end_time.format("%A, %B %d, %Y").to_string();
            format!("{} - {}", start_formatted, end_formatted)
        }
    }

pub fn formatted_start_time(&self) -> String {
        // Convert UTC to user's local timezone automatically
        let local_time = self.start_time.with_timezone(&chrono::Local);
        local_time.format("%I:%M %p").to_string().trim_start_matches('0').to_string()
    }

pub fn formatted_end_time(&self) -> String {
        let local_time = self.end_time.with_timezone(&chrono::Local);
    }

pub fn clean_description(&self) -> String {
        html2text::from_read(self.description.as_bytes(), 80)
            .replace('\n', " ")
            .split_whitespace()
            .collect::<Vec<&str>>()
            .join(" ")
    }

    pub fn formatted_date(&self) -> String {
    }
    
    /// Returns formatted date range for multi-day events, single date for same-day events
        
        } else {
        }
    }
    
    pub fn formatted_start_time(&self) -> String {
    }
    
    pub fn formatted_end_time(&self) -> String {
    }
    
    pub fn clean_description(&self) -> String {
            .join(" ")
    }
}

// ISO string format
    pub end_time: String,   // ISO string format

// String to match API exactly

    pub recurring_type: Option<String>,

    pub bulletin_week: Option<String>, // Date string in YYYY-MM-DD format

// Date string in YYYY-MM-DD format
    pub submitter_email: String,

/// Event submission for public submission endpoint
pub struct EventSubmission {
    pub start_time: String, // ISO string format
    pub category: String, // String to match API exactly
}

/// Parse start_time string to DateTime<Utc>
    pub fn parse_start_time(&self) -> Option<DateTime<Utc>> {
        crate::utils::parse_datetime_flexible(&self.start_time)
    }

/// Parse end_time string to DateTime<Utc>
    pub fn parse_end_time(&self) -> Option<DateTime<Utc>> {
        crate::utils::parse_datetime_flexible(&self.end_time)
    }

/// Validate that both start and end times can be parsed
    pub fn validate_times(&self) -> bool {
        self.parse_start_time().is_some() && self.parse_end_time().is_some()
    }

impl EventSubmission {
    /// Parse start_time string to DateTime<Utc>
    }
    
    /// Parse end_time string to DateTime<Utc>
    }
    
    /// Validate that both start and end times can be parsed
    }
}

    pub bulletin_week: Option<String>,

/// Pending event for admin management
pub struct PendingEvent {
}