use crate::error::Result;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;

const TABLE_NAME: &str = "events";

#[derive(Debug, Serialize, Deserialize, sqlx::FromRow)]
pub struct Event {
  pub id: Uuid,
  pub guild_id: i64,
  pub author_id: i64,
  pub title: String,
  pub date_time: DateTime<Utc>,
  pub description: Option<String>,
  pub rsvp: Vec<i64>,
}

impl Event {
  pub async fn insert(&self) -> Result<()> {
    let pool = crate::data::pool();
    sqlx::query(&format!(
      "INSERT INTO {} (
        id,
        guild_id,
        author_id,
        title,
        date_time,
        description,
        rsvp
      ) VALUES (
        $1, $2, $3, $4, $5, $6, $7
      )",
      TABLE_NAME
    ))
    .bind(self.id)
    .bind(self.guild_id)
    .bind(self.author_id)
    .bind(&self.title)
    .bind(self.date_time)
    .bind(&self.description)
    .bind(&self.rsvp)
    .execute(pool)
    .await?;
    Ok(())
  }

  pub async fn get_by_id(id: i64) -> Result<Option<Self>> {
    let pool = crate::data::pool();
    let item = sqlx::query_as::<_, Self>(&format!("SELECT * FROM {} WHERE id = $1", TABLE_NAME))
      .bind(id)
      .fetch_optional(pool)
      .await?;

    Ok(item)
  }
}
