use crate::models::{Category, CategoryMapping, Enclosure, FatArticle, Feed, FeedMapping, Headline, Marked, Read, Tag, Tagging};
use chrono::{Duration, Utc};
use random_color::RandomColor;

#[derive(Debug)]
pub struct SyncResult {
    pub feeds: Option<Vec<Feed>>,
    pub categories: Option<Vec<Category>>,
    pub feed_mappings: Option<Vec<FeedMapping>>,
    pub category_mappings: Option<Vec<CategoryMapping>>,
    pub tags: Option<Vec<Tag>>,
    pub headlines: Option<Vec<Headline>>,
    pub articles: Option<Vec<FatArticle>>,
    pub enclosures: Option<Vec<Enclosure>>,
    pub taggings: Option<Vec<Tagging>>,
}

impl SyncResult {
    pub fn remove_old_articles(self, older_than: Option<Duration>) -> Self {
        if let Some(older_than) = older_than {
            SyncResult {
                feeds: self.feeds,
                categories: self.categories,
                feed_mappings: self.feed_mappings,
                category_mappings: self.category_mappings,
                tags: self.tags,
                headlines: self.headlines,
                articles: self.articles.map(|articles| {
                    articles
                        .into_iter()
                        .filter(|a| a.synced >= Utc::now() - older_than || a.unread == Read::Unread || a.marked == Marked::Marked)
                        .collect()
                }),
                enclosures: self.enclosures,
                taggings: self.taggings,
            }
        } else {
            self
        }
    }

    pub fn generate_tag_colors(self, db_tags: &[Tag]) -> Self {
        let tags = self.tags.map(|tags| {
            tags.into_iter()
                .map(|mut tag| {
                    let random_color = RandomColor::new().to_hex();
                    let db_tag = db_tags.iter().find(|t| t.tag_id == tag.tag_id);
                    let db_tag_color = db_tag.and_then(|t| t.color.clone()).unwrap_or(random_color);
                    let color = tag.color.unwrap_or(db_tag_color);
                    tag.color = Some(color);
                    tag
                })
                .collect::<Vec<Tag>>()
        });

        SyncResult {
            feeds: self.feeds,
            categories: self.categories,
            feed_mappings: self.feed_mappings,
            category_mappings: self.category_mappings,
            tags,
            headlines: self.headlines,
            articles: self.articles,
            enclosures: self.enclosures,
            taggings: self.taggings,
        }
    }
}
