package com.xunmei.core.resumption.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xunmei.common.core.constant.SecurityConstants;
import com.xunmei.common.core.utils.IDHelper;
import com.xunmei.common.core.web.page.TableDataInfo;
import com.xunmei.core.resumption.domain.AppRule;
import com.xunmei.core.resumption.domain.AppRuleItem;
import com.xunmei.core.resumption.domain.AppRulePoint;
import com.xunmei.core.resumption.dto.appRuleItem.AppRuleItemDetailDto;
import com.xunmei.core.resumption.dto.appRuleItem.AppRuleItemPageDto;
import com.xunmei.core.resumption.dto.appRuleItem.AppRulePointSelectPageDto;
import com.xunmei.core.resumption.dto.appRulePoint.AppRulePointDetailDto;
import com.xunmei.core.resumption.mapper.AppRuleItemMapper;
import com.xunmei.core.resumption.mapper.AppRuleMapper;
import com.xunmei.core.resumption.mapper.AppRulePointMapper;
import com.xunmei.core.resumption.dto.appRuleItem.AppRuleItemDto;
import com.xunmei.core.resumption.dto.appRulePoint.AppRulePointDto;
import com.xunmei.core.resumption.service.IAppRuleItemService;
import com.xunmei.core.resumption.service.IAppRulePointService;
import com.xunmei.core.resumption.vo.appRuleItem.AppRuleItemPageVo;
import com.xunmei.core.resumption.vo.appRuleItem.AppRulePointSelectVo;
import com.xunmei.core.resumption.vo.appRuleItem.RuleTreeItem;
import com.xunmei.system.api.Eto.OrgListByTypesConditionEto;
import com.xunmei.system.api.RemoteOrgService;
import com.xunmei.system.api.domain.SysOrg;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jingyuanchao
 * @since 2022-04-27
 */
@Service
public class AppRuleItemServiceImpl extends ServiceImpl<AppRuleItemMapper, AppRuleItem> implements IAppRuleItemService {
    @Resource
    private AppRuleItemMapper appRuleItemMapper;
    @Resource
    private IAppRulePointService appRulePointService;
    @Resource
    private AppRulePointMapper appRulePointMapper;
//    @Resource
//    private SysDictDetailService sysDictDetailService;

    @Resource
    RemoteOrgService remoteOrgService;
    @Resource
    private AppRuleMapper appRuleMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public long edit(AppRuleItemDto appRuleItemDto) {
        final AppRuleItem item = new AppRuleItem();
        BeanUtils.copyProperties(appRuleItemDto, item);
//        if (item.getId() == null) {
//            item.setId(IDHelper.id());
//        }

//        Integer num = appRuleItemMapper.checkItemNumRepeat(item.getId(), item.getRuleId(), item.getItemNum());
//        if (num > 0) {
//            throw new RuntimeException("检查项编号重复");
//        }

        Integer itemNameNums = appRuleItemMapper.checkItemNameRepeat(item.getId(), item.getRuleId(), item.getName());
        if (itemNameNums > 0) {
            throw new RuntimeException("检查项名称重复");
        }

        final AppRule appRule = appRuleMapper.selectById(appRuleItemDto.getRuleId());
        if (appRule == null) {
            throw new RuntimeException("请选择具体规范新增数据!");
        }

        saveOrUpdate(item);
        final List<AppRulePointDto> pointDtoList = appRuleItemDto.getPointDtoList();
        Set<String> hashMap = new HashSet<>();
        for (AppRulePointDto appRulePointDto : pointDtoList) {
            if (hashMap.contains(appRulePointDto.getName())) {
                throw new RuntimeException("履职内容重复!");
            }
            hashMap.add(appRulePointDto.getName());
        }


        final List<Long> pointIds = appRulePointMapper.selectPointIds(item.getId());
        if (pointIds.size() > 0) {
            List<Long> idList2 = pointDtoList.stream().map(AppRulePointDto::getId).collect(Collectors.toList());
            for (Long pointId : pointIds) {
                if (!idList2.contains(pointId)) {
                    Integer isUsed = appRulePointMapper.checkIsUsed(pointId);
                    if (isUsed == null) {
                        appRulePointMapper.deleteById(pointId);
                    } else {
                        throw new RuntimeException("有要点已被使用，不能删除!");
                    }
                }
            }
        }


        for (AppRulePointDto appRulePointDto : pointDtoList) {
            AppRulePoint point = new AppRulePoint();
            BeanUtils.copyProperties(appRulePointDto, point);
            point.setItemId(item.getId());
            point.setRuleId(item.getRuleId());
            if (point.getId() == null) {
                //新增
                point.setId(IDHelper.id());

                appRulePointService.save(point);
            } else {
                //修改
                Integer isUsed = appRulePointMapper.checkIsUsed(point.getId());
                if (isUsed == null) {
                    appRulePointService.updateById(point);
                } else {
                    //将之前的记录逻辑删除,然后新增一条记录关联到检查项
                    appRulePointMapper.updateDeleted(point.getId(), 1);
                    Long newId = IDHelper.id();
                    appRulePointMapper.updatePlanItem(point.getId(), newId);
                    point.setId(newId);
                    appRulePointMapper.insert(point);

                }
            }
        }
        return item.getId();
    }

