use crate::{
    providers::{
        all::AllProvider, hanime::HanimeProvider, okporn::OkpornProvider, perverzija::PerverzijaProvider, pmvhaven::PmvhavenProvider, pornhub::PornhubProvider, redtube::RedtubeProvider, rule34video::Rule34videoProvider
    }, util::cache::VideoCache, videos::{ServerOptions, VideoItem}, DbPool
};

pub mod all;
pub mod hanime;
pub mod perverzija;
pub mod pmvhaven;
pub mod pornhub;
// pub mod spankbang;
pub mod rule34video;
pub mod redtube;
pub mod okporn;
pub mod pornhat;
pub mod perfectgirls;
pub mod okxxx;
pub mod homoxxx;
// pub mod hentaimoon;
pub mod missav;
pub mod xxthots;
pub mod sxyprn;
pub mod porn00;
// pub mod noodlemagazine;
pub mod freshporno;
pub mod youjizz;
pub mod paradisehill;


pub trait Provider {
    async fn get_videos(
        &self,
        cache: VideoCache,
        pool: DbPool,
        sort: String,
        query: Option<String>,
        page: String,
        per_page: String,
        options: ServerOptions,
    ) -> Vec<VideoItem>;
}

#[derive(Debug, Clone)]
pub enum AnyProvider {
    All(AllProvider),
    Perverzija(PerverzijaProvider),
    Hanime(HanimeProvider),
    // Spankbang(SpankbangProvider),
    Pornhub(PornhubProvider),
    Pmvhaven(PmvhavenProvider),
    Rule34video(Rule34videoProvider),
    Redtube(RedtubeProvider),
    Okporn(OkpornProvider),
    Pornhat(crate::providers::pornhat::PornhatProvider),
    Perfectgirls(crate::providers::perfectgirls::PerfectgirlsProvider),
    Okxxx(crate::providers::okxxx::OkxxxProvider),
    Homoxxx(crate::providers::homoxxx::HomoxxxProvider),
    // Hentaimoon(crate::providers::hentaimoon::HentaimoonProvider),
    Missav(crate::providers::missav::MissavProvider),
    Xxthots(crate::providers::xxthots::XxthotsProvider),
    Sxyprn(crate::providers::sxyprn::SxyprnProvider),
    Porn00(crate::providers::porn00::Porn00Provider),
    // Noodlemagazine(crate::providers::noodlemagazine::NoodlemagazineProvider),
    Freshporno(crate::providers::freshporno::FreshpornoProvider),
    Youjizz(crate::providers::youjizz::YoujizzProvider),
    Paradisehill(crate::providers::paradisehill::ParadisehillProvider),
}

impl Provider for AnyProvider {
    async fn get_videos(
        &self,
        cache: VideoCache,
        pool: DbPool,
        sort: String,
        query: Option<String>,
        page: String,
        per_page: String,
        options: ServerOptions
    ) -> Vec<VideoItem> {
        println!(
            "/api/videos: sort={:?}, query={:?}, page={:?}, provider={:?}",
            sort, query, page, self
        );
        match self {
            AnyProvider::Perverzija(p) => {
                p.get_videos(
                    cache.clone(),
                    pool.clone(),
                    sort.clone(),
                    query.clone(),
                    page.clone(),
                    per_page.clone(),
                    options,
                )
                .await
            }
            AnyProvider::Hanime(p) => {
                p.get_videos(cache, pool, sort, query, page, per_page, options,)
                    .await
            }
            // AnyProvider::Spankbang(p) => {
            //     p.get_videos(cache, pool, sort, query, page, per_page, options,)
            //         .await
            // }
            AnyProvider::Pornhub(p) => {
                p.get_videos(cache, pool, sort, query, page, per_page, options,)
                    .await
            }
            AnyProvider::Pmvhaven(p) => {
                p.get_videos(cache, pool, sort, query, page, per_page, options,)
                    .await
            }
            AnyProvider::Rule34video(p) => {
                p.get_videos(cache, pool, sort, query, page, per_page, options,)
                    .await
            }
            AnyProvider::Redtube(p) => {
                p.get_videos(cache, pool, sort, query, page, per_page, options,)
                    .await
            }
            AnyProvider::All(p) => {
                p.get_videos(cache, pool, sort, query, page, per_page, options,)
                    .await
            }
            AnyProvider::Okporn(p) => {
                p.get_videos(cache, pool, sort, query, page, per_page, options,)
                    .await
            }
            AnyProvider::Pornhat(p) => {
                p.get_videos(cache, pool, sort, query, page, per_page, options,)
                    .await
            }
            AnyProvider::Perfectgirls(p) => {
                p.get_videos(cache, pool, sort, query, page, per_page, options,)
                    .await
            }
            AnyProvider::Okxxx(p) => {
                p.get_videos(cache, pool, sort, query, page, per_page, options,)
                    .await
            }
            AnyProvider::Homoxxx(p) => {
                p.get_videos(cache, pool, sort, query, page, per_page, options,)
                    .await
            }
            // AnyProvider::Hentaimoon(p) => {
            //     p.get_videos(cache, pool, sort, query, page, per_page, options,)
            //         .await
            // }
            AnyProvider::Missav(p) => {
                p.get_videos(cache, pool, sort, query, page, per_page, options,)
                    .await
            }
            AnyProvider::Xxthots(p) => {
                p.get_videos(cache, pool, sort, query, page, per_page, options,)
                    .await
            }
            AnyProvider::Sxyprn(p) => {
                p.get_videos(cache, pool, sort, query, page, per_page, options,)
                    .await
            }
            AnyProvider::Porn00(p) => {
                p.get_videos(cache, pool, sort, query, page, per_page, options,)
                    .await
            }
            // AnyProvider::Noodlemagazine(p) => {
            //     p.get_videos(cache, pool, sort, query, page, per_page, options,)
            //         .await
            // }
            AnyProvider::Freshporno(p) => {
                p.get_videos(cache, pool, sort, query, page, per_page, options,)
                    .await
            }
            AnyProvider::Youjizz(p) => {
                p.get_videos(cache, pool, sort, query, page, per_page, options,)
                    .await
            },
            AnyProvider::Paradisehill(p) => {
                p.get_videos(cache, pool, sort, query, page, per_page, options,)
                    .await
            }
        }
    }
}
