package com.xinelu.manage.service.labelfieldinfo.impl;

import com.xinelu.common.constant.Constants;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.codes.GenerateSystemCodeUtil;
import com.xinelu.manage.domain.labelfieldinfo.LabelFieldInfo;
import com.xinelu.manage.dto.labelfieldinfo.LabelFieldInfoAddDTO;
import com.xinelu.manage.mapper.labelfieldcontent.LabelFieldContentMapper;
import com.xinelu.manage.mapper.labelfieldinfo.LabelFieldInfoMapper;
import com.xinelu.manage.service.labelfieldinfo.ILabelFieldInfoService;
import com.xinelu.manage.vo.labelfieldcontent.LabelFieldContentVO;
import com.xinelu.manage.vo.labelfieldinfo.LabelFieldVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 标签字段信息Service业务层处理
 *
 * @author xinelu
 * @date 2024-03-11
 */
@Service
public class LabelFieldInfoServiceImpl implements ILabelFieldInfoService {
    @Resource
    private LabelFieldInfoMapper labelFieldInfoMapper;

    @Resource
    private GenerateSystemCodeUtil systemCodeUtil;

    @Resource
    private LabelFieldContentMapper labelFieldContentMapper;

    /**
     * 查询标签字段信息
     *
     * @param id 标签字段信息主键
     * @return 标签字段信息
     */
    @Override
    public LabelFieldInfo selectLabelFieldInfoById(Long id) {
        return labelFieldInfoMapper.selectLabelFieldInfoById(id);
    }

    /**
     * 查询标签字段信息列表
     *
     * @param labelFieldInfo 标签字段信息
     * @return 标签字段信息
     */
    @Override
    public List<LabelFieldInfo> selectLabelFieldInfoList(LabelFieldInfo labelFieldInfo) {
        return labelFieldInfoMapper.selectLabelFieldInfoList(labelFieldInfo);
    }

    /**
     * 查询标签字段信息列表树图
     *
     * @param fieldType 字段类型
     * @return AjaxResult
     */
    @Override
    public AjaxResult labelFieldList(String fieldType) {
        List<LabelFieldVO> labelFieldList = labelFieldInfoMapper.selectLabelFieldList(fieldType);
        List<Long> labelFieldIds = labelFieldList.stream().filter(Objects::nonNull).map(LabelFieldVO::getLabelFieldId).filter(Objects::nonNull).collect(Collectors.toList());
        if (labelFieldIds.size() == 0) {
            return AjaxResult.success(labelFieldList);
        }
        List<LabelFieldContentVO> labelFieldContentList = labelFieldContentMapper.selectLabelFieldContent(labelFieldIds);
        for (LabelFieldVO labelField : labelFieldList) {
            List<LabelFieldContentVO> collect = labelFieldContentList.stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getFieldId()) && labelField.getLabelFieldId().equals(item.getFieldId())).collect(Collectors.toList());
            labelField.setLabelFieldContentList(collect);
        }
        return AjaxResult.success(labelFieldList);
    }

    /**
     * 新增标签字段信息
     *
     * @param labelFieldInfo 标签字段信息
     * @return 结果
     */
    @Override
    public int insertLabelFieldInfo(LabelFieldInfo labelFieldInfo) {
        labelFieldInfo.setCreateTime(LocalDateTime.now());
        return labelFieldInfoMapper.insertLabelFieldInfo(labelFieldInfo);
    }

    /**
     * 修改标签字段信息
     *
     * @param labelFieldInfo 标签字段信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateLabelFieldInfo(LabelFieldInfo labelFieldInfo) {
        // 检查id对应的标签信息是否存在
        LabelFieldInfo fieldInfo = labelFieldInfoMapper.selectLabelFieldInfoById(labelFieldInfo.getId());
        if (ObjectUtils.isEmpty(fieldInfo)) {
            throw new ServiceException("当前标签信息不存在，无法修改，请联系管理员");
        }
        // 检查除当前记录外有没有重复的标签信息名称
        if (labelFieldInfoMapper.countByFieldNameExcludingId(labelFieldInfo.getId(), labelFieldInfo.getFieldType(), labelFieldInfo.getFieldName()) > 0) {
            throw new ServiceException("当前字段类型下字段名称已存在");
        }
        // 执行修改操作
        labelFieldInfo.setUpdateBy(SecurityUtils.getUsername());
        labelFieldInfo.setUpdateTime(LocalDateTime.now());
        return labelFieldInfoMapper.updateLabelFieldInfo(labelFieldInfo);
    }

    /**
     * 批量删除标签字段信息
     *
     * @param ids 需要删除的标签字段信息主键
     * @return 结果
     */
    @Override
    public int deleteLabelFieldInfoByIds(Long[] ids) {
        return labelFieldInfoMapper.deleteLabelFieldInfoByIds(ids);
    }

    /**
     * 删除标签字段信息信息
     *
     * @param id 标签字段信息主键
     * @return 结果
     */
    @Override
    public int deleteLabelFieldInfoById(Long id) {
        return labelFieldInfoMapper.deleteLabelFieldInfoById(id);
    }

    /**
     * 批量新增标签字段信息
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertLabelFieldInfoList(LabelFieldInfoAddDTO labelFieldInfoAddDTO) {
        // 如果对象为空，提示请填加标签字段信息
        List<LabelFieldInfo> fieldInfoList = labelFieldInfoAddDTO.getLabelFieldInfoList();
        if (CollectionUtils.isEmpty(fieldInfoList)) {
            throw new ServiceException("请填加标签字段信息");
        }
        // 如果不为空，按字段类型分组并且收集每个类型下的字段名称
        Map<String, List<String>> fieldTypeToNamesMap = fieldInfoList.stream().
                collect(Collectors.groupingBy(LabelFieldInfo::getFieldType,
                        Collectors.mapping(LabelFieldInfo::getFieldName, Collectors.toList())));
        // 对于每个字段类型下字段名称进行重复性检查
        for (Map.Entry<String, List<String>> entry : fieldTypeToNamesMap.entrySet()) {
            // 获取字段类型和字段名称集合
            String fieldType = entry.getKey();
            List<String> fieldNames = entry.getValue();
            // 查询数据库中是否存在同字段类型下字段名称
            int duplicateCount = labelFieldInfoMapper.countDuplicateFieldNamesByType(fieldType, fieldNames);
            // 如果存在，提示该字段类型下已存在
            if (duplicateCount > 0) {
                throw new ServiceException("当前字段类型下字段名称已存在");
            }
        }
        // 如果不存在，执行新增操作
        for (LabelFieldInfo labelFieldInfo : fieldInfoList) {
            labelFieldInfo.setFieldCode(Constants.FIELD_ENCODING + systemCodeUtil.generateDepartCode(Constants.FIELD_ENCODING));
            labelFieldInfo.setCreateBy(SecurityUtils.getUsername());
            labelFieldInfo.setCreateTime(LocalDateTime.now());
            if (labelFieldInfoMapper.insertLabelFieldInfo(labelFieldInfo) <= 0) {
                throw new ServiceException("新增标签字段信息失败");
            }
        }
        return 1;
    }
}
