use async_trait::async_trait;
use once_cell::sync::Lazy;
use rustc_hash::FxHashMap as HashMap;
use std::sync::Arc;

use crate::{
    DbPool, api::ClientVersion, status::Channel, util::cache::VideoCache, videos::{ServerOptions, VideoItem}
};

pub mod all;
pub mod hanime;
pub mod perverzija;
pub mod pmvhaven;
pub mod pornhub;
// pub mod spankbang;
pub mod homoxxx;
pub mod okporn;
pub mod okxxx;
pub mod perfectgirls;
pub mod pornhat;
pub mod redtube;
pub mod rule34video;
// pub mod hentaimoon;
pub mod missav;
pub mod porn00;
pub mod sxyprn;
pub mod xxthots;
// pub mod noodlemagazine;
pub mod freshporno;
pub mod omgxxx;
pub mod paradisehill;
pub mod pornzog;
pub mod youjizz;
pub mod beeg;
pub mod tnaflix;
pub mod pornxp;
pub mod rule34gen;
pub mod xxdbx;

// convenient alias
pub type DynProvider = Arc<dyn Provider>;

pub static ALL_PROVIDERS: Lazy<HashMap<&'static str, DynProvider>> = Lazy::new(|| {
    let mut m = HashMap::default();
    m.insert("omgxxx", Arc::new(omgxxx::OmgxxxProvider::new()) as DynProvider);
    m.insert("beeg", Arc::new(beeg::BeegProvider::new()) as DynProvider);
    m.insert("tnaflix", Arc::new(tnaflix::TnaflixProvider::new()) as DynProvider);
    m.insert("pornxp", Arc::new(pornxp::PornxpProvider::new()) as DynProvider);
    m.insert("rule34gen", Arc::new(rule34gen::Rule34genProvider::new()) as DynProvider);
    m.insert("xxdbx", Arc::new(xxdbx::XxdbxProvider::new()) as DynProvider);
    // add more here as you migrate them
    m
});

pub fn init_providers_now() {
    // Idempotent & thread-safe: runs the Lazy init exactly once.
    Lazy::force(&ALL_PROVIDERS);
}


#[async_trait]
pub trait Provider: Send + Sync {
    async fn get_videos(
        &self,
        cache: VideoCache,
        pool: DbPool,
        sort: String,
        query: Option<String>,
        page: String,
        per_page: String,
        options: ServerOptions,
    ) -> Vec<VideoItem>;

    fn get_channel(&self, clientversion: ClientVersion) -> Channel {
        println!(
            "Getting channel for placeholder with client version: {:?}",
            clientversion
        );
        let _ = clientversion;
        Channel {
            id: "placeholder".to_string(),
            name: "PLACEHOLDER".to_string(),
            description: "PLACEHOLDER FOR PARENT CLASS".to_string(),
            premium: false,
            favicon: "https://www.google.com/s2/favicons?sz=64&domain=missav.ws".to_string(),
            status: "active".to_string(),
            categories: vec![],
            options: vec![],
            nsfw: true,
            cacheDuration: None,
        }
    }
}
