package com.ruoyi.system.service.other;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.system.domain.other.Labels;
import com.ruoyi.system.domain.other.LabelsExample;
import com.ruoyi.system.domain.other.vo.LabelsVO;
import com.ruoyi.system.mapper.other.LabelsMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Method;
import java.util.*;

/**
 * @Auther: hxc
 * @Date: 2019/6/18 0018 09:23
 * @Description: 数据字典
 */
@Component
public class LabelsFacadeService {

    @Autowired
    private LabelsService bsCommonService;

    @Autowired
    private LabelsMapper labelsMapper;

    public String commit(Labels body, String method) {
        try {
            AjaxResult result = new AjaxResult();

            Method methodCheck = null;
            try {
                methodCheck = this.getClass().getMethod(method + "Pre", body.getClass(), result.getClass());
            } catch (Exception e) {
                methodCheck = null;
            }
            if (null != methodCheck) {
                Object ret = methodCheck.invoke(this, body, result);
                if ((ret instanceof Boolean) && !(boolean) ret) {
                    return JSON.toJSONString(result);
                }
            }

            Method methodCommit = null;
            try {
                methodCommit = this.getClass().getMethod(method, body.getClass(), result.getClass());
            } catch (Exception e) {
                methodCommit = null;
            }
            if (null == methodCommit) {
                return JSON.toJSONString(AjaxResult.error(600, "方法未找到:" + method));
            }

            methodCommit.invoke(this, body, result);
            return JSON.toJSONString(result);
        } catch (Exception e) {
            e.printStackTrace();
            return JSON.toJSONString(AjaxResult.error(500, "服务器内部错误"));
        }
    }

    public boolean insertPre(Labels body, AjaxResult result) {
        if (null == body) {
            result.buildError(500, "body为空");
            return false;
        }

        LabelsExample example = new LabelsExample();
        example.createCriteria().andCodeEqualTo(body.getCode());
        int count = bsCommonService.countByExample(example);
        if (count > 0) {
            result.buildError(500, "编码存在，请重新填写！");
            return false;
        }
        return true;
    }

    public void insert(Labels body, AjaxResult result) {
        String id = UUID.randomUUID().toString();

        Labels bsCommon = new Labels();
        bsCommon.setId(id);
        bsCommon.setCode(body.getCode());
        bsCommon.setDescription(body.getDescription());
        bsCommon.setName(body.getName());
        bsCommon.setParentId(body.getParentId());
        bsCommon.setIsValid(body.getIsValid());
        bsCommon.setSort(body.getSort());
        bsCommon.setScope(body.getScope());
        bsCommon.setYlzd1(body.getYlzd1());
        bsCommon.setYlzd2(body.getYlzd2());
        bsCommon.setYlzd3(body.getYlzd3());
        bsCommon.setYlzd4(body.getYlzd4());
        bsCommon.setYlzd5(body.getYlzd5());

        int ret = bsCommonService.insertSelective(bsCommon);
        if (ret > 0) {
            result.buildSuccess("success", id);
        } else {
            result.buildError(600, "新增失败");
        }
        return;
    }


    public boolean updatePre(Labels body, AjaxResult result) {
        if (null == body) {
            result.buildError(500, "body为空");
            return false;
        }

        return true;
    }

    public void update(Labels body, AjaxResult result) {
        String id = body.getId();
        Labels bean = get(id, null);
        if (null == bean) {
            result.buildError(500, "body为空");
            return;
        }

        if (!bean.getCode().equals(body.getCode())) {
            LabelsExample example = new LabelsExample();
            example.createCriteria().andCodeEqualTo(body.getCode());
            int count = bsCommonService.countByExample(example);
            if (count > 0) {
                result.buildError(500, "编码存在，请重新填写！");
                return;
            }
        }

        int ret = bsCommonService.updateByPrimaryKeySelective(body);
        if (ret > 0) {
            result.buildSuccess("success", id);
        } else {
            result.buildError(600, "更新失败");
        }
        return;
    }

    public Labels get(String id, Labels bsCommon) {
        if (null == bsCommon) {
            if (StringUtils.isNotEmpty(id)) {
                bsCommon = bsCommonService.selectByPrimaryKey(id);
            }
            if (null == bsCommon) {
                return null;
            }
        }

        return bsCommon;
    }

    public boolean deletePre(Labels body, AjaxResult result) {
        if (null == body) {
            result.buildError(500, "body为空");
            return false;
        }

        if (!itemIsUUID(body.getId())) {
            result.buildError(500, "参数非法");
            return false;
        }

        return true;
    }

    public void delete(Labels body, AjaxResult result) {
        Labels bean = get(body.getId(), null);
        if (null == bean) {
            result.buildError(500, "找不到该数据");
            return;
        }

        // 如果该网格下有子网格，则无法删除
        LabelsExample gridRegionExample = new LabelsExample();
        gridRegionExample.createCriteria().andIsValidEqualTo("1").andParentIdEqualTo(body.getId());
        int count = bsCommonService.countByExample(gridRegionExample);
        if (count > 0) {
            result.buildError(600, "有子数据无法删除");
            return;
        }

        // 防止数据残留
        int ret = bsCommonService.deleteByStringPrimaryKey(body.getId());
        if (ret > 0) {
            result.buildSuccess("success", null);
        } else {
            result.buildError(600, "删除失败");
        }

        return;
    }

