use crate::models::{CategoryID, FeedID, Url};
use crate::schema::{feed_mapping, feeds};
use diesel::sql_types::{BigInt, Text};
use std::hash::{Hash, Hasher};

#[derive(Identifiable, Clone, Insertable, Queryable, PartialEq, Eq, Debug)]
#[primary_key(feed_id)]
#[table_name = "feeds"]
pub struct Feed {
    pub feed_id: FeedID,
    pub label: String,
    pub website: Option<Url>,
    pub feed_url: Option<Url>,
    pub icon_url: Option<Url>,
    pub sort_index: Option<i32>,
}

impl Feed {
    pub fn decompose(self) -> (FeedID, String, Option<Url>, Option<Url>, Option<Url>, Option<i32>) {
        (self.feed_id, self.label, self.website, self.feed_url, self.icon_url, self.sort_index)
    }
}

impl Hash for Feed {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.feed_id.hash(state);
    }
}

//------------------------------------------------------------------

#[derive(QueryableByName, Debug)]
pub struct FeedCount {
    #[sql_type = "Text"]
    pub feed_id: FeedID,
    #[sql_type = "BigInt"]
    pub count: i64,
}

//------------------------------------------------------------------

#[derive(Identifiable, Insertable, Associations, Queryable, PartialEq, Debug)]
#[primary_key(feed_id)]
#[table_name = "feed_mapping"]
#[belongs_to(Feed, foreign_key = "feed_id")]
pub struct FeedMapping {
    pub feed_id: FeedID,
    pub category_id: CategoryID,
}

impl FeedMapping {
    pub fn decompose(self) -> (FeedID, CategoryID) {
        (self.feed_id, self.category_id)
    }
}
