use crate::markdowner::MarkdownModule;
use warp::Reply;

fn get_header_html(page_contents: &Vec<MarkdownModule>) -> String {
    let header = page_contents
        .iter()
        .find(|m| m.path.file_name().unwrap_or_default().eq("header.md"));
    match header {
        Some(h) => markdown::to_html_with_options(h.content.as_str(), &markdown::Options::gfm())
            .unwrap_or_default(),
        None => "".to_string(),
    }
}

fn get_content_html(page_contents: &Vec<MarkdownModule>) -> String {
    let content: Vec<&MarkdownModule> = page_contents
        .iter()
        .filter(|m| m.path.file_name().unwrap_or_default().ne("header.md"))
        .collect();
    let content_html: Vec<String> = content
        .iter()
        .filter_map(|m| {
            markdown::to_html_with_options(m.content.as_str(), &markdown::Options::gfm())
                .ok()
                .and_then(|c| {
                    format!(
                        "<div id='{}' class='markdown-module'>{}</div>",
                        m.path
                            .file_stem()
                            .unwrap_or_default()
                            .to_str()
                            .unwrap_or_default(),
                        c
                    )
                    .into()
                })
        })
        .collect();
    content_html.join("\n")
}

fn fill_template(
    header_html: String,
    content_html: String,
    sidebar_html: String,
    page_title: String,
) -> String {
    let template_html = std::fs::read_to_string("./serve/assets/templates/page.html")
        .expect("could not read page.html template");
    let template = text_template::Template::from(template_html.as_str());
    let mut values = std::collections::HashMap::new();
    values.insert("title", page_title.as_str());
    values.insert("header", header_html.as_str());
    values.insert("sidebar", sidebar_html.as_str());
    values.insert("content", content_html.as_str());
    template.fill_in(&values).to_string()
}

pub fn html_response(
    page_contents: Vec<MarkdownModule>,
    sidebar_contents: Vec<MarkdownModule>,
    page_title: String,
) -> Box<dyn Reply> {
    let header_html = get_header_html(&page_contents);

    let content_html = get_content_html(&page_contents);
    let sidebar_html = get_content_html(&sidebar_contents);

    Box::new(warp::reply::html(fill_template(
        header_html,
        content_html,
        sidebar_html,
        page_title,
    )))
}