    public AjaxResult getTreeNode(LabelsVO bsCommonVO) {
        LabelsExample bsCommonExample = new LabelsExample();
        LabelsExample.Criteria criteria = bsCommonExample.createCriteria();
        criteria.andIsValidEqualTo("1");
        if(bsCommonVO != null){
            if(StringUtils.isNotBlank(bsCommonVO.getCode())){
                criteria.andCodeLike("%"+bsCommonVO.getCode()+"%");
            }
//            if(StringUtils.isNotBlank(bsCommonVO.getScope())){
//                criteria.andScopeLike("%"+bsCommonVO.getScope()+"%");
//            }
        }
        bsCommonExample.setOrderByClause(" sort + 0 ");
        List<Labels> bsCommons = bsCommonService.selectByExample(bsCommonExample);
        List<Map<String, Object>> jsTreeModels = convertFrBomsCommon(bsCommons);
        if(bsCommonVO == null || StringUtils.isBlank(bsCommonVO.getScope())){
            return AjaxResult.success("success", jsTreeModels);
        }
        List<Map<String, Object>> res = new ArrayList<>();
        for (Map<String, Object> map : jsTreeModels) {
            String scope = (String) map.get("scope");
            if(scope == null){
                continue;
            }
            if(scope.contains(bsCommonVO.getScope())){
                res.add(map);
            }
        }
        return AjaxResult.success("success", res);
    }

    private List<Map<String, Object>> convertFrBomsCommon(List<Labels> bsCommons) {
        List<Map<String, Object>> models = new ArrayList<>();

        if (!CollectionUtils.isEmpty(bsCommons)) {
            for (Labels bsCommon : bsCommons) {
                if (StringUtils.isEmpty(bsCommon.getParentId())) {
                    Map<String, Object> model = new HashMap<>();
                    model.put("id", bsCommon.getId());
                    model.put("code", bsCommon.getCode());
                    model.put("name", bsCommon.getName());
                    model.put("description", bsCommon.getDescription());
                    model.put("parentId", bsCommon.getParentId());
                    model.put("isValid", bsCommon.getIsValid());
                    model.put("sort", bsCommon.getSort());
                    model.put("scope", bsCommon.getScope());
                    List<Map<String, Object>> childrenDocTypes = convertFromWgCodeByParent(bsCommons, bsCommon.getId());
                    model.put("child", childrenDocTypes);
                    models.add(model);
                }
            }
        }
        return models;
    }


    private List<Map<String, Object>> convertFromWgCodeByParent(List<Labels> bsCommons, String parentId) {
        List<Map<String, Object>> models = new ArrayList<>();

        for (Labels bsCommon : bsCommons) {
            if (StringUtils.isNotEmpty(bsCommon.getParentId()) && bsCommon.getParentId().equals(parentId)) {
                Map<String, Object> model = new HashMap<>();
                model.put("id", bsCommon.getId());
                model.put("code", bsCommon.getCode());
                model.put("name", bsCommon.getName());
                model.put("description", bsCommon.getDescription());
                model.put("parentId", bsCommon.getParentId());
                model.put("isValid", bsCommon.getIsValid());
                model.put("sort", bsCommon.getSort());
                List<Map<String, Object>> childrenDocTypes = convertFromWgCodeByParent(bsCommons, bsCommon.getId());
                model.put("child", childrenDocTypes);
                models.add(model);
            }
        }
        return models;
    }

    private boolean itemIsUUID(String item) {
        if (StringUtils.isEmpty(item)) {
            return false;
        }
        return item.matches("(\\w{8}(-\\w{4}){3}-\\w{12}?)");
    }

    public AjaxResult threeToTree(List<String> codes){
        Set<String> codeSet = new HashSet<>();
        List<Labels> bsCommons = new ArrayList<>();
        for(String code : codes){
            String degree_one = labelsMapper.getDegreeOne(code);
            codeSet.add(degree_one);
        }
        for(String code : codeSet){
            LabelsExample bsCommonExample = new LabelsExample();
            LabelsExample.Criteria criteria = bsCommonExample.createCriteria();
            criteria.andIsValidEqualTo("1");
            if(StringUtils.isNotBlank(code)){
                criteria.andCodeLike("%"+code+"%");
            }
            bsCommonExample.setOrderByClause(" sort + 0 ");
            List<Labels> bsCommon = bsCommonService.selectByExample(bsCommonExample);
            bsCommons.addAll(bsCommon);
        }
        List<Map<String, Object>> jsTreeModels = convertFrBomsCommon(bsCommons);
        return AjaxResult.success(jsTreeModels);
    }

}
