use chrono::{DateTime, Utc};

use crate::sources::Sources;

#[derive(Debug, Clone)]
pub struct FeedEntry {
    pub id: String,
    pub updated: Option<DateTime<Utc>>,
    pub url: String,
    pub title: String,
    pub tags: Vec<String>,
}

pub fn generate(sources: &Sources, tag_name: &str) -> Option<Vec<FeedEntry>> {
    let mut entries = vec![];

    let tag = sources.treehouse.tags.get(tag_name)?;
    for file_id in &tag.files {
        if let Some(roots) = sources.treehouse.roots.get(file_id) {
            if let Some(id) = roots.attributes.id.clone() {
                entries.push(FeedEntry {
                    id,
                    updated: roots.attributes.timestamps.map(|ts| ts.updated),
                    url: format!(
                        "{}/{}.tree",
                        sources.config.site,
                        sources.treehouse.tree_path(*file_id).unwrap()
                    ),
                    title: roots.attributes.title.clone(),
                    tags: roots.attributes.tags.clone(),
                });
            }
        } else if let Some(doc) = sources.treehouse.docs.get(file_id) {
            if !doc.attributes.id.is_empty() && doc.attributes.updated.is_some() {
                entries.push(FeedEntry {
                    id: doc.attributes.id.clone(),
                    updated: doc.attributes.updated,
                    url: format!(
                        "{}/{}",
                        sources.config.site,
                        sources.treehouse.path(*file_id).with_extension("")
                    ),
                    title: doc.attributes.title.clone(),
                    tags: doc.attributes.tags.clone(),
                });
            }
        } else {
            unreachable!(
                "{file_id:?} registered in tag #{tag_name} is not actually in the treehouse"
            );
            // Well... either that, or unknown variant.
        }
    }

    entries.sort_by_key(|entry| entry.updated);
    entries.reverse();

    Some(entries)
}
