use super::error::Error;
use super::ext::VideoThumbnailExtractorExt;
use async_trait::async_trait;
use reqwest::Client;
use url::Url;

#[derive(Debug, Clone)]
pub struct YoutubeThumbnailExtractor;

impl YoutubeThumbnailExtractor {
    fn get_video_id(&self, video_url: &Url) -> Option<String> {
        if let Some(id) = video_url
            .query_pairs()
            .find_map(|(key, val)| if key == "v" { Some(val) } else { None })
        {
            return Some(id.to_string());
        }

        let mut path_segments = video_url.path_segments()?;
        if let Some("embed") = path_segments.next() {
            return path_segments.next().map(|seg| seg.to_string());
        }

        None
    }
}

#[async_trait]
impl VideoThumbnailExtractorExt for YoutubeThumbnailExtractor {
    fn matches_url(&self, video_url: &str) -> bool {
        video_url.contains("youtube.com")
    }

    async fn get_thumbnail_url(&self, video_url: &str, _client: &Client) -> Result<String, Error> {
        let video_url = Url::parse(video_url)?;
        let video_id = self.get_video_id(&video_url).ok_or(Error::Parse)?;
        let thumbnail_url = format!("http://img.youtube.com/vi/{video_id}/maxresdefault.jpg");
        Ok(thumbnail_url)
    }
}
