use json::{object, JsonValue};
#[derive(Clone, Debug)]
pub enum Fields {
    String,
    StringPass,
    StringKey,
    StringTel,
    StringIdent,
    StringEmail,
    StringColor,
    StringCode,
    StringBarcode,
    StringQrcode,
    Radio,
    Select,
    TableList,
    TableTree,
    Int,
    Switch,
    Dict,
    Text,
    TextEditor,
    TextUrl,
    Json,
    Array,
    Object,
    Float,
    DateTime,
    Year,
}
impl Fields {
    pub fn name(&mut self, name: &str) -> Field {
        Field::new(self.clone(), name)
    }
    pub fn str(self) -> &'static str {
        match self {
            Fields::String | Fields::StringPass | Fields::StringKey | Fields::StringTel | Fields::StringIdent | Fields::StringEmail | Fields::StringColor | Fields::StringCode | Fields::StringBarcode | Fields::StringQrcode => "string",
            Fields::Radio => "radio",
            Fields::Select => "select",
            Fields::TableList => "table",
            Fields::TableTree => "tree",
            Fields::Int => "int",
            Fields::Switch => "bool",
            Fields::Dict => "string",
            Fields::Text | Fields::TextEditor | Fields::TextUrl => "text",
            Fields::Json => "json",
            Fields::Array => "array",
            Fields::Object => "object",
            Fields::Float => "float",
            Fields::DateTime => "datetime",
            Fields::Year => "year",
        }
    }
}
#[derive(Debug)]
pub struct Field {
    mode: Fields,
    /// 必填
    require: bool,
    field: String,
    title: String,
    /// 默认值
    def: JsonValue,
    /// 长度
    length: usize,
    /// 小数点位数
    dec: usize,
    /// 选择项目
    option: Vec<&'static str>,
    /// 是否显示
    show: bool,
    describe: String,
    /// 示例
    example: JsonValue,
    /// 接口
    api: String,
    /// 表名称
    table_name: String,
    /// 是否多选
    multiple: bool,
}

impl Field {
    pub fn new(mode: Fields, name: &str) -> Field {
        Self {
            mode,
            require: true,
            field: name.to_string(),
            title: "".to_string(),
            def: JsonValue::Null,
            length: 0,
            dec: 0,
            option: vec![],
            show: true,
            describe: "".to_string(),
            example: JsonValue::Null,
            api: "".to_string(),
            table_name: "".to_string(),
            multiple: false,
        }
    }
    pub fn title(mut self, name: &str) -> Field {
        self.title = name.to_string();
        self
    }
    /// 默认值
    pub fn def(mut self, name: JsonValue) -> Field {
        self.def = name;
        self
    }
    pub fn require(mut self, require: bool) -> Field {
        self.require = require;
        self
    }
    pub fn show(mut self, show: bool) -> Field {
        self.show = show;
        self
    }
    pub fn example(mut self, example: JsonValue) -> Field {
        self.example = example;
        self
    }
    pub fn length(mut self, length: usize) -> Field {
        self.length = length;
        self
    }
    pub fn describe(mut self, describe: &str) -> Field {
        self.describe = describe.to_string();
        self
    }
    pub fn option(mut self, option: Vec<&'static str>) -> Field {
        self.option = option;
        self
    }
    /// 关联数据表配置
    pub fn table(mut self, table: &str, api: &str, fields: Vec<&'static str>) -> Field {
        self.api = api.to_string();
        self.table_name = table.to_string();
        self.option = fields;
        self
    }
    pub fn multiple(mut self, multiple: bool, count: usize) -> Field {
        self.multiple = multiple;
        if count == 0 {
            self.length = 1
        } else {
            self.length = count;
        }
        self
    }
    pub fn dec(mut self, dec: usize) -> Field {
        self.dec = dec;
        self
    }
    pub fn sql(self) -> JsonValue {
        object! {}
    }
    pub fn swagger(self) -> JsonValue {
        object! {
            "type": self.mode.str(),
            "example": self.example,
        }
    }
    pub fn field(self) -> JsonValue {
        let example = if self.example.is_empty() {
            self.def.clone()
        } else {
            self.example
        };
        let mut field = object! {
            "require"=> self.require,
            "field"=> self.field,
            "title"=> self.title,
            "show"=> self.show,
            "describe"=> self.describe,
            "example"=> example
        };
        match self.mode {
            Fields::String | Fields::StringPass | Fields::StringKey | Fields::StringTel | Fields::StringIdent | Fields::StringEmail | Fields::StringColor | Fields::StringCode | Fields::StringBarcode | Fields::StringQrcode => {
                field["length"] = self.length.into();
                field["def"] = self.def;
            }
            Fields::Radio => {
                field["option"] = self.option.into();
                field["def"] = self.def;
            }
            Fields::Select => {
                field["option"] = self.option.into();
                field["def"] = self.def;
            }
            Fields::TableList | Fields::TableTree | Fields::Dict => {
                field["option"] = self.option.into();
                field["def"] = self.def;
                field["api"] = self.api.into();
                field["table"] = self.table_name.into();
                field["multiple"] = self.multiple.into();
                field["length"] = self.length.into();
            }
            Fields::Int => {
                field["length"] = self.length.into();
                field["def"] = self.def;
            }
            Fields::Switch => {
                field["def"] = self.def;
            }
            Fields::Text | Fields::TextEditor | Fields::TextUrl | Fields::Json | Fields::Array | Fields::Object => {
                field["length"] = self.length.into();
                field["def"] = self.def;
            }
            Fields::Float => {
                field["length"] = self.length.into();
                field["dec"] = self.dec.into();
                field["def"] = self.def;
            }
            Fields::DateTime => {
                field["def"] = self.def;
            }
            Fields::Year => {
                field["def"] = self.def;
            }
        };
        field
    }
}
mod test {
    #[allow(unused_imports)]
    use crate::fields::Fields;
    #[test]
    fn test() {
        let res = Fields::String.name("Test").title("花球").def("话".into()).describe("哈哈哈").field();
        println!("{res:#}");
        let res = Fields::TableList.name("Test").title("花球").def("话".into()).describe("哈哈哈").table("tree", "atata.dadasd.ads", vec!["12313", "!2313123"]).multiple(false, 1).field();
        println!("{res:#}");
        let res = Fields::Int.name("Test").require(false).show(false).title("花球").describe("哈哈哈").length(20).def(1.into()).field();
        println!("{res:#}");
        let res = Fields::Radio.name("Test").title("花球").describe("哈哈哈").option(vec!["开心", "不开心"]).def("开心".into()).example("12313".into()).field();
        println!("{res:#}");
        let res = Fields::Select.name("Test").title("花球").describe("哈哈哈").option(vec!["开心", "不开心"]).def(vec!["开心", "不开心"].into()).example(vec!["开心", "不开心"].into()).field();
        println!("{res:#}");
        let res = Fields::Float.name("Test").title("花球").length(20).dec(3).def(1.02.into()).example(3.into()).field();
        println!("{res:#}");
    }
}
