use std::{env, fs};

use json::{JsonValue, object};

use br_db::Db;
use br_db::config::Config;
#[cfg(any(feature = "default", feature = "cache"))]
use br_cache::Cache;
#[cfg(any(feature = "default", feature = "kafka"))]
use br_kafka::Kafka;

use lazy_static::lazy_static;
use std::sync::Mutex;
use std::collections::HashMap;
use std::process::exit;
#[cfg(any(feature = "default", feature = "cache"))]
use br_cache::CacheConfig;
#[cfg(any(feature = "default", feature = "mail"))]
use br_email::Mail;
use log::info;

pub mod addon;
pub mod model;
pub mod action;

/// 集合工具
#[derive(Clone)]
pub struct Tools {
    pub db: Db,
    #[cfg(any(feature = "default", feature = "cache"))]
    pub cache: Cache,
    #[cfg(any(feature = "default", feature = "kafka"))]
    pub kafka: Kafka,
    #[cfg(any(feature = "default", feature = "mail"))]
    pub mail: Mail,
}

impl Tools {
    pub fn new() -> Self {
        Self {
            db: Db::None,
            #[cfg(any(feature = "default", feature = "cache"))]
            cache: Cache::connect(object! {}),
            #[cfg(any(feature = "default", feature = "kafka"))]
            kafka: Kafka::connect(object! {}),
            #[cfg(any(feature = "default", feature = "mail"))]
            mail: Mail::default(),
        }
    }
    pub fn set_db(&mut self, config_path: &str) -> &mut Self {
        let conf = fs::read_to_string(config_path.clone());
        match conf {
            Ok(str) => {
                match json::parse(str.as_str().clone()) {
                    Ok(config) => {
                        self.db = Db::new(config);
                        PLUGIN_TOOLS.lock().unwrap().insert("tools".to_string(), self.clone());
                    }
                    Err(e) => {
                        info!("数据库配置文件错误: {}",e.to_string());
                    }
                }
            }
            Err(_) => {
                let data = Config::default().to_json();
                fs::write(config_path, data.to_string()).expect("创建数据库配置文件失败");
                exit(0)
            }
        }
        self
    }
    pub fn set_db_json(&mut self, config: JsonValue) -> &mut Self {
        self.db = Db::new(config);
        PLUGIN_TOOLS.lock().unwrap().insert("tools".to_string(), self.clone());
        self
    }
    #[cfg(any(feature = "default", feature = "cache"))]
    pub fn set_cache(&mut self, config_path: &str) -> &mut Self {
        let conf = fs::read_to_string(config_path.clone());
        match conf {
            Ok(str) => {
                match json::parse(str.as_str().clone()) {
                    Ok(config) => {
                        self.cache = Cache::connect(config);
                        PLUGIN_TOOLS.lock().unwrap().insert("tools".to_string(), self.clone());
                    }
                    Err(e) => {
                        info!("缓存配置文件错误: {}",e.to_string());
                    }
                }
            }
            Err(_) => {
                let data = CacheConfig::default().to_json();
                fs::write(config_path, data.to_string()).expect("创建缓存配置文件失败");
                exit(101)
            }
        }


        self
    }
    #[cfg(any(feature = "default", feature = "kafka"))]
    pub fn set_kafka(&mut self, config_path: &str) -> &mut Self {
        let conf = fs::read_to_string(config_path.clone()).unwrap();
        match json::parse(conf.as_str().clone()) {
            Ok(config) => {
                self.kafka = Kafka::connect(config);
                PLUGIN_TOOLS.lock().unwrap().insert("tools".to_string(), self.clone());
            }
            Err(e) => {
                println!("kafka配置文件错误: {}", e.to_string());
            }
        }
        self
    }
    #[cfg(any(feature = "default", feature = "mail"))]
    pub fn set_mail(&mut self, config_path: &str) -> &mut Self {
        let conf = fs::read_to_string(config_path.clone());
        match conf {
            Ok(e) => {
                match json::parse(e.as_str().clone()) {
                    Ok(config) => {
                        self.mail = Mail::from(config.clone());
                        PLUGIN_TOOLS.lock().unwrap().insert("tools".to_string(), self.clone());
                    }
                    Err(e) => {
                        println!("配置文件错误: {}", e.to_string());
                    }
                }
            }
            Err(_) => {
                Mail::new(config_path);
                exit(102)
            }
        }

        self
    }
    // #[cfg(any(feature = "default", feature = "wechat"))]
    // pub fn set_wechat(&mut self, config_path: &str) -> &mut Self {
    //     let conf = fs::read_to_string(config_path.clone());
    //     match conf {
    //         Ok(e) => {
    //             match json::parse(e.as_str().clone()) {
    //                 Ok(config) => {
    //                     self.wechat = Wechat::new(config);
    //                     PLUGIN_TOOLS.lock().unwrap().insert("tools".to_string(), self.clone());
    //                 }
    //                 Err(e) => {
    //                     println!("微信配置文件错误: {}", e.to_string());
    //                 }
    //             }
    //         }
    //         Err(_) => {
    //             exit(103)
    //         }
    //     }
    //     self
    // }
}

