use crate::{Images, MediaCacheType, TexturedImage};
use poll_promise::Promise;

/// Tracks where media was on the screen so that
/// we can do fun animations when opening the
/// Media Viewer
#[derive(Debug, Clone)]
pub struct MediaInfo {
    /// The original screen position where it
    /// was rendered from. This is not where
    /// it should be rendered in the scene.
    pub original_position: egui::Rect,
    pub url: String,
}

/// Contains various information for when a user
/// clicks a piece of media. It contains the current
/// location on screen for each piece of media.
///
/// Viewers can use this to smoothly transition from
/// the timeline to the viewer
#[derive(Debug, Clone, Default)]
pub struct ViewMediaInfo {
    pub clicked_index: usize,
    pub medias: Vec<MediaInfo>,
}

impl ViewMediaInfo {
    pub fn clicked_media(&self) -> &MediaInfo {
        &self.medias[self.clicked_index]
    }
}

/// Actions generated by media ui interactions
pub enum MediaAction {
    /// An image was clicked on in a carousel, we have
    /// the opportunity to open into a fullscreen media viewer
    /// with a list of url values
    ViewMedias(ViewMediaInfo),

    FetchImage {
        url: String,
        cache_type: MediaCacheType,
        no_pfp_promise: Promise<Option<Result<TexturedImage, crate::Error>>>,
    },
    DoneLoading {
        url: String,
        cache_type: MediaCacheType,
    },
}

impl std::fmt::Debug for MediaAction {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::ViewMedias(ViewMediaInfo {
                clicked_index,
                medias,
            }) => f
                .debug_struct("ViewMedias")
                .field("clicked_index", clicked_index)
                .field("media", medias)
                .finish(),
            Self::FetchImage {
                url,
                cache_type,
                no_pfp_promise,
            } => f
                .debug_struct("FetchNoPfpImage")
                .field("url", url)
                .field("cache_type", cache_type)
                .field("no_pfp_promise ready", &no_pfp_promise.ready().is_some())
                .finish(),
            Self::DoneLoading { url, cache_type } => f
                .debug_struct("DoneLoading")
                .field("url", url)
                .field("cache_type", cache_type)
                .finish(),
        }
    }
}

impl MediaAction {
    /// Handle view media actions
    pub fn on_view_media(&self, handler: impl FnOnce(&ViewMediaInfo)) {
        if let MediaAction::ViewMedias(view_medias) = self {
            handler(view_medias)
        }
    }

    /// Default processing logic for Media Actions. We don't handle ViewMedias here since
    /// this may be app specific ?
    pub fn process_default_media_actions(self, images: &mut Images) {
        match self {
            MediaAction::ViewMedias(_urls) => {
                // NOTE(jb55): don't assume we want to show a fullscreen
                // media viewer we can use on_view_media for that. We
                // also don't want to have a notedeck_ui dependency in
                // the notedeck lib (MediaViewerState)
                //
                // In general our notedeck crate should be pretty
                // agnostic to functionallity in general unless it low
                // level like image rendering.
                //
                //mview_state.set_urls(urls);
            }

            MediaAction::FetchImage {
                url,
                cache_type,
                no_pfp_promise: promise,
            } => {
                images
                    .get_cache_mut(cache_type)
                    .textures_cache
                    .insert_pending(&url, promise);
            }
            MediaAction::DoneLoading { url, cache_type } => {
                let cache = match cache_type {
                    MediaCacheType::Image => &mut images.static_imgs,
                    MediaCacheType::Gif => &mut images.gifs,
                };

                cache.textures_cache.move_to_loaded(&url);
            }
        }
    }
}
