use crate::models::files::FileID;
use crate::models::movements::MovementID;
use crate::models::users::UserID;
use crate::schema::*;
use diesel::{Insertable, Queryable};

#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
pub struct InboxEntryID(pub i32);

/// Single inbox entry information
#[derive(Queryable, Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct InboxEntry {
    /// The ID of the inbox entry
    id: i32,
    /// ID of the file attached to this inbox entry
    file_id: i32,
    /// The ID this inbox entry belongs to
    user_id: i32,
    /// The ID of the movement this inbox entry is attached to (if any)
    movement_id: Option<i32>,
    /// The time this inbox entry happened
    pub time: i64,
    /// The label associated to this inbox entry
    pub label: Option<String>,
    /// The amount of the inbox entry
    pub amount: Option<f32>,
    /// The time this inbox entry was created in the database
    pub time_create: i64,
    /// The time this inbox entry was last updated in the database
    pub time_update: i64,
}

impl InboxEntry {
    /// Get the ID of the inbox entry
    pub fn id(&self) -> InboxEntryID {
        InboxEntryID(self.id)
    }

    /// The id of the user owning this inbox entry
    pub fn user_id(&self) -> UserID {
        UserID(self.user_id)
    }

    /// The ID of the movement attached to the movement (if any)
    pub fn movement_id(&self) -> Option<MovementID> {
        self.movement_id.map(MovementID)
    }

    /// The ID of the file attached to the movement, if any
    pub fn file_id(&self) -> FileID {
        FileID(self.file_id)
    }
}

#[derive(Insertable, Debug)]
#[diesel(table_name = inbox)]
pub struct NewInboxEntry<'a> {
    pub file_id: i32,
    pub user_id: i32,
    pub movement_id: Option<i32>,
    pub time: i64,
    pub label: Option<&'a str>,
    pub amount: Option<f32>,
    pub time_create: i64,
    pub time_update: i64,
}
