package cn.cecep.talroad.service.impl;

import cn.cecep.talroad.common.core.domain.R;
import cn.cecep.talroad.common.core.utils.StringUtils;
import cn.cecep.talroad.common.security.utils.SecurityUtils;
import cn.cecep.talroad.domain.PcLabel;
import cn.cecep.talroad.domain.PcLabelFactory;
import cn.cecep.talroad.domain.PcLabelValue;
import cn.cecep.talroad.enums.LabelFactoryEnum;
import cn.cecep.talroad.feign.BaseRegionService;
import cn.cecep.talroad.mapper.PcLabelFactoryMapper;
import cn.cecep.talroad.mapper.PcLabelMapper;
import cn.cecep.talroad.mapper.PcLabelValueMapper;
import cn.cecep.talroad.service.IPcLabelService;
import cn.cecep.talroad.vo.PcLabelValueVo;
import cn.cecep.talroad.vo.PcLabelVo;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 特征标签Service业务层处理
 *
 * @author szhpt
 * @date 2023-01-10*/
@Service
public class PcLabelServiceImpl extends ServiceImpl<PcLabelMapper,PcLabel> implements IPcLabelService
{
    @Autowired
    private PcLabelMapper pcLabelMapper;

    @Autowired
    private PcLabelValueMapper labelValueMapper;

    @Autowired
    private PcLabelFactoryMapper labelFactoryMapper;

    @Autowired
    @Qualifier("baseRegionService")
    private BaseRegionService baseRegionService;
    /**
     * 查询特征标签列表
     *
     * @param pcLabel 特征标签
     * @return 特征标签
     */
    @Override
    public List<PcLabel> selectPcLabelList(PcLabel pcLabel)
    {
        return pcLabelMapper.selectPcLabelList(pcLabel);
    }

    @Override
    public List<PcLabelVo> tree(String id, String factoryId) {

        return pcLabelMapper.selectTreeList(id, factoryId);
    }

    @Override
    public List<PcLabelVo> getChildrenLabel(String id) {

        QueryWrapper<PcLabel> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(id)) {
            queryWrapper.eq("label_paramid", id);
        } else {
            queryWrapper.isNotNull("label_paramid");
        }
        queryWrapper.orderByAsc("order_num");
        List<PcLabel> labels = list(queryWrapper);

        List<PcLabelValue> values = new ArrayList<>();

        if (!labels.isEmpty()) {
            values = labelValueMapper.selectList(new QueryWrapper<PcLabelValue>()
                    .in("label_id", labels.stream().map(PcLabel::getId).collect(Collectors.toList()))
                    .orderByAsc("order_num")
            );
        }
        Map<String, List<PcLabelValue>> valueMap = values.stream().collect(Collectors.groupingBy(PcLabelValue::getLabelId));

