package com.yunzhupaas.base.service.impl;


import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yunzhupaas.base.entity.DictionaryDataEntity;
import com.yunzhupaas.base.entity.VisualKitEntity;
import com.yunzhupaas.base.mapper.VisualKitMapper;
import com.yunzhupaas.base.model.visualkit.KitPagination;
import com.yunzhupaas.base.model.visualkit.KitTreeVo;
import com.yunzhupaas.base.model.visualkit.VisualKitForm;
import com.yunzhupaas.base.service.DictionaryDataService;
import com.yunzhupaas.base.service.SuperServiceImpl;
import com.yunzhupaas.base.service.VisualKitService;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.exception.DataException;
import com.yunzhupaas.util.JsonUtil;
import com.yunzhupaas.util.RandomUtil;
import com.yunzhupaas.util.StringUtil;
import com.yunzhupaas.util.UserProvider;
import com.yunzhupaas.util.enums.DictionaryDataEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 表单套件
 *
 * @author 云筑产品开发平台组
 * @version v5.1.0
 * @copyright 深圳市乐程软件有限公司
 * @date 2024/8/22 11:11:35
 */
@Service
public class VisualKitServiceImpl extends SuperServiceImpl<VisualKitMapper, VisualKitEntity> implements VisualKitService {

    
    @Autowired
    private DictionaryDataService dictionaryDataService;

    @Override
    public List<VisualKitEntity> getList(KitPagination pagination) {
        // 定义变量判断是否需要使用修改时间倒序
        boolean flag = false;
        QueryWrapper<VisualKitEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().select(VisualKitEntity::getId, VisualKitEntity::getFullName, VisualKitEntity::getEnCode, VisualKitEntity::getCategory,
                VisualKitEntity::getIcon, VisualKitEntity::getCreatorUserId, VisualKitEntity::getCreatorTime, VisualKitEntity::getLastModifyTime,
                VisualKitEntity::getSortCode, VisualKitEntity::getEnabledMark);
        if (StringUtil.isNotEmpty(pagination.getKeyword())) {
            flag = true;
            queryWrapper.lambda().and(t -> t.like(VisualKitEntity::getFullName, pagination.getKeyword())
                    .or().like(VisualKitEntity::getEnCode, pagination.getKeyword())
            );
        }

        if (StringUtil.isNotEmpty(pagination.getCategory())) {
            flag = true;
            queryWrapper.lambda().eq(VisualKitEntity::getCategory, pagination.getCategory());
        }

        if (pagination.getEnabledMark() != null) {
            flag = true;
            queryWrapper.lambda().eq(VisualKitEntity::getEnabledMark, pagination.getEnabledMark());
        }

        //排序
        queryWrapper.lambda().orderByAsc(VisualKitEntity::getSortCode)
                .orderByDesc(VisualKitEntity::getCreatorTime);
        if (flag) {
            queryWrapper.lambda().orderByDesc(VisualKitEntity::getLastModifyTime);
        }
        Page<VisualKitEntity> page = new Page<>(pagination.getCurrentPage(), pagination.getPageSize());
        IPage<VisualKitEntity> iPage = this.page(page, queryWrapper);
        return pagination.setData(iPage.getRecords(), iPage.getTotal());
    }

    @Override
    public void saveCheck(VisualKitEntity visualKitEntity, Boolean fullNameCheck, Boolean encodeCheck) {
        String fullName = visualKitEntity.getFullName();
        String encode = visualKitEntity.getEnCode();
        // 名称长度验证
        if (fullName.length() > 80) {
            throw new DataException(MsgCode.EXIST005.get());
        }
        QueryWrapper<VisualKitEntity> query = new QueryWrapper<>();
        //重名验证
        if (fullNameCheck) {
            query.lambda().eq(VisualKitEntity::getFullName, fullName);
            if (this.list(query).size() > 0) {
                throw new DataException(MsgCode.EXIST001.get());
            }
        }
        //编码验证
        if (encodeCheck) {
            query.clear();
            query.lambda().eq(VisualKitEntity::getEnCode, encode);
            if (this.list(query).size() > 0) {
                throw new DataException(MsgCode.EXIST002.get());
            }
        }
    }

    @Override
    public void create(VisualKitForm form) {
        clearFormDataTable(form);
        VisualKitEntity entity = JsonUtil.getJsonToBean(form, VisualKitEntity.class);
        this.saveCheck(entity, true, true);
        if (StringUtil.isEmpty(form.getId())) {
            entity.setId(RandomUtil.uuId());
        }
        entity.setCreatorUserId(UserProvider.getUser().getUserId());
        entity.setCreatorTime(new Date());
        this.save(entity);
        form.setId(entity.getId());
    }

    @Override
    public boolean update(String id, VisualKitForm form) {
        clearFormDataTable(form);
        VisualKitEntity entity = JsonUtil.getJsonToBean(form, VisualKitEntity.class);
        VisualKitEntity byId = this.getById(id);
        this.saveCheck(entity, !byId.getFullName().equals(form.getFullName()), !byId.getEnCode().equals(form.getEnCode()));
        entity.setLastModifyUserId(UserProvider.getUser().getUserId());
        entity.setLastModifyTime(new Date());
        return this.updateById(entity);
    }

