package com.bohuikeji.frame.module.admin.entity.web.block;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bohuikeji.frame.module.admin.annotation.TableKeyField;
import com.bohuikeji.frame.module.admin.annotation.TableNewField;
import com.bohuikeji.frame.module.admin.annotation.TableQueryField;
import com.bohuikeji.frame.module.admin.base.EntityBase;
import com.bohuikeji.frame.module.admin.base.HtmlBlockFormBase;
import com.bohuikeji.frame.module.admin.entity.configure.BaseInputAn;
import com.bohuikeji.frame.module.admin.entity.configure.FieldConf;
import com.bohuikeji.frame.module.admin.entity.configure.KeyAn;
import com.bohuikeji.frame.module.admin.entity.configure.QueryAn;
import com.bohuikeji.frame.module.admin.entity.sys.SysRes;
import com.bohuikeji.frame.module.admin.entity.web.block.vo.Option;
import com.bohuikeji.frame.module.admin.utils.ReflectUtil;
import com.bohuikeji.frame.module.admin.utils.StringUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 下拉选择框元素块
 * @author 10552
 */
@Slf4j
@Data
public class SelectBlock extends HtmlBlockFormBase<SelectBlock> {
    public SelectBlock(){
        super();
    }
    public SelectBlock(Field field, EntityBase entity){
        super(field,entity);
        TableNewField tableNewField=field.getAnnotation(TableNewField.class);
        if (tableNewField==null){
            /**
             * 获取TableQueryField中的TableNewField注解
             */
            tableNewField=field.getAnnotation(TableQueryField.class).getClass().getInterfaces()[0].getAnnotation(TableNewField.class);
        }
            //先处理预置选项的方式
            for (String op:tableNewField.options()){
                this.options.add(new Option(op,op));
            }

        if (this.options.size()>0)return;

        TableKeyField tableKeyField=field.getAnnotation(TableKeyField.class);

        //未设置预置同时也未指定外键，则使用默认分组方式，
        if(tableKeyField==null||"".equals(tableKeyField.table())){
            List<Object> values=entity.selectJobs(
                    new QueryWrapper<String>()
                            .select(field.getAnnotation(TableField.class).value())
                            .groupBy(field.getAnnotation(TableField.class).value()));
            for (Object value:values){
                if(value!=null){
                    this.options.add(new Option(value.toString(),value));
                }
            }
            return;
        }
        /**
         * 指定为外键，设置控件支持下拉搜索
         */
        this.selectType="searchSelect";
        this.keyShowName=tableKeyField.keyShowFields();
        this.keyLikeName=tableKeyField.keyLikeFields();
        this.keyTableName= tableKeyField.table();
        if("".equals(keyTableName)){
            keyTableName=ReflectUtil.getTableName(tableKeyField.key());
        }
        try {
            this.keyWhere= URLEncoder.encode(tableKeyField.where(),"UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if(this.keyShowName.length==0){
            this.keyShowName=this.keyLikeName;
        }
        if (this.keyLikeName.length==0){
            this.keyLikeName=this.keyShowName;
        }
        if (this.keyLikeName.length==0){
            log.error("下拉选择控件初始化错误，未指定搜索字段和展示字段！位于[{}.{}]",field.getDeclaringClass(),field.getName());
            throw new RuntimeException("下拉选择控件初始化错误");
        }
        /*Class<?> modelClass=tableNewField.key();
        TableName tableName=modelClass.getAnnotation(TableName.class);
        this.keyTableName=tableName!=null?tableName.value(): CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, "modelClass.getSimpleName()");*/
    }

    /**
     * 下拉项
     */
    List<Option> options=new ArrayList<>();
    /**
     * 控件类型，默认为“select”类型
     * 【说明：】select类型，传统类型，仅支持下拉
     *          searchSelect类型，支持下拉搜索的类型
     */
    String selectType="select";
    /**
     * 外键展示的列
     */
    String[] keyShowName;
    /**
     * 外键用于支持模糊查询的列
     */
    String[] keyLikeName;
    /**
     * 外键指向的实体的全类名
     */
    String keyTableName;
    /**
     * 外键查询附加的where条件
     */
    String keyWhere;
    /**
     * 搜搜关键字
     */
    String searchKey;

    /**
     * 下拉项为外键处理
     * @param optionsMap
     * @return
     */
    public SelectBlock setOptions(List<Map<String, Object>> optionsMap) {
        List<Option> optionList=new ArrayList<>(optionsMap.size());
        for(Map<String,Object> map:optionsMap){
            Option option=new Option();
            for(String strKey:map.keySet()){
                switch (strKey){
                    case "key_id":
                        option.setKey(map.get("key_id").toString());break;
                    case "value_name":
                        option.setValue(map.get("value_name").toString());break;
                    default:
                        log.error("【组件初始化错误】：无法识别的参数类型{}",strKey);break;
                }
            }
            optionList.add(option);
        }
        this.options = optionList;
        return this;
    }

    /**
     * 转换显示字段为用逗号分隔的字符串
     * @return
     */
    public String toShowNameStr(){
        StringBuilder strb=new StringBuilder(60);
        for (String s:keyShowName){
            strb.append(s);
            strb.append(",");
        }
        strb.deleteCharAt(strb.length()-1);
        return strb.toString();
    }

    /**
     * 配置文件初始化方式
     * @param fieldConf
     * @param inputAn
     */
    public SelectBlock(FieldConf fieldConf, BaseInputAn inputAn){
        super(fieldConf,inputAn);
        String[] ops=inputAn.getOption();
        if(ops!=null&&ops.length>0){
            for(String op:ops){
                this.options.add(new Option(op,op));
            }
            return;
        }
        //未设置预置同时也未指定外键，则使用默认分组方式，
        KeyAn key=fieldConf.getKey();
        if(key==null|| StringUtils.isBlank(key.getTable())){
            String sql="select "+fieldConf.getColumnName()+" from "+fieldConf.getTableName()+" group by "+fieldConf.getColumnName();
            List<Object> values=(new SysRes()).sql().selectObjs(sql);
            for (Object value:values){
                if(value!=null){
                    this.options.add(new Option(value.toString(),value));
                }
            }
            return;
        }
        /**
         * 指定为外键，设置控件支持下拉搜索
         */

        this.selectType="searchSelect";
        this.keyShowName=key.getKeyShowFields();
        this.keyLikeName=key.getKeyLikeFields();
        this.keyTableName= key.getTable();
        try {
            this.keyWhere= URLEncoder.encode(key.getWhere(),"UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        if(this.keyShowName.length==0){
            this.keyShowName=this.keyLikeName;
        }
        if (this.keyLikeName.length==0){
            this.keyLikeName=this.keyShowName;
        }
        if (this.keyLikeName.length==0){
            log.error("下拉选择控件初始化错误，未指定搜索字段和展示字段！位于[{}.{}]",fieldConf.getTableName(),fieldConf.getFieldName());
            throw new RuntimeException("下拉选择控件初始化错误");
        }

    }
}