    @Override
    public TableDataInfo pageQuery(AppRuleItemPageDto itemPageDto) {
        Page<AppRuleItemPageVo> page;

        page = appRuleItemMapper.pageQuery(itemPageDto.getPageDto(), itemPageDto);
        int order = itemPageDto.getPage() * itemPageDto.getSize();
        for (AppRuleItemPageVo vo : page.getRecords()) {
            vo.setOrder(++order);
            final List<AppRulePointDetailDto> pointList = appRulePointMapper.selectDataListByItemId(vo.getId());
            vo.setPointDtoList(pointList);
        }

        return TableDataInfo.success(page);
    }

    @Override
    public AppRuleItemDetailDto findOne(Long id) {
        final AppRuleItem appRuleItem = appRuleItemMapper.selectById(id);
        if (ObjectUtil.isNull(appRuleItem)) {
            return null;
        }
        AppRuleItemDetailDto appRuleItemDto = new AppRuleItemDetailDto();
        BeanUtils.copyProperties(appRuleItem, appRuleItemDto);

        List<AppRulePointDetailDto> list = appRulePointMapper.selectDataListByItemId(id);
        appRuleItemDto.setPointDtoList(list);
        return appRuleItemDto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean del(Long id) {
        List<Long> idList = appRulePointMapper.selectPointIds(id);
        if (idList.size() > 0) {

            Integer num1 = appRulePointMapper.checkIsJoinResumptionPlan(idList);
            if (ObjectUtil.isNotNull(num1)) {
                throw new RuntimeException("该检查项已被检查计划或履职计划关联,请先删除检查计划或履职计划!");
            }
        }
        appRuleItemMapper.deleteById(id);
        appRulePointMapper.deleteByMap(MapUtil.of("item_id", id));
        return true;
    }

    @Override
    public List<RuleTreeItem> getRuleTree(Long orgId) {
        List<RuleTreeItem> tree = new ArrayList<>();
        List<SysOrg> orgs = remoteOrgService
                .listByTypes(OrgListByTypesConditionEto.builder().orgId(orgId).orgTypes(Arrays.asList("1", "2", "3", "4", "11")).build())
                .getData();
        if (ObjectUtil.isEmpty(orgs)) {
            return tree;
        }
        Map<Long, SysOrg> orgMap = orgs.stream().collect(Collectors.toMap(o -> o.getId(), o -> o));
        List<SysOrg> tops = orgs.stream().filter(o -> !orgMap.containsKey(o.getParentId())).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(tops)) {
            return tree;
        }
        List<Long> orgIds = orgs.stream().map(o -> o.getId()).collect(Collectors.toList());
        List<AppRule> rules = appRuleMapper.selectList(new LambdaQueryWrapper<AppRule>().in(AppRule::getOrgId, orgIds));

        tree = tops.stream().map(o -> generateTree(o, orgs, rules)).collect(Collectors.toList());

        return tree;
    }

