package com.artfess.cqlt.manager.impl;

import com.artfess.base.entity.CqltTreeModel;
import com.artfess.base.enums.DelStatusEnum;
import com.artfess.base.enums.SubjectTypeEnum;
import com.artfess.base.manager.impl.BaseManagerImpl;
import com.artfess.base.util.BeanUtils;
import com.artfess.cqlt.dao.QfSubjectInfoDao;
import com.artfess.cqlt.manager.QfSubjectInfoManager;
import com.artfess.cqlt.manager.QfSubjectInternationalInfoManager;
import com.artfess.cqlt.manager.QfSubjectRelationManager;
import com.artfess.cqlt.model.QfSubjectInfo;
import com.artfess.cqlt.model.QfSubjectInternationalInfo;
import com.artfess.cqlt.model.QfSubjectRelation;
import com.artfess.sysConfig.persistence.manager.SysDictionaryManager;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;

/**
 * 国内准则科目信息 服务实现类
 *
 * @author min.wu
 * @company 阿特菲斯信息技术有限公司
 * @since 2023-02-08
 */
@Service
public class QfSubjectInfoManagerImpl extends BaseManagerImpl<QfSubjectInfoDao, QfSubjectInfo> implements QfSubjectInfoManager {

    @Resource
    private QfSubjectRelationManager qfSubjectRelationService;

    @Resource
    private QfSubjectInternationalInfoManager subjectInternationalInfoManager;

    @Resource
    private SysDictionaryManager sdm;

    @Override
    public List<QfSubjectInfo> getTree(QfSubjectInfo entity) {
        QueryWrapper<QfSubjectInfo> queryWrapper = new QueryWrapper();
        if (StringUtils.isNotBlank(entity.getCode())) {
            queryWrapper.like("code_", entity.getCode());
        }

        if (StringUtils.isNotBlank(entity.getName())) {
            queryWrapper.like("name_", entity.getName());
        }

        queryWrapper.eq("is_dele_", DelStatusEnum.N.getType());
        queryWrapper.orderByAsc("sn_");
        List<QfSubjectInfo> sysList = this.baseMapper.selectList(queryWrapper);
        List<QfSubjectInfo> tree = BeanUtils.listToTree(sysList);
        return tree;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void associatedSubject(QfSubjectInfo t) {
        if (CollectionUtils.isEmpty(t.getList())) {
            return;
        }

        QueryWrapper<QfSubjectRelation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sub_id_", t.getId());
        qfSubjectRelationService.getBaseMapper().delete(queryWrapper);
        qfSubjectRelationService.saveBatch(t.getList());
    }

    @Override
    public QfSubjectInfo findById(String id) {
        QfSubjectInfo qfSubjectInfo = this.baseMapper.selectById(id);
        QueryWrapper<QfSubjectRelation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sub_id_", id);
        List<QfSubjectRelation> qfSubjectRelations = qfSubjectRelationService.getBaseMapper().selectList(queryWrapper);
        qfSubjectRelations.forEach(qfSubjectRelation -> {
            QfSubjectInternationalInfo qfSubjectInternationalInfos = subjectInternationalInfoManager.getBaseMapper().selectById(qfSubjectRelation.getInterId());
            if (null != qfSubjectInternationalInfos) {
                qfSubjectRelation.setInternationalName(qfSubjectInternationalInfos.getName());
            }
        });
        qfSubjectInfo.setList(qfSubjectRelations);

        return qfSubjectInfo;
    }

    @Override
    @Transactional
    public boolean importExcel(List<QfSubjectInfo> list) {

        List<QfSubjectRelation> relationData = Lists.newArrayList();
        List<QfSubjectInternationalInfo> internationalInfos = subjectInternationalInfoManager.list();

        // BUG记录：客户给出的数据中，PL层级是从上往下正常的，但BS和CF层级是反的，直接插入将会导致树结构数据填充异常，先按照层级排序确保所有父级先被保存
        list.stream()
                .sorted(Comparator.comparing(QfSubjectInfo::getLevel))
                .forEach(subject -> {
                    subject.setType(SubjectTypeEnum.getType(subject.getType()));
                    if (subject.getLevel() == 1) {
                        subject.setParentId("0");
                    }
                    QueryWrapper<QfSubjectInfo> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("code_", subject.getParentCode());
                    QfSubjectInfo qfSubjectInfo = this.baseMapper.selectOne(queryWrapper);
                    if (null != qfSubjectInfo) {
                        subject.setParentId(qfSubjectInfo.getId());
                    }
                    subject.setName(subject.getSubjectName());
                    subject.setCode(subject.getSubjectCode());
                    subject.setSn(subject.getLevel());

                    String relation = subject.getRelation();
                    if (null == relation) {
                        return;
                    }
                    subject.setRelation(subject.getRelation().replace("无", ""));
                    boolean isExpression = relation.contains("+") || relation.contains("-");
                    if (isExpression) {
                        subject.setExpression(relation);
                    }
                    this.newInsertTree(subject);
                    // 不再使用关联数据
//                    if (!isExpression) {
//                        List<String> relations = Arrays.asList(subject.getRelation().split("[,]"));
//                        relations.forEach(r -> {
//                            internationalInfos.forEach(inter -> {
//                                if (inter.getCode().equals(r)) {
//                                    QfSubjectRelation relationTemp = new QfSubjectRelation();
//                                    relationTemp.setSubId(subject.getId());
//                                    relationTemp.setSubCode(subject.getCode());
//                                    relationTemp.setInternationalName(inter.getName());
//                                    relationTemp.setInterCode(inter.getCode());
//                                    relationTemp.setInterId(inter.getId());
//                                    if (isExpression) {
//                                        relationTemp.setExpression(relation);
//                                    }
//                                    relationData.add(relationTemp);
//                                }
//                            });
//                        });
//                    }
                });
//        qfSubjectRelationService.saveBatch(relationData);

        return true;
    }

    @Override
    @Transactional
    public String newSaveTree(CqltTreeModel e, boolean useDefaultCheck) {
        QfSubjectInfo entity = (QfSubjectInfo) e;
        QfSubjectInfoDao m = super.getBaseMapper();
        if (useDefaultCheck) {
            List<QfSubjectInfo> duplicateEntities = findDuplicateEntities(entity.getId(), entity.getParentId(), entity.getCode(), entity.getName());
            QfSubjectInfo other = null;
            if (duplicateEntities.size() > 0) {
                other = duplicateEntities.get(0);
            }
            entity.checkConstraints(other);
        }

        if (entity.isNew()) {
            entity.setHasChildren(Integer.valueOf(0));
            m.insert(entity);
        }

        QueryWrapper<QfSubjectInfo> queryWrapper = new QueryWrapper<QfSubjectInfo>();
        queryWrapper.eq("code_", entity.getParentCode());
        QfSubjectInfo parent = baseMapper.selectOne(queryWrapper);
        e.buildFullIdAndName(parent);
        if (e.getSn() == null) {
            e.setSn(Integer.valueOf(parent == null ? 1 : parent.getHasChildren().intValue() + 1));
        }
        m.updateById(entity);

        if (parent != null) {
            QueryWrapper<QfSubjectInfo> queryWrappe = new QueryWrapper<QfSubjectInfo>();
            queryWrappe.eq(StringUtils.isNotEmpty(entity.getParentCode()), "parent_code_", entity.getParentCode());
            Integer childrenCount = this.baseMapper.selectCount(queryWrappe);
            parent.setHasChildren(childrenCount);
            m.updateById(parent);
        }

        return entity.getId();
    }

}

