use std::collections::HashMap;



#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct VideosRequest {
    //"versionInstallDate":"2025-06-03T18:20:20Z","languageCode":"en","appInstallDate":"2025-06-03T18:20:20Z","server":"spacemoehre","sexu
    pub clientHash: Option<String>, // "a07b23c9b07813c65050e2a4041ca777",
    pub blockedKeywords: Option<String>, // "kittens",
    pub countryCode: Option<String>, // "DE",
    pub clientVersion: Option<String>, // "2.1.4-22b",
    pub timestamp: Option<String>, // "1748976686",
    pub blockedUploaders: Option<String>, // "",
    pub anonId: Option<String>, // "1AB8A060-A47D-47EF-B9CB-63980ED84C8A",
    pub debugTools: Option<bool>, // false,
    pub versionInstallDate: Option<String>, // "2025-06-03T18:20:20Z",
    pub languageCode: Option<String>, // "en",
    pub appInstallDate: Option<String>, // "2025-06-03T18:20:20Z",
    pub server: Option<String>, // "spacemoehre",
    pub sexuality: Option<String>, // "straight",
    pub channel: Option<String>, //"youtube",
    pub sort: Option<String>,    //"new",
    pub query: Option<String>,   //"kittens",
    pub page: Option<String>,    //1,
    pub perPage: Option<String>, //10,
                                 // Your server's global options will be sent in the videos request
                                 //   pub flavor: "mint chocolate chip"
    pub featured: Option<String>, // "featured",
}
#[derive(serde::Serialize, Debug)]
pub struct PageInfo {
    pub hasNextPage: bool,   // true,
    pub resultsPerPage: u32, // 10
}


#[derive(serde::Serialize, Debug, Clone)]
pub struct VideoEmbed{
    pub html: String,
    pub source: String,
}
impl VideoEmbed {
    pub fn new(html: String, source: String) -> Self {
        VideoEmbed {
            html,
            source,
        }
    }
}
#[derive(serde::Serialize, Debug, Clone)]
pub struct VideoItem {
    pub duration: u32,              // 110,
    pub views: Option<u32>,         // 14622653,
    pub rating: Option<f32>,        // 0.0,
    pub id: String, // "c85017ca87477168d648727753c4ded8a35f173e22ef93743e707b296becb299",
    pub title: String, // "20 Minutes of Adorable Kittens   BEST Compilation",
    pub url: String, // "https://www.youtube.com/watch?v=y0sF5xhGreA",
    pub channel: String, // "youtube",
    pub thumb: String, // "https://i.ytimg.com/vi/y0sF5xhGreA/hqdefault.jpg",
    pub uploader: Option<String>, // "The Pet Collective",
    pub uploaderUrl: Option<String>, // "https://www.youtube.com/@petcollective",
    pub verified: Option<bool>, // false,
    pub tags: Option<Vec<String>>, // [],
    pub uploadedAt: Option<u64>, // 1741142954
    pub formats: Option<Vec<VideoFormat>>, // Additional HTTP headers if needed
    pub embed: Option<VideoEmbed>, // Optional embed information
    pub preview: Option<String>
}
#[allow(dead_code)]
impl VideoItem {
    pub fn new(
        id: String,
        title: String,
        url: String,
        channel: String,
        thumb: String,
        duration: u32,
    ) -> Self {
        VideoItem {
            duration: duration,  // Placeholder, adjust as needed
            views: None,  // Placeholder, adjust as needed
            rating: None, // Placeholder, adjust as needed
            id,
            title,
            url,
            channel,
            thumb,
            uploader: None,
            uploaderUrl: None,
            verified: None,
            tags: None, // Placeholder, adjust as needed
            uploadedAt: None,
            formats: None, // Placeholder for formats
            embed: None, // Placeholder for embed information
            preview: None
        }
    }
    pub fn tags(mut self, tags: Vec<String>) -> Self {
        self.tags = Some(tags);
        self
    }
    pub fn uploader(mut self, uploader: String) -> Self {
        self.uploader = Some(uploader);
        self
    }
    pub fn uploader_url(mut self, uploader_url: String) -> Self {
        self.uploaderUrl = Some(uploader_url);
        self
    }
    pub fn verified(mut self, verified: bool) -> Self {
        self.verified = Some(verified);
        self
    }
    pub fn views(mut self, views: u32) -> Self {
        self.views = Some(views);
        self
    }
    pub fn rating(mut self, rating: f32) -> Self {
        self.rating = Some(rating);
        self
    }
    pub fn uploaded_at(mut self, uploaded_at: u64) -> Self {
        self.uploadedAt = Some(uploaded_at);
        self
    }
    pub fn formats(mut self, formats: Vec<VideoFormat>) -> Self {
        self.formats = Some(formats);
        self
    }
    pub fn add_format(mut self, format: VideoFormat){
        if let Some(formats) = self.formats.as_mut() {
            formats.push(format);
        } else {
            self.formats = Some(vec![format]);
        }
    }
    pub fn embed(mut self, embed: VideoEmbed) -> Self {
        self.embed = Some(embed);
        self
    }
    pub fn preview(mut self, preview: String) -> Self {
        self.preview = Some(preview);
        self
    }
}

#[derive(serde::Serialize, Debug, Clone)]
pub struct VideoFormat {
    url: String,
    quality: String,
    format: String,
    format_id: Option<String>,
    format_note: Option<String>,
    filesize: Option<u32>,
    asr: Option<u32>,
    fps: Option<u32>,
    width: Option<u32>,
    height: Option<u32>,
    tbr: Option<u32>,
    language: Option<String>,
    language_preference: Option<u32>,
    ext: Option<String>,
    vcodec: Option<String>,
    acodec: Option<String>,
    dynamic_range: Option<String>,
    abr: Option<u32>,
    vbr: Option<u32>,
    container: Option<String>,
    protocol: Option<String>,
    audio_ext: Option<String>,
    video_ext: Option<String>,
    resolution: Option<String>,
    http_headers: Option<HashMap<String, String>>,
    
}
impl VideoFormat {
    pub fn new(url: String, quality: String, format: String) -> Self {
        let _ = format;
        VideoFormat {
            url,
            quality,
            format: "mp4".to_string(), // Default format
            format_id: Some("mp4-1080".to_string()),
            format_note: None,
            filesize: None,
            asr: None,
            fps: None,
            width: None,
            height: None,
            tbr: None,
            language: None,
            language_preference: None,
            ext: Some("mp4".to_string()),
            vcodec: None,
            acodec: None,
            dynamic_range: None,
            abr: None,
            vbr: None,
            container: None,
            protocol: Some("m3u8_native".to_string()),
            audio_ext: Some("none".to_string()),
            video_ext: Some("mp4".to_string()),
            resolution: None,
            http_headers: None,
        }
    }
    pub fn add_http_header(&mut self, key: String, value: String) {
        if self.http_headers.is_none() {
            self.http_headers = Some(HashMap::new());
        }
        if let Some(headers) = &mut self.http_headers {
            headers.insert(key, value);
        }
    }
}
#[derive(serde::Serialize, Debug)]
pub struct Videos {
    pub pageInfo: PageInfo,
    pub items: Vec<VideoItem>,
}
