package jnpf.qualifications.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jnpf.base.service.SuperServiceImpl;
import jnpf.entity.qualifications.QualificationsField;
import jnpf.entity.qualifications.QualificationsFieldCategory;
import jnpf.entity.qualifications.QualificationsFieldItem;
import jnpf.model.qualifications.dto.QualificationsDto;
import jnpf.model.qualifications.vo.QualificationsCategoryVo;
import jnpf.model.qualifications.vo.QualificationsItemsVo;
import jnpf.qualifications.mapper.QualificationsFieldMapper;
import jnpf.qualifications.service.QualificationsFieldCategoryService;
import jnpf.qualifications.service.QualificationsFieldItemService;
import jnpf.qualifications.service.QualificationsFieldService;
import jnpf.qualifications.service.QualificationsService;
import jnpf.util.ServiceException;
import jnpf.util.StringUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.filters.RemoteIpFilter;
import org.apache.commons.collections4.ListUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * todo
 *
 * @author Flynn Chan
 * @create 2024-03-04
 */
@Slf4j
@Service
public class QualificationsFieldServiceImpl extends SuperServiceImpl<QualificationsFieldMapper, QualificationsField> implements QualificationsFieldService {

    @Resource
    private QualificationsFieldCategoryService qualificationsFieldCategoryService;

    @Resource
    private QualificationsFieldItemService qualificationsFieldItemService;

    @Resource
    @Lazy
    private QualificationsService qualificationsService;
    @Override
    @Transactional
    public Boolean create(QualificationsDto qualificationsDto) {
        List<QualificationsFieldItem> qualificationsFieldItems = qualificationsDto.getQualificationsFieldItems();
        examine(qualificationsDto,0L);
        Long fieldCount = baseMapper.selectCount(Wrappers.<QualificationsField>query().lambda().eq(QualificationsField::getFId, qualificationsDto.getFieldId()));
        QualificationsField fileBuild = QualificationsField.builder()
                .name(qualificationsDto.getFieldName())
                .categoryId(qualificationsDto.getCategoryId())
                .itemNum(fieldCount+(long) qualificationsFieldItems.size())
                .propertyJson(qualificationsDto.getPropertyJson())
                .description(qualificationsDto.getDescription())
                .sortCode(qualificationsDto.getSortCode())
                .build();
        QualificationsField qualificationsField = baseMapper.selectOne(Wrappers.<QualificationsField>query()
                .lambda()
                .eq(QualificationsField::getCategoryId, qualificationsDto.getCategoryId())
                .eq(QualificationsField::getName, qualificationsDto.getFieldName()));
        fileBuild.setLastModifyTime(new Date());
        fileBuild.setCreatorTime(new Date());
        this.save(fileBuild);
        qualificationsFieldItems.forEach(item->{
            item.setFieldId(StringUtil.isNotNull(qualificationsField)?qualificationsField.getFId():fileBuild.getId());
            examine(item,0L);
            //注释项每一条都需要校验 因此循环 校验 添加
            qualificationsFieldItemService.save(item);
        });
        QualificationsFieldCategory categoryById = qualificationsFieldCategoryService.getCategoryById(qualificationsDto.getCategoryId());
        qualificationsFieldCategoryService.update(Wrappers.<QualificationsFieldCategory>update()
                .lambda()
                .set(QualificationsFieldCategory::getFieldNum,categoryById.getFieldNum()+1L)
                .eq(QualificationsFieldCategory::getId,qualificationsDto.getCategoryId()));
        return true;
    }

    private void examine(QualificationsFieldItem item,Long num) {
        Long itemCount = qualificationsFieldItemService.countItem(item.getFieldId(), item.getName());
        if(itemCount>num){
            throw new ServiceException(String.format("分类字段下注释项:%s,不可重复！", item.getName()));
        }
    }

    private void examine(QualificationsDto qualificationsDto,Long num) {
        Long l = baseMapper.selectCount(Wrappers.<QualificationsField>query()
                .lambda()
                .eq(QualificationsField::getCategoryId, qualificationsDto.getCategoryId())
                .eq(QualificationsField::getName, qualificationsDto.getFieldName()));
        if(l>num){
            throw new ServiceException(String.format("分类下字段:%s,不可重复！", qualificationsDto.getFieldName()));
        }
    }

