package cn.com.capcloud.api.action.service;

import cn.com.capcloud.api.action.service.util.TextUtil;
import cn.com.capcloud.ccui.core.common.json.JackJSON;
import cn.com.capcloud.ccui.core.common.json.JackJSONArray;
import cn.com.capcloud.ccui.core.common.json.JackJSONObject;
import cn.com.capcloud.ccui.core.common.utils.StringUtil;
import cn.com.capcloud.ccui.core.common.utils.UUIDUtils;
import cn.com.capcloud.core.noentitydb.JtPage;
import cn.com.capcloud.core.noentitydb.MongoTool;
import cn.com.capcloud.core.system.user.User;
import cn.com.capcloud.core.system.user.UserService;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @Author LiaoJiaHui
 * @Create 2022/9/22 10:14
 */
@Service
public class MongoService {

    @Value("${rzth.mongodb.isCreateMongoDBConnect:N}")
    private  String isCreateMongoDBConnect;
    @Autowired
    private ApiService apiService;
    @Autowired
    private DataSourceService dsService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private UserService userService;

    // mysql: apiController > apiAction > apiService
    // mongo: apiController > apiAction > 扩展类 > mongoService
    // 呜呜呜呜~ mongoService调用是在扩展类调的
    public JtPage showAll(String jsonStr, JackJSONObject retJson, HttpServletRequest request, JtPage jtPage) {
        if(!isCreateMongoDBConnect.equals("Y")){
            jtPage.setTotalElements( 0);
            jtPage.setNumber(0);
            jtPage.setNumberOfElements(0);
            jtPage.setSize(0);
            jtPage.setContent(new ArrayList<>());
            return jtPage;
        }
        User user=userService.getUser(request);
        Map<String,Object> queryMap=dsService.getQuery(jsonStr);
        String viewAllRoleId=String.valueOf(queryMap.get("view_all_data_role_id"));
        boolean isQueryAll=false;
        if(StringUtil.isNotEmpty(viewAllRoleId)) {
            String[] roleIdArray = viewAllRoleId.split(",");
            for(int i=0;i<roleIdArray.length;i++) {
                if(StringUtil.isNotEmpty(roleIdArray[i])&&userService.isExistsRole(roleIdArray[i], user.getId())) {
                    isQueryAll=true;
                }
            }
        }
        if(!isQueryAll){//如果查询mongo校验用户是否有查询全部数据角色，没有则判断权限不足
            retJson.putAll(JackJSONObject.fromObject(apiService.getReturnDataByCode("4031")));
            return null;
        }
        JackJSONObject jsonObject = JackJSONObject.fromObject(jsonStr);
        Integer page =Integer.parseInt(String.valueOf(jsonObject.getJackJSONObject("queryParam").get("page")));
        Integer pageSize =Integer.parseInt(String.valueOf(jsonObject.getJackJSONObject("queryParam").get("pageSize")));
        Map<String, Object> dsMap=dsService.findDataSourceByJsonStr(jsonStr);
        String tableName=String.valueOf(dsMap.get("ds_table_name"));
        Query query;
        Query queryCount;
        List<Map> listMap;
        List<Map<String,Object>> fieldList=dsService.getQueryInfo(jsonStr);
        query=getMongoWhere(fieldList,jsonStr,jdbcTemplate,retJson);
        queryCount=getMongoWhere(fieldList,jsonStr,jdbcTemplate,retJson);
        query.limit(pageSize).skip(page*pageSize);//分页
        Sort sort=getMongoOrderBy(jsonStr);//排序
        query.with(sort);
        listMap=mongoTemplate.find(query, Map.class,tableName);
        long count=mongoTemplate.count(queryCount,tableName);
        List<Map<String,Object>> content=new ArrayList<>();
        for (int i = 0; i < listMap.size(); i++) {
            listMap.get(i).remove("_id");
            content.add(listMap.get(i));
        }
        content= JackJSON.parseObject(TextUtil.nullToStrFilter(content), ArrayList.class);
        jtPage.setTotalElements((int) count);
        if (count % pageSize == 0) {
            jtPage.setTotalPages((int) count/pageSize);
        } else {
            jtPage.setTotalPages((int) count/pageSize+1);
        }
        jtPage.setNumber(page);
        jtPage.setNumberOfElements((int) count);
        jtPage.setSize(pageSize);
        jtPage.setContent(content);
        return jtPage;
    }

    public JackJSONArray save(String jsonStr, JackJSONObject retJson, HttpServletRequest request, JackJSONArray array) {
        if(!isCreateMongoDBConnect.equals("Y")){
            return new JackJSONArray();
        }
        Map<String, Object> dsMap=dsService.findDataSourceByJsonStr(jsonStr);
        String tableName=String.valueOf(dsMap.get("ds_table_name"));
        for (int i = 0; i < array.size(); i++) {
            Map<String, Object> map = array.getJackJSONObject(i);
            save(tableName,map);
        }
        retJson.putAll(JackJSONObject.fromObject(apiService.getReturnDataByCode("ok")));
        Map<String,Object> map=new HashMap<>();
        map.put("saveData",array);
        retJson.put("data",map);
        return new JackJSONArray();
    }

    public void save(String tableName, Map<String,Object> map){
        if(!isCreateMongoDBConnect.equals("Y")){
            return ;
        }
        setDefaultValue(map);
        MongoTool.save(tableName,map,mongoTemplate);
    }

    //set一些默认值
    public void setDefaultValue(Map<String,Object> objMap){
        if(StringUtil.isEmpty(objMap.get("status"))){
            objMap.put("status","0");
        }
        if(StringUtil.isEmpty(objMap.get("create_time"))){
            DateTime d = new DateTime();
            String time=d.toString("yyyy-MM-dd HH:mm:ss");
            objMap.put("create_time", time);
            objMap.put("update_time", time);
        }
        if(StringUtil.isEmpty(objMap.get("uuid"))){
            objMap.put("uuid", UUIDUtils.randomUuidWithoutHyphen());
        }
    }