    private RuleTreeItem generateTree(SysOrg parent, List<SysOrg> allOrg, List<AppRule> allRule) {
        RuleTreeItem item = RuleTreeItem.builder().isRule(0).id(parent.getId()).label(parent.getName()).children(new ArrayList<>()).build();
        List<RuleTreeItem> ruleItems = allRule.stream().filter(r -> ObjectUtil.equal(r.getOrgId(), parent.getId()))
                .map(o -> RuleTreeItem.builder().isRule(1).id(o.getId()).label(o.getName()).orgType(parent.getType().toString()).build())
                .collect(Collectors.toList());
        item.getChildren().addAll(ruleItems);

        List<SysOrg> children = allOrg.stream()
                .filter(o -> ObjectUtil.equal(o.getParentId(), parent.getId()))
                .collect(Collectors.toList());
        for (SysOrg child : children) {
            item.getChildren().add(generateTree(child, allOrg, allRule));
        }

        return item;
    }

    /**
     * 获取履职内容选择框的翻页列表
     *
     * @param dto
     * @return
     */
    @Override
    public TableDataInfo pointSelectionPage(AppRulePointSelectPageDto dto) {
        Page<AppRulePointSelectVo> page = dto.getPageDto();
        page = appRulePointMapper.pointSelectionPage(page, dto);
        return TableDataInfo.success(page);
    }

//    @Override
//    public SysDictListDto dict() {
//        final SysDictListDto dto = new SysDictListDto();
//        final List<SysDictDetail> detailList = sysDictDetailService.all();
//        final List<SysDictDetail> checkMethodList = detailList.stream().filter(detail -> "check_method".equals(detail.getDictCode())).collect(Collectors.toList());
//        final List<SysDictDetail> checkTypeList = detailList.stream().filter(detail -> "check_type".equals(detail.getDictCode())).collect(Collectors.toList());
//        final List<SysDictDetail> rectifyTremList = detailList.stream().filter(detail -> "rectify_trem".equals(detail.getDictCode())).collect(Collectors.toList());
//        dto.setCheckTypeList(checkTypeList);
//        dto.setRectifyTremList(rectifyTremList);
//        dto.setCheckMethodList(checkMethodList);
//        return dto;
//    }

//    @Override
//    public List<SecBookDtInstDto> dataType() {
//
//        return appRuleItemMapper.selectDataTypeList();
//    }
//
//    @Override
//    public List<AreaListVo> selectCheckAreaList() {
//        return appRuleItemMapper.selectCheckAreaList();
//    }

//    @Override
//    public JsonResponse<?> checkRepeat(AppRuleItemCheckDto checkDto) {
//        if (checkDto.getItemNum() != null) {
//            Integer num = appRuleItemMapper.checkItemNumRepeat(checkDto.getItemId(), checkDto.getRuleId(), checkDto.getItemNum());
//            if (num > 0) {
//                return JsonResponse.fail("检查项编号重复!");
//            }
//        }
//        if (checkDto.getPointNum() != null) {
//            Integer num = appRulePointMapper.checkPointNumRepeat(checkDto.getItemId(), checkDto.getPointId(), checkDto.getPointNum());
//            if (num > 0) {
//                return JsonResponse.fail("要点编号重复!");
//            }
//        }
//        if (!StringUtil.isNullOrEmpty(checkDto.getPointName())) {
//            Integer num = appRulePointMapper.checkPointNameRepeat(checkDto.getItemId(), checkDto.getPointId(), checkDto.getPointName());
//            if (num > 0) {
//                return JsonResponse.fail("要点名称重复!");
//            }
//        }
//        return JsonResponse.success();
//    }
}