    @Override
    public List<KitTreeVo> selectorList() {
        List<DictionaryDataEntity> typeList = dictionaryDataService.getListByTypeDataCode(DictionaryDataEnum.VISUALDEV.getDictionaryTypeId());
        QueryWrapper<VisualKitEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(VisualKitEntity::getEnabledMark, 1);
        queryWrapper.lambda().orderByAsc(VisualKitEntity::getSortCode)
                .orderByDesc(VisualKitEntity::getCreatorTime);
        List<VisualKitEntity> list = this.list(queryWrapper);
        Map<String, List<VisualKitEntity>> collect = list.stream().collect(Collectors.groupingBy(VisualKitEntity::getCategory));
        List<KitTreeVo> resList = new ArrayList<>();
        for (String key : collect.keySet()) {
            DictionaryDataEntity dataEntity = typeList.stream().filter(t -> t.getId().equals(key)).findFirst().orElse(new DictionaryDataEntity());
            KitTreeVo kitTreeVo = new KitTreeVo();
            kitTreeVo.setId(key);
            kitTreeVo.setFullName(dataEntity.getFullName());
            kitTreeVo.setEnCode(dataEntity.getEnCode());
            kitTreeVo.setHasChildren(true);
            List<VisualKitEntity> visualKitEntities = collect.get(key);
            List<KitTreeVo> jsonToList = JsonUtil.getJsonToList(visualKitEntities, KitTreeVo.class);
            jsonToList.forEach(t -> {
                t.setParentId(key);
            });
            kitTreeVo.setChildren(jsonToList);
            resList.add(kitTreeVo);
        }
        return resList;
    }

    @Override
    public void actionsCopy(String id) {
        VisualKitEntity entity = this.getById(id);
        String copyNum = UUID.randomUUID().toString().substring(0, 5);
        String fullName = entity.getFullName() + ".副本" + copyNum;
        if (fullName.length() > 80) {
            throw new DataException(MsgCode.PRI006.get());
        }
        VisualKitForm form = JsonUtil.getJsonToBean(entity, VisualKitForm.class);
        form.setId(RandomUtil.uuId());
        form.setFullName(fullName);
        form.setEnCode(entity.getEnCode() + copyNum);
        form.setEnabledMark(0);
        this.create(form);
    }

    @Override
    public String importData(VisualKitEntity entity, Integer type) {
        QueryWrapper<VisualKitEntity> queryWrapper = new QueryWrapper<>();
        StringJoiner stringJoiner = new StringJoiner("、");
        if (this.getById(entity.getId()) != null) {
            if (Objects.equals(type, 0)) {
                stringJoiner.add("ID");
            } else {
                entity.setId(RandomUtil.uuId());
            }
        }
        queryWrapper.clear();
        queryWrapper.lambda().eq(VisualKitEntity::getEnCode, entity.getEnCode());
        if (this.count(queryWrapper) > 0) {
            stringJoiner.add(MsgCode.IMP009.get());
        }
        queryWrapper.clear();
        queryWrapper.lambda().eq(VisualKitEntity::getFullName, entity.getFullName());
        if (this.count(queryWrapper) > 0) {
            stringJoiner.add(MsgCode.IMP008.get());
        }
        if (stringJoiner.length() > 0 && ObjectUtil.equal(type, 1)) {
            String copyNum = UUID.randomUUID().toString().substring(0, 5);
            entity.setFullName(entity.getFullName() + ".副本" + copyNum);
            entity.setEnCode(entity.getEnCode() + copyNum);
        } else if (ObjectUtil.equal(type, 0) && stringJoiner.length() > 0) {
            return stringJoiner.toString() + MsgCode.IMP007.get();
        }
        entity.setEnabledMark(0);
        entity.setCreatorTime(new Date());
        entity.setCreatorUserId(UserProvider.getLoginUserId());
        entity.setLastModifyTime(null);
        entity.setLastModifyUserId(null);
        this.save(entity);
        return "";
    }

    /**
     * 清空formdata内的表信息
     *
     * @param form
     */
    private void clearFormDataTable(VisualKitForm form) {
        Map<String, Object> formMap = JsonUtil.stringToMap(form.getFormData());
        JSONArray formJsonArray = JsonUtil.getJsonToJsonArray(String.valueOf(formMap.get("fields")));
        this.recuClearTable(formJsonArray);
        formMap.put("fields", formJsonArray);
        form.setFormData(JsonUtil.getObjectToString(formMap));
    }

    /**
     * 递归清除
     *
     * @param formJsonArray
     */
    private void recuClearTable(JSONArray formJsonArray) {
        for (Object o : formJsonArray) {
            JSONObject jsonObject = (JSONObject) o;
            JSONObject config = jsonObject.getJSONObject("__config__");
            boolean hasChange = false;
            if (ObjectUtil.isNotEmpty(config.get("tableName"))) {
                config.put("tableName", "");
                hasChange = true;
            }
            if (ObjectUtil.isNotEmpty(config.get("relationTable"))) {
                config.put("relationTable", "");
                hasChange = true;
            }
            JSONArray childArray = config.getJSONArray("children");
            if (ObjectUtil.isNotEmpty(childArray)) {
                this.recuClearTable(childArray);
                config.put("children", childArray);
                hasChange = true;
            }
            if (hasChange) {
                jsonObject.put("__config__", config);
            }
        }
    }
}