        return labels.stream().map(label -> {
            PcLabelVo vo = new PcLabelVo();
            BeanUtils.copyProperties(label, vo);

            List<PcLabelValue> list = valueMap.get(label.getId());
            if("BASE002".equals(label.getLabelCode())){
                List<String> regionCodes=new ArrayList<>();
                R<List<String>> r = baseRegionService.getRegionCodeListChild(SecurityUtils.getLoginUser().getSysUser().getRegionCode());
                if(r.getCode()==200){
                    regionCodes=r.getData();
                }
                List<String> finalRegionCodes = regionCodes;
                list = list.stream().filter(l -> finalRegionCodes.stream().anyMatch(f -> f.equals(l.getArgumentsCode()))).collect(Collectors.toList());

            }
            if (list == null) {
                vo.setPcLabelValueVos(new ArrayList<>());
            } else {
                List<PcLabelValueVo> collect = list.stream().map(labelValue -> {
                    PcLabelValueVo valueVo = new PcLabelValueVo();
                    BeanUtils.copyProperties(labelValue, valueVo);
                    return valueVo;
                }).collect(Collectors.toList());
                vo.setPcLabelValueVos(collect);
            }
            return vo;
        }).collect(Collectors.toList());
    }

    public List<PcLabelVo> getChildPerms(List<PcLabelVo> list, String parentId) {
        List<PcLabelVo> returnList = Lists.newArrayList();

        for (Iterator<PcLabelVo> iterator = list.iterator(); iterator.hasNext();)
        {
            PcLabelVo t = iterator.next();
            // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
            if (StringUtils.equals(t.getLabelParamid(), parentId)) {
                recursionFn(list, t);
                returnList.add(t);
            }
        }

        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list
     * @param t
     */
    private void recursionFn(List<PcLabelVo> list, PcLabelVo t) {
        // 得到子节点列表
        List<PcLabelVo> childList = getChildList(list, t);
//        t.setChildren(childList);
        for (PcLabelVo tChild : childList)
        {
            if (hasChild(list, tChild))
            {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<PcLabelVo> getChildList(List<PcLabelVo> list, PcLabelVo t) {
        List<PcLabelVo> tlist = new ArrayList<>();
        Iterator<PcLabelVo> it = list.iterator();
        while (it.hasNext())
        {
            PcLabelVo n = it.next();
            if (StringUtils.equals(n.getLabelParamid(), t.getId()))
            {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<PcLabelVo> list, PcLabelVo t)
    {
        return getChildList(list, t).size() > 0;
    }

    @Override
    public List<PcLabel>getPcLabelListByLabelCodes(List<String>codeList){
        List<PcLabel> tlist = new ArrayList<>();
        if(codeList.isEmpty()){
           return tlist;
        }
        return pcLabelMapper.selectList(new QueryWrapper<PcLabel>().in("label_code", codeList));
    }

    @Override
    public void add(PcLabel pcLabel) {
        if (StringUtils.isNotBlank(pcLabel.getLabelCode())) {
            List<PcLabel> labels = list(new QueryWrapper<PcLabel>().eq("label_code", pcLabel.getLabelCode()));
            if (labels.size() > 0) {
                throw new RuntimeException("标签编码重复");
            }
        }
        if (StringUtils.isBlank(pcLabel.getLabelVal())) {
            throw new RuntimeException("标签名称不可以为空");
        }
        List<PcLabel> labels = list(new QueryWrapper<PcLabel>().eq("label_val", pcLabel.getLabelVal()));
        if (labels.size() > 0) {
            throw new RuntimeException("标签名称重复");
        }
        pcLabel.setLablevalue("1");
        pcLabel.setId(UUID.randomUUID().toString());

        save(pcLabel);
    }

    @Override
    public void edit(PcLabelVo vo) {
        PcLabel pcLabel = getById(vo.getId());

        if (!Objects.equals(pcLabel.getLabelCode(), vo.getLabelCode())) {
            if (StringUtils.isNotEmpty(pcLabel.getFactoryField()) || LabelFactoryEnum.getByCode(pcLabel.getLabelCode()) != null) {
                throw new RuntimeException("非手工标签，标签编码不可以修改");
            } else {
                if (StringUtils.isNotBlank(vo.getLabelCode())) {
                    List<PcLabel> labels = list(new QueryWrapper<PcLabel>()
                            .eq("label_code", vo.getLabelCode())
                            .ne("id", vo.getId()) // 不包括自己
                    );
                    if (labels.size() > 0) {
                        throw new RuntimeException("标签编码重复");
                    }
                }
            }
        }

        if (!Objects.equals(pcLabel.getLabelVal(), vo.getLabelVal())) {
            if (StringUtils.isNotEmpty(pcLabel.getFactoryField()) || LabelFactoryEnum.getByCode(pcLabel.getLabelCode()) != null) {
                throw new RuntimeException("非手工标签，标签名称不可以修改");
            } else {
                if (StringUtils.isBlank(vo.getLabelVal())) {
                    throw new RuntimeException("标签名称不可以为空");
                }
                List<PcLabel> labels = list(new QueryWrapper<PcLabel>()
                        .eq("label_val", vo.getLabelVal())
                        .ne("id", vo.getId()) // 不包括自己
                );
                if (labels.size() > 0) {
                    throw new RuntimeException("标签名称重复");
                }
            }
        }

        BeanUtil.copyProperties(vo, pcLabel);
        updateById(pcLabel);
    }

    @Override
    @Transactional
    public void delete(String id) {
        PcLabel pcLabel = getById(id);
        if (pcLabel == null) {
            return;
        }

        if (StringUtils.isNotEmpty(pcLabel.getFactoryField()) || LabelFactoryEnum.getByCode(pcLabel.getLabelCode()) != null) {
            throw new RuntimeException("非手工标签，不支持删除");
        }

        Integer count = labelFactoryMapper.selectCount(new QueryWrapper<PcLabelFactory>().eq("label_id", id));
        if (count > 0) {
            throw new RuntimeException("存在关联的企业，标签不可以删除");
        }

        // 删除标签值
        labelValueMapper.delete(new UpdateWrapper<PcLabelValue>().eq("label_id", id));
        removeById(pcLabel);
    }
}
