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

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Bulletin {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
    pub date: NaiveDate,
    pub sermon_title: String,
    pub sermon_scripture: String,
    pub sermon_preacher: String,
    pub sermon_opening_hymn: String,
    pub sermon_closing_hymn: String,
    pub sabbath_school_section: String,
    pub divine_worship_section: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub pdf: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub cover_image: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub created: Option<DateTime<Utc>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub updated: Option<DateTime<Utc>>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct NewApiBulletin {
    pub id: String,
    pub title: String,
    pub date: String,
    pub url: Option<String>,
    pub cover_image_path: Option<String>,
    pub pdf_url: Option<String>,
    #[serde(default = "default_bool_true")]
    pub is_active: bool,
    pub pdf_file: Option<String>,
    pub sabbath_school: String,
    pub divine_worship: String,
    pub scripture_reading: String,
    pub sunset: Option<String>,
    pub cover_image: Option<String>,
    pub pdf_path: Option<String>,
    pub created_at: String,
    pub updated_at: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct NewApiResponse {
    pub success: bool,
    pub data: NewApiBulletin,
    pub message: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct NewApiEventsResponse {
    pub success: bool,
    pub data: Vec<NewApiEvent>,
    pub message: Option<String>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct NewApiEvent {
    pub id: String,
    pub title: String,
    pub description: String,
    pub start_time: String,
    pub end_time: String,
    pub location: String,
    pub location_url: Option<String>,
    pub image: String,
    pub thumbnail: Option<String>,
    pub category: String,
    pub is_featured: bool,
    pub recurring_type: Option<String>,
    pub approved_from: Option<String>,
    pub created_at: String,
    pub updated_at: String,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Event {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
    pub name: String,
    pub date: NaiveDate,
    pub time: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub end_time: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub location: Option<String>,
    pub event_type: EventType,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub start_datetime: Option<DateTime<Utc>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub end_datetime: Option<DateTime<Utc>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub recurring_type: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub created: Option<DateTime<Utc>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub updated: Option<DateTime<Utc>>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "lowercase")]
pub enum EventType {
    Announcement,
    Event,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Personnel {
    pub date: NaiveDate,
    pub elder: String,
    pub deacon: String,
    pub greeters: String,
    pub stream_host: String,
    pub camera: String,
    pub computer: String,
}

#[derive(Debug, Deserialize)]
pub struct OfferingData {
    pub date: NaiveDate,
    pub offering_focus: String,
    pub sunset_time: String,
}

#[derive(Debug, Deserialize)]
pub struct BibleVerse {
    pub book: String,
    pub chapter: i32,
    pub verse: i32,
    pub text: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ConferenceDataResponse {
    pub success: bool,
    pub data: ConferenceData,
    pub message: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ConferenceData {
    pub date: String,
    pub offering_focus: String,
    pub sunset_tonight: String,
    pub sunset_next_friday: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ScheduleResponse {
    pub success: bool,
    pub data: ScheduleData,
    pub message: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ScheduleData {
    pub date: String,
    pub personnel: PersonnelData,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct PersonnelData {
    #[serde(default = "default_empty_string")]
    pub ss_leader: String,
    #[serde(default = "default_empty_string")]
    pub ss_teacher: String,
    #[serde(default = "default_empty_string")]
    pub mission_story: String,
    #[serde(default = "default_empty_string")]
    pub song_leader: String,
    #[serde(default = "default_empty_string")]
    pub announcements: String,
    #[serde(default = "default_empty_string")]
    pub offering: String,
    #[serde(default = "default_empty_string")]
    pub special_music: String,
    #[serde(default = "default_empty_string")]
    pub speaker: String,
}

fn default_empty_string() -> String {
    String::new()
}

fn default_bool_true() -> bool {
    true
}

#[derive(Debug, Serialize)]
pub struct LoginRequest {
    pub username: String,
    pub password: String,
}

#[derive(Debug, Deserialize)]
pub struct LoginResponse {
    pub success: bool,
    pub data: Option<LoginData>,
    pub message: Option<String>,
}

#[derive(Debug, Deserialize)]
pub struct LoginData {
    pub token: String,
}