use chrono::NaiveDateTime;

use internal::stars_to_shards;
use models::user_farm::UserFarm;
use schema::farm_entry;

#[derive(Identifiable, Queryable, Associations, PartialEq, Debug, Clone)]
#[belongs_to(UserFarm)]
#[table_name = "farm_entry"]
pub struct FarmEntry {
    pub id: i32,
    pub user_farm_id: i32,
    pub comments: Option<String>,
    pub current_shards: u16,
    pub current_stars: u16,
    pub date: NaiveDateTime,
}

impl FarmEntry {
    pub fn get_remaining_shards(&self, stars_goal: u16) -> u16 {
        (stars_to_shards(stars_goal) - stars_to_shards(self.current_stars))
            .checked_sub(self.current_shards)
            .unwrap_or(0)
    }

    pub fn compact_summary(&self) -> String {
        let co = if self.comments.is_some() {
            format!(", comments => {}", self.comments.clone().unwrap())
        } else {
            "".to_string()
        };

        format!(
            "{} :: shards => {}, stars => {}{}\n",
            self.date, self.current_shards, self.current_stars, co
        )
    }

    pub fn summary(&self) -> String {
        format!(
            "date     :: {}\nshards   :: {}\nstars    :: {}\ncomments :: {}\n",
            self.date,
            self.current_shards,
            self.current_stars,
            self.comments.clone().unwrap_or_else(|| "".to_string())
        )
    }

    pub fn total_shards(&self) -> u16 {
        stars_to_shards(self.current_stars) + self.current_shards
    }
}

#[derive(Insertable)]
#[table_name = "farm_entry"]
pub struct NewFarmEntry<'a> {
    pub comments: Option<&'a String>,
    pub current_shards: &'a u16,
    pub current_stars: &'a u16,
    pub date: &'a NaiveDateTime,
    pub user_farm_id: &'a i32,
}
