use super::posts::{HtmlContent, Post};
use super::util::output_rendered_template;
use askama::Template;
use std::path::{Path, PathBuf};

pub trait PaginatableTemplate<'a>: Template {
    fn with_posts(
        &'a self,
        posts: &'a [&'a Post<HtmlContent>],
        pagination_info: PaginationInfo,
    ) -> Self;
}

#[derive(Default)]
pub struct PaginationInfo {
    pub page: usize,
    pub total_pages: usize,
    // Relative to path of the file being generated
    pub next_href: Option<String>,
    // Relative to path of the file being generated
    pub prev_href: Option<String>,
}

const SIZE: usize = 5;

pub fn render_paginated<'a, T: PaginatableTemplate<'a>>(
    template: &'a T,
    posts: &'a [&'a Post<HtmlContent>],
    base_path: impl AsRef<Path>,
) -> Result<(), std::io::Error> {
    // div_ceil is unstable, so we do it ourselves
    let total_pages = (posts.len() as f32 / SIZE as f32).ceil() as usize;
    let mut buf: PathBuf = base_path.as_ref().into();
    for (chunk_idx, chunk) in posts.chunks(SIZE).enumerate() {
        let page = chunk_idx + 1;
        let next_page = if page < total_pages {
            Some(page + 1)
        } else {
            None
        };
        let prev_page = if page > 1 { Some(page - 1) } else { None };

        if page == 1 {
            buf.push("index.html");
            let chunk_template = template.with_posts(
                chunk,
                PaginationInfo {
                    page,
                    total_pages,
                    next_href: next_page.map(|p| format!("./{}/", p)),
                    prev_href: None,
                },
            );
            output_rendered_template(&chunk_template, &buf)?;
            buf.pop();
        }

        let chunk_template = template.with_posts(
            chunk,
            PaginationInfo {
                page,
                total_pages,
                next_href: next_page.map(|p| format!("../{}/", p)),
                prev_href: prev_page.map(|p| format!("../{}/", p)),
            },
        );
        buf.push(page.to_string());
        buf.push("index.html");
        output_rendered_template(&chunk_template, &buf)?;
        buf.pop();
        buf.pop();
    }
    Ok(())
}
