use chrono::{DateTime, NaiveDate, Utc};
use serde::{Deserialize, Serialize};
use sqlx::FromRow;
use uuid::Uuid;

#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct User {
    pub id: Uuid,
    pub username: String,                    // NOT NULL
    pub email: Option<String>,               // nullable
    pub name: Option<String>,                // nullable  
    pub avatar_url: Option<String>,          // nullable
    pub role: Option<String>,                // nullable (has default)
    pub verified: Option<bool>,              // nullable (has default)
    pub created_at: Option<DateTime<Utc>>,   // nullable (has default)
    pub updated_at: Option<DateTime<Utc>>,   // nullable (has default)
}

#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct Bulletin {
    pub id: Uuid,
    pub title: String,
    pub date: NaiveDate,
    pub url: Option<String>,
    pub pdf_url: Option<String>,
    pub is_active: Option<bool>,
    pub pdf_file: Option<String>,
    pub sabbath_school: Option<String>,
    pub divine_worship: Option<String>,
    pub scripture_reading: Option<String>,
    pub sunset: Option<String>,
    pub cover_image: Option<String>,
    pub pdf_path: Option<String>,
    pub cover_image_path: Option<String>,
    pub created_at: Option<DateTime<Utc>>,
    pub updated_at: Option<DateTime<Utc>>,
}

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

#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct PendingEvent {
    pub id: Uuid,
    pub title: String,                       // NOT NULL
    pub description: String,                 // NOT NULL
    pub start_time: DateTime<Utc>,           // NOT NULL
    pub end_time: DateTime<Utc>,             // NOT NULL
    pub location: String,                    // NOT NULL
    pub location_url: Option<String>,        // nullable
    pub image: Option<String>,               // nullable
    pub thumbnail: Option<String>,           // nullable
    pub category: String,                    // NOT NULL
    pub is_featured: Option<bool>,           // nullable (has default)
    pub recurring_type: Option<String>,      // nullable
    pub approval_status: Option<String>,     // nullable (has default)
    pub submitted_at: Option<DateTime<Utc>>, // nullable (has default)
    pub bulletin_week: String,               // NOT NULL
    pub admin_notes: Option<String>,         // nullable
    pub submitter_email: Option<String>,     // nullable
    pub email_sent: Option<bool>,            // nullable (has default)
    pub pending_email_sent: Option<bool>,    // nullable (has default)
    pub rejection_email_sent: Option<bool>,  // nullable (has default)
    pub approval_email_sent: Option<bool>,   // nullable (has default)
    pub image_path: Option<String>,
    pub created_at: Option<DateTime<Utc>>,   // nullable (has default)
    pub updated_at: Option<DateTime<Utc>>,   // nullable (has default)
}

#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
pub struct ChurchConfig {
    pub id: Uuid,
    pub church_name: String,
    pub contact_email: String,
    pub contact_phone: Option<String>,
    pub church_address: String,
    pub po_box: Option<String>,
    pub google_maps_url: Option<String>,
    pub about_text: String,
    pub api_keys: Option<serde_json::Value>,
    pub created_at: Option<DateTime<Utc>>,
    pub updated_at: Option<DateTime<Utc>>,
}

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

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

#[derive(Debug, Serialize)]
pub struct LoginResponse {
    pub token: String,
    pub user: User,
}

#[derive(Debug, Deserialize)]
pub struct CreateBulletinRequest {
    pub title: String,
    pub date: NaiveDate,
    pub url: Option<String>,
    pub sabbath_school: Option<String>,
    pub divine_worship: Option<String>,
    pub scripture_reading: Option<String>,
    pub sunset: Option<String>,
    pub is_active: Option<bool>,
}

#[derive(Debug, Deserialize)]
pub struct CreateEventRequest {
    pub title: String,
    pub description: String,
    pub start_time: DateTime<Utc>,
    pub end_time: DateTime<Utc>,
    pub location: String,
    pub location_url: Option<String>,
    pub category: String,
    pub is_featured: Option<bool>,
    pub recurring_type: Option<String>,
}

#[derive(Debug, Deserialize)]
pub struct SubmitEventRequest {
    pub title: String,
    pub description: String,
    pub start_time: DateTime<Utc>,
    pub end_time: DateTime<Utc>,
    pub location: String,
    pub location_url: Option<String>,
    pub category: String,
    pub is_featured: Option<bool>,
    pub recurring_type: Option<String>,
    pub bulletin_week: String,
    pub submitter_email: Option<String>,
}

#[derive(Debug, Serialize)]
pub struct PaginatedResponse<T> {
    pub items: Vec<T>,
    pub total: i64,
    pub page: i32,
    pub per_page: i32,
    pub has_more: bool,
}

#[derive(Debug, Deserialize)]
pub struct PaginationParams {
    pub page: Option<i64>,
    pub per_page: Option<i64>,
}
