use std::sync::Arc;

use async_graphql::{
    async_stream::stream, futures_util::Stream, Context, Object, Subscription, ID,
};
use scel_core::App;

use super::query::Download;

pub struct SubscriptionRoot;

struct DownloadChanged {
    download: Download,
}

#[Object]
impl DownloadChanged {
    async fn download(&self) -> Download {
        self.download.clone()
    }
}

#[Subscription]
impl SubscriptionRoot {
    async fn get_download(&self, ctx: &Context<'_>, id: ID) -> impl Stream<Item = DownloadChanged> {
        let app = ctx.data_unchecked::<Arc<App>>();

        let mut stream = app
            .download_service
            .subscribe_download(id.to_string())
            .await;

        stream! {
            while stream.changed().await.is_ok() {
                let next_download = (*stream.borrow()).clone();
                let id = ID::from(next_download.id.unwrap());

                yield DownloadChanged {
                    download: Download {
                        id: id,
                        link: next_download.link,
                        file_name: next_download.file_name,
                        progress: next_download.progress,
                    }
                }
            }
        }
    }
}