    public Sort getMongoOrderBy(String jsonStr){
        JackJSONObject jsonObject = JackJSONObject.fromObject(jsonStr).getJackJSONObject("queryParam");
        try {
            jsonObject.size();
        } catch (Exception e) {
            jsonObject=new JackJSONObject();
        }
        Map<String,Object> dsMap=dsService.findDataSourceByJsonStr(jsonStr);
        Map<String,Object> queryMap=dsService.getQuery(jsonStr);
        String dsPkId = String.valueOf(dsMap.get("ds_pk_id"));
        String defaultSortType = "desc";
        String sortField = String.valueOf(jsonObject.get("sortField"));
        String sortType = String.valueOf(jsonObject.get("sortType"));
        if (StringUtil.isEmpty(sortField)) {
            sortField=String.valueOf(queryMap.get("default_sort_field"));
            if(StringUtil.isEmpty(sortField)){
                sortField = dsPkId;
            }
        }
        if (StringUtil.isEmpty(sortType)) {
            sortType=String.valueOf(queryMap.get("default_sort_type"));
            if(StringUtil.isEmpty(sortType)){
                sortType = defaultSortType;
            }
        }
        Sort sort;
        if(sortType.equals("desc")){
            sort = Sort.by(
                    Sort.Order.desc(sortField)
                    //,Sort.Order.desc("create_time") //支持多字段排序
            );
        }else{
            sort = Sort.by(
                    Sort.Order.asc(sortField)
            );
        }
        return sort;
    }

    public Query getMongoWhere(List<Map<String,Object>> fieldList, String jsonStr, JdbcTemplate jdbcTemplate, JackJSONObject retJson){
        JackJSONObject queryParamJson=JackJSONObject.fromObject(jsonStr).getJackJSONObject("queryParam");
        try {
            queryParamJson.size();
        } catch (Exception e) {
            return new Query();
        }
        return getMongoWhereByFieldInfo(fieldList,jsonStr,jdbcTemplate,retJson);
    }

    /*
    现在只有模糊查询和精确查询
     */
    public Query getMongoWhereByFieldInfo(List<Map<String,Object>> fieldList, String jsonStr, JdbcTemplate jdbcTemplate, JackJSONObject retJson){
        JackJSONObject requestJson=JackJSONObject.fromObject(jsonStr);
        JackJSONObject queryParamJson=requestJson.getJackJSONObject("queryParam");
        Map<String,Object> map=new HashMap<>();
        String whereSql="";
        Criteria criteria=new Criteria();
        for (int i = 0; i < fieldList.size(); i++) {
            String fieldName=String.valueOf(fieldList.get(i).get("name"));
            String fieldValue=String.valueOf(queryParamJson.get(fieldName));
            map.put(fieldName,fieldList.get(i));//map里存一份用field做key
            // 点查询
            if (StringUtil.isNotEmpty(fieldList.get(i).get("is_query")) && fieldList.get(i).get("is_query").equals("Y")
                    && StringUtil.isNotEmpty(fieldList.get(i).get("query_type")) && fieldList.get(i).get("query_type").equals("0")
                    && !"null".equals(fieldValue)) {
                if (!(fieldName.equals("starttime") || fieldName.equals("endtime"))) {
                    if (fieldList.get(i).get("type").equals("String")) {
                        String isFuzzySearch=String.valueOf(fieldList.get(i).get("is_fuzzy_search"));
                        if (fieldList.get(i).get("show_type").equals("checkbox")){
                            String checkStr=fieldValue;
                            if(!"".equals(checkStr)){
                                String[] checkboxArray = fieldValue.split(",");
                                for (int j = 0; j < checkboxArray.length; j++) {
                                    //whereSql += " and FIND_IN_SET('" +checkboxArray[j]+"',"+ fieldName + ")";
                                    //todo 啊这，得研究一下mongo怎么写
                                }
                            }
                        }else if (String.valueOf(fieldList.get(i).get("show_type")).equals("tree")){
                            String treeValue=fieldValue;
                            String isRecursion=String.valueOf(queryParamJson.get("isRecursion"));
                            if(!"".equals(treeValue)&&("null".equals(isRecursion)||isRecursion.equals("Y"))){
                                whereSql += " and FIND_IN_SET(" +fieldName+","+fieldList.get(i).get("dict_code")+"('"+ treeValue + "'))";
                                whereSql += " and " + fieldName + " != ''";
                            }else if(!"".equals(treeValue)&&isRecursion.equals("N")){
                                whereSql += " and " + fieldName + " = '"+fieldValue+"'";
                            }
                        }else if (StringUtil.isNotEmpty(isFuzzySearch)&&isFuzzySearch.equals("0")) {
                            if (StringUtil.isNotEmpty(fieldValue)) {
                                // 模糊查询下
                                criteria.and(fieldName+"").regex(fieldValue+"");
                            }
                        }else if (StringUtil.isNotEmpty(isFuzzySearch)&&isFuzzySearch.equals("2")) {
                            if (StringUtil.isNotEmpty(fieldValue)) {
                                // 精确查询
                                criteria.and(fieldName+"").is(fieldValue);
                            }
                        }
                    } else if (StringUtil.isNotEmpty(fieldValue)) {
                        if(fieldName.equals("create_org_id")) {
                            whereSql += " and " + fieldName + " in (" + fieldValue+")";
                        }
                    }
                }
            }
        }
        return new Query(criteria);
    }
}