lazy_static! {
    /// 工具集合
    pub static ref PLUGIN_TOOLS: Mutex<HashMap<String,Tools>> =Mutex::new(HashMap::new());
}


/// 按钮颜色
pub enum BtnColor {
    Red,
    Blue,
    Yellow,
    Green,
}

impl BtnColor {
    fn from(self) -> &'static str {
        match self {
            BtnColor::Red => "red",
            BtnColor::Blue => "blue",
            BtnColor::Yellow => "yellow",
            BtnColor::Green => "green",
        }
    }
}

/// 按钮模式
pub enum BtnMode {
    Form,
    Url,
    Api,
    Download,
    Path,
}

impl BtnMode {
    fn from(self) -> &'static str {
        match self {
            BtnMode::Form => "form",
            BtnMode::Api => "api",
            BtnMode::Download => "download",
            BtnMode::Url => "url",
            BtnMode::Path => "path",
        }
    }
}

/// 返回响应
#[derive(Clone, Debug)]
pub struct Response(i32, &'static str, JsonValue);

impl Response {
    /// 获取状态
    pub fn get_code(self) -> i32 {
        self.0
    }
    /// 获取消息
    pub fn get_msg(self) -> &'static str {
        self.1
    }
    /// 获取数据
    pub fn get_data(self) -> JsonValue {
        self.2
    }
    /// 获取业务数据
    pub fn get_data_data(self) -> JsonValue {
        self.get_data()["data"].clone()
    }
    /// 获取业务反馈编号
    pub fn get_data_code(self) -> i32 {
        self.get_data()["code"].as_i32().unwrap()
    }
    /// 获取业务提示消息
    pub fn get_data_msg(self) -> String {
        self.get_data()["msg"].to_string()
    }
    pub fn into(self) -> (i32, &'static str, JsonValue) {
        return (self.0, self.1, self.2);
    }
    /// 成功
    pub fn success(data: JsonValue, msg: &str) -> Self {
        let data = object! {code: 0,data:data,msg: msg.to_string()};
        Self(200, "json", data)
    }
    /// 失败
    pub fn fail(msg: &str) -> Self {
        let data = object! {
            code: -1,
            msg: msg.to_string()
        };
        Self(200, "json", data)
    }
    /// 登陆
    pub fn login(msg: &str) -> Self {
        let data = object! {code: 1000,msg: msg.to_string(),};
        Self(200, "json", data)
    }
    /// 下载
    pub fn download(filename: &str) -> Self {
        Self(200, "download", filename.into())
    }
    /// 重定向
    pub fn redirect(url: &str) -> Self {
        Self(301, "url", url.into())
    }
}

pub struct ApiModel {}

impl ApiModel {
    pub fn run(args_new: Vec<String>) -> (bool, String, String, String, String, JsonValue) {
        let mut args: Vec<String> = env::args().collect();
        if args_new.len() > 0 {
            args = args_new.clone();
        }
        if args.len() <= 1 {
            return (false, "参数错误".to_string(), "".to_string(), "".to_string(), "".to_string(), object! {});
        }
        let mode = args[1].as_str();
        let api = args[2].as_str();
        if api.is_empty() {
            return (false, "无API参数".to_string(), "".to_string(), "".to_string(), "".to_string(), object! {});
        }
        let api: Vec<&str> = api.split(".").collect();
        if api.len() != 3 {
            return (false, "API参数错误".to_string(), "".to_string(), "".to_string(), "".to_string(), object! {});
        }
        let data = args[3].as_str();
        if data.is_empty() {
            return (false, "请求参数无效".to_string(), "".to_string(), "".to_string(), "".to_string(), object! {});
        }
        let data = json::parse(data).unwrap();
        return (true, mode.to_string(), api[0].to_string(), api[1].to_string(), api[2].to_string(), data);
    }
    pub fn fail(msg: &str) -> JsonValue {
        let data = object! {code:-1,msg:msg};
        return data;
    }
}