    @Override
    @Transactional
    public Boolean updateById(QualificationsDto qualificationsDto) {
        //新的集合
        List<QualificationsFieldItem> qualificationsFieldItems = qualificationsDto.getQualificationsFieldItems();
        QualificationsField one = this.lambdaQuery().eq(QualificationsField::getId, qualificationsDto.getFieldId()).one();
        if(!qualificationsDto.getCategoryId().equals(one.getCategoryId())){
            QualificationsFieldCategory categoryById = qualificationsFieldCategoryService.getCategoryById(qualificationsDto.getCategoryId());
            QualificationsFieldCategory categoryById1 = qualificationsFieldCategoryService.getCategoryById(one.getCategoryId());
            categoryById.setFieldNum(categoryById.getFieldNum()+1);
            categoryById1.setFieldNum(categoryById.getFieldNum()-1);
            qualificationsFieldCategoryService.updateById(categoryById);
            qualificationsFieldCategoryService.updateById(categoryById1);
            one.setCategoryId(qualificationsDto.getCategoryId());
        }
        one.setCreatorTime(new Date());
        one.setName(qualificationsDto.getFieldName());
        examine(qualificationsDto,1L);
        //原有集合
        List<QualificationsFieldItem> qualificationsFieldItemList = qualificationsFieldItemService.getBaseMapper().selectList(Wrappers.<QualificationsFieldItem>query().lambda()
                .eq(QualificationsFieldItem::getFieldId, qualificationsDto.getFieldId()));
        //新的id集合
        List<String> items = new ArrayList<>();
        //原有id集合
        List<String> itemList = new ArrayList<>();
        qualificationsFieldItems.forEach(i->{
            items.add(i.getId());
        });
        qualificationsFieldItemList.forEach(i->{itemList.add(i.getId());});
        for(String i : items){
            for(QualificationsFieldItem item:qualificationsFieldItems){
                examine(item,1L);
                boolean contains = itemList.contains(i);
                if(contains){
                    qualificationsFieldItemService.updateById(item);
                }
                if(StringUtil.isEmpty(item.getId())){
                    one.setItemNum(one.getItemNum()+1);
                    qualificationsFieldItemService.save(item);
                }
            }
        }
        itemList.forEach(i->{
            if(!items.contains(i)){
                one.setItemNum(one.getItemNum()-1);
                qualificationsFieldItemService.removeById(i);
                qualificationsService.deleteAllItemRelationByItemIds(Collections.singletonList(i));
            }
        });
        this.updateById(one);
        return true;
    }

    @Override
    public PageInfo<QualificationsCategoryVo> getQualificationsFieldPages(String keyWord, String categoryId, Integer currentPage, Integer pageSize) {
        return  new PageInfo<>(qualificationsFieldCategoryService.getQualificationsFieldPages(keyWord, categoryId, currentPage, pageSize));
    }

    @Override
    public QualificationsItemsVo getQualificationsFieldItem(String fieldId) {
        return getBaseMapper().getQualificationsFieldItem(fieldId);
    }

    @Override
    @Transactional
    public Boolean deleteFieldById(String fieldId) {
        QualificationsField byId = this.getById(fieldId);
        QualificationsFieldCategory categoryById = qualificationsFieldCategoryService.getCategoryById(byId.getCategoryId());
        categoryById.setFieldNum(categoryById.getFieldNum()-1L);
        qualificationsFieldCategoryService.updateById(categoryById);
        //新增删除标准字段关联数据
        qualificationsService.deleteAllItemRelationByFieldId(fieldId);
        return this.removeById(fieldId);
    }

    @Override
    public List<QualificationsField> getCategoryFieldList(String categoryId) {
        return baseMapper.selectList(Wrappers.<QualificationsField>query().lambda().eq(QualificationsField::getCategoryId,categoryId));
    }
}
