use std::sync::mpsc::{Sender};
use json::{array, JsonValue, object};
use crate::{BtnColor, BtnMode, PLUGIN_TOOLS, PLUGIN_TX, Response, Tools};
use crate::model::{ModelTemp};

/// 动作
pub trait Action {
    /// 作者
    fn author(&mut self) -> &'static str {
        return "Blue Rain";
    }
    /// 动标题
    fn title(&mut self) -> &'static str;
    /// 动作api
    fn api(&mut self) -> &'static str;

    /// 支持模式
    /// org 企业模式
    /// admin 平台模式
    /// user 普通模式
    fn mode(&mut self) -> Vec<&'static str> {
        return vec![];
    }
    /// 菜单
    fn menu(&mut self) -> bool { return false; }
    /// 菜单 icon
    fn icon(&mut self) -> &'static str { return ""; }

    /// 菜单排序
    fn menu_sort(&mut self) -> usize { return 0; }
    /// 标签
    fn tags(&mut self) -> Vec<&'static str> { return vec![]; }

    /// 是否使用密钥
    fn token(&mut self) -> bool { true }
    /// API描述
    fn describe(&mut self) -> &'static str { return ""; }
    /// 是否公开
    fn public(&mut self) -> bool { true }
    /// 是否权限组显示
    fn auth(&mut self) -> bool { true }
    /// 接口类型 btn api
    fn interface_type(&mut self) -> &'static str {
        ""
    }
    /// 依赖接口
    fn dependent(&mut self) -> Vec<&'static str> {
        return vec![];
    }
    /// 请求参数入口
    fn params(&mut self) -> JsonValue { object! {} }
    /// 检测
    fn _check(&mut self, mut request: JsonValue) -> (bool, String, JsonValue) {
        let params = self.params();
        let mut new_request = object! {};
        for (key, field) in params.entries() {
            if request[key].is_null() && field["require"].as_bool().unwrap() {
                return (false, format!("缺少参数 {}:{}", key, field["title"]), request);
            }
            if request[key].is_null() && !field["require"].as_bool().unwrap() {
                request[key] = field["def"].clone().into();
            }
            if (request[key] == "" || request[key].is_empty()) && !field["require"].as_bool().unwrap() {
                request[key] = field["def"].clone().into();
            }
            if request[key] == JsonValue::from("null") {
                request[key] = field["def"].clone().into();
            }
            new_request[key] = request[key].clone();
        }
        return (true, "验证通过".to_string(), new_request);
    }
    /// 执行参数入口
    fn run(&mut self, header: JsonValue, request: JsonValue) -> Response {
        let (state, msg, request) = self._check(request.clone());
        if !state {
            return self.fail(&*msg);
        }
        return self.index(header.clone(), request.clone());
    }

    fn index(&mut self, header: JsonValue, request: JsonValue) -> Response;
    /// 业务成功返回
    fn success(&mut self, data: JsonValue, msg: &str) -> Response {
        Response::success(data, msg).clone()
    }
    /// 业务错误返回
    fn fail(&mut self, msg: &str) -> Response {
        Response::fail(msg).clone()
    }
    /// 登陆返回
    fn login(&mut self, msg: &str) -> Response {
        Response::login(msg).clone()
    }
    /// 下载返回
    fn download(&mut self, filename: &str) -> Response {
        Response::download(filename).clone()
    }
    /// 重定型返回
    fn redirect(&mut self, url: &str) -> Response {
        Response::redirect(url).clone()
    }
    /// 获取工具集合
    fn tools(&mut self) -> Tools {
        PLUGIN_TOOLS.lock().unwrap().get("tools").unwrap().clone()
    }
    /// 获取共享消息通道
    fn tx(&mut self) -> Sender<JsonValue> {
        PLUGIN_TX.lock().unwrap().get("tx").unwrap().clone()
    }
    /// 获取菜单信息
    /// * title 菜单名称
    fn menu_info(&mut self, title: &str) -> JsonValue {
        let apis: Vec<&str> = self.api().split(".").collect();
        let info = object! {
            title:if title=="" {self.title()}else{title},
            api:self.api(),
            addon:apis[0],
            model:apis[1],
            action:apis[2],
            icon:self.icon(),
            path:format!("/{}",self.api().replace(".","/")),
            auth:self.auth()
        };
        info
    }
    fn btn_info_data(&mut self, title: &str) -> JsonValue {
        let mut params = array![];
        for (_field, item) in self.params().entries() {
            params.push(item.clone()).unwrap();
        }
        let apis: Vec<&str> = self.api().split(".").collect();
        let info = object! {
            title:if title=="" {self.title()}else{title},
            api:self.api(),
            addon:apis[0],
            model:apis[1],
            action:apis[2],
            icon:self.icon(),
            path:format!("/{}",self.api().replace(".","/")),
            auth:self.auth(),
            params:params
        };
        info
    }
    /// 获取按钮信息
    /// * title 菜单名称
    /// * mode 按钮模式
    /// * color 按钮颜色
    /// * match_condition 显示条件
    fn btn_info(&mut self, title: &str, mode: BtnMode, color: BtnColor, match_condition: Vec<Vec<&str>>) -> JsonValue {
        let mut btn = object! {};
        if title.is_empty() {
            btn["title"] = self.title().into();
        } else {
            btn["title"] = title.into();
        }
        btn["api"] = self.api().into();
        let mut params = array![];
        for (_, item) in self.params().entries() {
            params.push(item.clone()).unwrap();
        }
        btn["params"] = JsonValue::from(params);
        btn["color"] = JsonValue::from(color.from());
        btn["icon"] = JsonValue::from(self.icon());
        btn["mode"] = JsonValue::from(mode.from());
        btn["match_condition"] = match_condition.into();
        return btn;
    }
    /// 获取跳转按钮信息
    /// * title 菜单名称
    /// * mode 按钮模式
    /// * color 按钮颜色
    /// * match_condition 显示条件
    fn btn_info_to(&mut self, title: &str, path: &str, mode: BtnMode, color: BtnColor, match_condition: Vec<Vec<&str>>) -> JsonValue {
        let mut btn = object! {};
        if title.is_empty() {
            btn["title"] = self.title().into();
        } else {
            btn["title"] = title.into();
        }
        btn["api"] = self.api().into();
        let mut params = array![];
        for (_, item) in self.params().entries() {
            params.push(item.clone()).unwrap();
        }
        if path == "" {
            btn["path"] = format!("/{}", self.api().replace(".", "/")).into();
        } else {
            btn["path"] = JsonValue::from(path);
        }
        btn["params"] = JsonValue::from(params);
        btn["color"] = JsonValue::from(color.from());
        btn["mode"] = JsonValue::from(mode.from());
        btn["match_condition"] = match_condition.into();
        return btn;
    }
    /// 获取自定义页面按钮信息
    /// * title 菜单名称
    /// * mode 按钮模式
    /// * color 按钮颜色
    /// * match_condition 显示条件
    fn btn_custom_info(&mut self, title: &str) -> JsonValue {
        let mut btn = object! {};
        if title.is_empty() {
            btn["title"] = self.title().into();
        } else {
            btn["title"] = title.into();
        }
        btn["api"] = self.api().into();
        let mut params = array![];
        for (_, item) in self.params().entries() {
            params.push(item.clone()).unwrap();
        }
        btn["params"] = JsonValue::from(params);
        btn["auth"] = self.auth().into();
        return btn;
    }
}


/// 模型模版
pub struct ActionTemp {
    pub model: ModelTemp,
}

impl Action for ActionTemp {
    fn title(&mut self) -> &'static str {
        "测试api"
    }
    fn api(&mut self) -> &'static str { "addon_temp.model_temp.action_temp" }
    fn index(&mut self, _header: JsonValue, _request: JsonValue) -> Response {
        return self.fail("无效API");
    }
}