use chrono::{offset::LocalResult, TimeZone, Utc};
use chrono_humanize::{Accuracy, HumanTime, Tense};
use mastodon_async::entities::status::Status;
use mastodon_async::prelude::*;
use serde::Serialize;
use time::OffsetDateTime;

use crate::Result;

#[derive(Serialize)]
pub struct Skweet {
    reblog: bool,
    avatar: String,
    username: String,
    url: String,
    time_since: String,
    content: String,
    media_attachments: Vec<Attachment>,
}

pub async fn get_recents(client: &Mastodon) -> Result<Vec<Skweet>> {
    Ok(client
        .statuses(&AccountId::new("cel"), Default::default())
        .await?
        .initial_items
        .into_iter()
        .map(|status| Skweet::from(status))
        .collect())
}

impl From<Status> for Skweet {
    fn from(value: Status) -> Self {
        let url = value.url.unwrap_or_default();
        fn time_since(time: OffsetDateTime) -> String {
            let time =
                if let LocalResult::Single(time) = Utc.timestamp_opt(time.unix_timestamp(), 0) {
                    time
                } else {
                    return "oops".to_owned();
                };
            let duration = Utc::now() - time;
            HumanTime::from(duration).to_text_en(Accuracy::Rough, Tense::Present)
        }
        match value.reblog {
            Some(original) => Self {
                reblog: true,
                avatar: original.account.avatar,
                username: original.account.acct,
                url,
                time_since: time_since(original.created_at),
                content: value.content,
                media_attachments: value.media_attachments,
            },
            None => Self {
                reblog: false,
                avatar: value.account.avatar,
                username: value.account.acct,
                url,
                time_since: time_since(value.created_at),
                content: value.content,
                media_attachments: value.media_attachments,
            },
        }
    }
}
