pub mod util;
pub mod ui;
pub mod repository;
pub mod redis_storage;

pub use rust_shared::t8x;

use rust_shared::i18n::Language;
use teloxide::{
    adaptors::DefaultParseMode,
    types::LinkPreviewOptions,
    dispatching::dialogue::{ErasedStorage, Dialogue},
};
use std::sync::Arc;

pub type Bot = DefaultParseMode<teloxide::Bot>;

pub type MyStorage<S> = Arc<ErasedStorage<S>>;
pub type MyDialogue<S> = Dialogue<S, ErasedStorage<S>>;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct HandlerSettings {
    pub behavior: ForceHandlerBehavior,
    pub language: Language,
}

impl HandlerSettings {
    pub fn force_behavior(&self, behavior: ForceHandlerBehavior) -> Self {
        Self {
            behavior,
            language: self.language,
        }
    }

    pub fn with_language(&self, language: Language) -> Self {
        Self {
            behavior: self.behavior,
            language,
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ForceHandlerBehavior {
    None,
    DeleteMessage,
    EditMessage,
    NewMessage,
}

mod env_var {
    pub const TOKEN_VAR: &str = "TELEGRAM_TOKEN";
    pub const PROD_DB_URL_VAR: &str = "PROD_DB_URL";
    pub const WEBSITE_DOMAIN_VAR: &str = "WEBSITE_DOMAIN";
}

pub mod consts {
    use crate::env_var::*;
    use std::env;
    use teloxide::{prelude::RequesterExt, types::ParseMode};
    use crate::Bot;

    pub fn init_bot() -> Bot {
        log::trace!("init {TOKEN_VAR}....");
    
        let token = std::env::var(TOKEN_VAR).expect("Unable to read {TOKEN_VAR} env");
    
        teloxide::Bot::new(token).parse_mode(ParseMode::Html)
    }

    lazy_static::lazy_static! {
        pub static ref BOT: Bot = init_bot();
        pub static ref NEWS_CHANNEL_LINK: String = "https://t.me/VProxyNews".to_string();
        pub static ref WEBSITE_DOMAIN: String = {
            env::var(WEBSITE_DOMAIN_VAR)
                .unwrap_or_else(|_| panic!("Unable to read {WEBSITE_DOMAIN_VAR} env"))
        };
        pub static ref WEBSITE_LINK: String = format!("https://{}", *WEBSITE_DOMAIN);
        pub static ref BOT_LINK: String = "https://t.me/V_Proxy_bot".to_string();
        pub static ref NEWS_CHANNEL_USERNAME: String = "@VProxyNews".to_string();
        pub static ref REVIEWS_LINK: String = format!("https://{}/reviews", *WEBSITE_DOMAIN);
        pub static ref SUPPORT_USERNAME: String = "@VProxy_Support_bot".to_string();
        pub static ref DOCUMENTATION_RESELLER_API_URL: String = "https://documenter.getpostman.com/view/38661340/2sB2xFfnZs".to_string();
        pub static ref DOCUMENTATION_USER_API_URL: String = "https://documenter.getpostman.com/view/38661340/2sB2xFfnZr#a52f1cd4-a09c-4fd9-b5eb-e22bdc0873ed".to_string();
        pub static ref BOT_USERNAME: String = "@V_Proxy_bot".to_string();
        pub static ref PROD_DB_URL: String = { // FIXME(nrv): this shit refuses to allow itself to be used in any way. dynamic resolution hardcoded for now directly at the place.
            env::var(PROD_DB_URL_VAR)
                .unwrap_or_else(|_| panic!("Unable to read {PROD_DB_URL_VAR} env"))
        };
    }
}

use consts::*;

pub fn no_preview() -> LinkPreviewOptions {
    LinkPreviewOptions {
        is_disabled: true,
        url: None,
        prefer_small_media: false,
        prefer_large_media: false,
        show_above_text: false,
    }
}


pub async fn init_envs() {
    rust_shared::repository::api::init_envs().await;
    let _ = &*WEBSITE_DOMAIN;
    let _ = &*BOT_USERNAME;
}
