package com.ruoyi.system.service.other;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.system.domain.other.BsCommon;
import com.ruoyi.system.domain.other.BsCommonExample;
import com.ruoyi.system.domain.other.vo.BsCommonVO;
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 BsCommonFacadeService {

    @Autowired
    private BsCommonService bsCommonService;

    public String commit(BsCommon 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(BsCommon body, AjaxResult result) {
        if (null == body) {
            result.buildError(500, "body为空");
            return false;
        }

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

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

        BsCommon bsCommon = new BsCommon();
        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.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(BsCommon body, AjaxResult result) {
        if (null == body) {
            result.buildError(500, "body为空");
            return false;
        }

        return true;
    }

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

        if (!bean.getCode().equals(body.getCode())) {
            BsCommonExample example = new BsCommonExample();
            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 BsCommon get(String id, BsCommon bsCommon) {
        if (null == bsCommon) {
            if (StringUtils.isNotEmpty(id)) {
                bsCommon = bsCommonService.selectByPrimaryKey(id);
            }
            if (null == bsCommon) {
                return null;
            }
        }

        return bsCommon;
    }

    public boolean deletePre(BsCommon 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(BsCommon body, AjaxResult result) {
        BsCommon bean = get(body.getId(), null);
        if (null == bean) {
            result.buildError(500, "找不到该数据");
            return;
        }

        // 如果该网格下有子网格，则无法删除
        BsCommonExample gridRegionExample = new BsCommonExample();
        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(BsCommonVO bsCommonVO) {
        BsCommonExample bsCommonExample = new BsCommonExample();
        BsCommonExample.Criteria criteria = bsCommonExample.createCriteria();
        criteria.andIsValidEqualTo("1");
        if(bsCommonVO != null){
            if(StringUtils.isNotBlank(bsCommonVO.getCode())){
                criteria.andCodeLike("%"+bsCommonVO.getCode()+"%");
            }
        }
        bsCommonExample.setOrderByClause(" sort + 0 ");
        List<BsCommon> bsCommons = bsCommonService.selectByExample(bsCommonExample);
        List<Map<String, Object>> jsTreeModels = convertFrBomsCommon(bsCommons);
        return AjaxResult.success("success", jsTreeModels);
    }

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

        if (!CollectionUtils.isEmpty(bsCommons)) {
            for (BsCommon 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());
                    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<BsCommon> bsCommons, String parentId) {
        List<Map<String, Object>> models = new ArrayList<>();

        for (BsCommon 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}?)");
    }
}
