use super::follow_packs::get_follow_pack;
use super::route_prelude::*;
use crate::rendering::render_notes;

#[derive(Template)]
#[template(path = "feed.gmi", escape = "txt")]
pub struct FeedTemplate {
    note_blocks: Vec<Block>,
}

pub async fn show_feed(
    ctx: RouteContext,
    user: &'static mut CaracalUser,
) -> Result<Response, UserError> {
    let limit_str = ctx.parameters.get("limit").unwrap_or("250");
    let limit = limit_str.parse::<usize>()?;
    let mute_list = user.mute_list().await;

    let public_keys = match get_follow_pack(ctx, user).await {
        Ok(follow_pack) => {
            // Follow pack feed
            let mut pubkeys = follow_pack
                .tags
                .public_keys()
                .map(|k| k.to_owned())
                .collect::<Vec<_>>();
            pubkeys.retain(|pk| !mute_list.public_keys.contains(pk));

            user.sub(
                Filter::new()
                    .kind(Kind::TextNote)
                    .kind(Kind::LongFormTextNote)
                    .authors(pubkeys.clone())
                    .since(Timestamp::now() - dur_parse("60d").unwrap()),
            )
            .await?;

            pubkeys
        }
        Err(_) => {
            let mut contacts = user.contact_list_pubkeys().await?;

            // Remove muted public keys
            contacts.retain(|pk| !mute_list.public_keys.contains(pk));
            contacts
        }
    };

    let filter = Filter::new()
        .kind(Kind::TextNote)
        .kind(Kind::LongFormTextNote)
        .authors(public_keys)
        .limit(limit);

    let events = user.client.database().query(filter).await?;

    let note_blocks = render_notes(
        user.events_filter_muted(&events).await,
        &user.client,
        None,
        None,
        NoteRenderOptions::default() | NoteRenderOptions::SHOW_HASHTAGS,
    )
    .await?;

    Ok(Response::success(WindTemplate::render(FeedTemplate {
        note_blocks,
    })))
}
