use super::config::AccountConfig;
use super::{Fever, FeverApi};
use crate::feed_api::{ApiMetadata, FeedApi, FeedApiError, FeedApiResult, Portal};
use crate::models::{
    ApiSecret, DirectLoginGUI, LoginGUI, PluginID, PluginIcon, PluginInfo, ServiceLicense, ServicePrice, ServiceType, Url, VectorIcon,
};
use rust_embed::RustEmbed;
use std::path::Path;
use std::str;
use std::sync::Arc;

#[derive(RustEmbed)]
#[folder = "src/feed_api_implementations/fever/icons"]
struct FeverResources;

pub struct FeverMetadata;

impl FeverMetadata {
    pub fn get_id() -> PluginID {
        PluginID::new("fever")
    }
}

impl ApiMetadata for FeverMetadata {
    fn id(&self) -> PluginID {
        Self::get_id()
    }

    fn info(&self) -> FeedApiResult<PluginInfo> {
        let icon_data = FeverResources::get("feed-service-fever.svg").ok_or(FeedApiError::Resource)?;
        let icon = VectorIcon {
            data: icon_data.data.to_vec(),
            width: 48,
            height: 48,
        };
        let icon = PluginIcon::Vector(icon);

        let symbolic_icon_data = FeverResources::get("feed-service-fever-symbolic.svg").ok_or(FeedApiError::Resource)?;
        let symbolic_icon = VectorIcon {
            data: symbolic_icon_data.data.to_vec(),
            width: 48,
            height: 48,
        };
        let symbolic_icon = PluginIcon::Vector(symbolic_icon);

        let login_gui = LoginGUI::Direct(DirectLoginGUI {
            http_auth: true,
            ..Default::default()
        });

        Ok(PluginInfo {
            id: self.id(),
            name: String::from("Fever"),
            icon: Some(icon),
            icon_symbolic: Some(symbolic_icon),
            website: Url::parse("https://feedafever.com/").ok(),
            service_type: ServiceType::Remote { self_hosted: true },
            license_type: ServiceLicense::ApacheV2,
            service_price: ServicePrice::Free,
            login_gui,
        })
    }

    fn get_instance(&self, config_dir: &Path, portal: Box<dyn Portal>, _user_api_secret: Option<ApiSecret>) -> FeedApiResult<Box<dyn FeedApi>> {
        let account_config = AccountConfig::load(config_dir)?;
        let mut api: Option<Arc<FeverApi>> = None;

        if let Some(url) = account_config.get_url()
            && let Ok(url) = Url::parse(&url)
            && let Some(username) = account_config.get_user_name()
            && let Some(password) = account_config.get_password()
        {
            api = if let Some(http_user) = account_config.get_http_user_name() {
                Some(Arc::new(FeverApi::new_with_http_auth(
                    &url,
                    &username,
                    &password,
                    &http_user,
                    account_config.get_http_password().as_deref(),
                )))
            } else {
                Some(Arc::new(FeverApi::new(&url, &username, &password)))
            }
        }

        let logged_in = api.is_some();

        let fever = Fever {
            api,
            portal: Arc::new(portal),
            logged_in,
            config: account_config,
        };
        let fever = Box::new(fever);
        Ok(fever)
    }
}
