package cn.stylefeng.team.meta.modular.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.stylefeng.team.meta.modular.entity.MetaUserDict;
import cn.stylefeng.team.meta.modular.mapper.MetaUserDictMapper;
import cn.stylefeng.team.meta.modular.pojo.metadict.MetaUserDictItem;
import cn.stylefeng.team.meta.modular.pojo.request.BusinessGenerateRequest;
import cn.stylefeng.team.meta.modular.pojo.request.MetaUserDictRequest;
import cn.stylefeng.team.meta.modular.pojo.response.UserDictTypeResponse;
import cn.stylefeng.team.meta.modular.service.MetaUserDictService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

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

@Service
public class MetaUserDictServiceImpl extends ServiceImpl<MetaUserDictMapper, MetaUserDict> implements MetaUserDictService {

    @Override
    public void add(MetaUserDictRequest metaUserDictRequest) {
        MetaUserDict metaUserDict = new MetaUserDict();

        metaUserDict.setBusinessId(metaUserDictRequest.getBusinessId());

        metaUserDict.setDictTypeName(metaUserDictRequest.getDictTypeName());
        metaUserDict.setDictTypeCode(metaUserDictRequest.getDictTypeCode());
        metaUserDict.setDictTypeSort(metaUserDictRequest.getDictTypeSort());

        this.save(metaUserDict);
    }

    @Override
    public void del(MetaUserDictRequest metaUserDictRequest) {
        LambdaUpdateWrapper<MetaUserDict> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(MetaUserDict::getMetaUserDictId, metaUserDictRequest.getMetaUserDictId());
        this.remove(wrapper);
    }

    @Override
    public void edit(MetaUserDictRequest metaUserDictRequest) {
        LambdaUpdateWrapper<MetaUserDict> wrapper = new LambdaUpdateWrapper<>();

        wrapper.set(MetaUserDict::getDictTypeCode, metaUserDictRequest.getDictTypeCode());
        wrapper.set(MetaUserDict::getDictTypeName, metaUserDictRequest.getDictTypeName());
        wrapper.set(MetaUserDict::getDictTypeSort, metaUserDictRequest.getDictTypeSort());

        wrapper.eq(MetaUserDict::getMetaUserDictId, metaUserDictRequest.getMetaUserDictId());
        this.update(wrapper);
    }

    @Override
    public MetaUserDict detail(MetaUserDictRequest metaUserDictRequest) {
        LambdaQueryWrapper<MetaUserDict> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MetaUserDict::getMetaUserDictId, metaUserDictRequest.getMetaUserDictId());
        wrapper.select(MetaUserDict::getMetaUserDictId, MetaUserDict::getDictTypeName, MetaUserDict::getDictTypeCode, MetaUserDict::getDictTypeSort, MetaUserDict::getDictList);
        return this.getOne(wrapper);
    }

    @Override
    public List<UserDictTypeResponse> findDictTypeList(MetaUserDictRequest metaUserDictRequest) {
        LambdaQueryWrapper<MetaUserDict> wrapper = this.createWrapper(metaUserDictRequest);
        wrapper.select(MetaUserDict::getMetaUserDictId, MetaUserDict::getDictTypeName);
        List<MetaUserDict> list = this.list(wrapper);

        ArrayList<UserDictTypeResponse> resultList = new ArrayList<>();
        for (MetaUserDict metaUserDict : list) {
            UserDictTypeResponse userDictTypeResponse = new UserDictTypeResponse();
            userDictTypeResponse.setDictTypeId(metaUserDict.getMetaUserDictId());
            userDictTypeResponse.setDictTypeName(metaUserDict.getDictTypeName());
            resultList.add(userDictTypeResponse);
        }
        return resultList;
    }

    @Override
    public void updateDictItemList(MetaUserDictRequest metaUserDictRequest) {
        MetaUserDict detail = this.detail(metaUserDictRequest);

        List<MetaUserDictItem> dictList = metaUserDictRequest.getDictList();
        for (MetaUserDictItem metaUserDictItem : dictList) {
            if (metaUserDictItem.getDictId() == null) {
                metaUserDictItem.setDictId(IdWorker.getId());
            }
            if (ObjectUtil.isEmpty(metaUserDictItem.getDictSort())) {
                metaUserDictItem.setDictSort(new BigDecimal("1"));
            }
        }

        List<Map<String, Object>> maps = new ArrayList<>();
        for (MetaUserDictItem metaUserDictItem : dictList) {
            Map<String, Object> map = BeanUtil.beanToMap(metaUserDictItem);
            maps.add(map);
        }

        detail.setDictList(maps);
        this.updateById(detail);
    }

    @Override
    public List<MetaUserDict> getCurrentProjectDictList(BusinessGenerateRequest businessGenerateRequest) {
        LambdaQueryWrapper<MetaUserDict> wrapper = new LambdaQueryWrapper<>();

        if (businessGenerateRequest.getMetaUserDictId() != null) {
            wrapper.eq(MetaUserDict::getMetaUserDictId, businessGenerateRequest.getMetaUserDictId());
        }

        if (businessGenerateRequest.getBusinessId() != null) {
            wrapper.eq(MetaUserDict::getBusinessId, businessGenerateRequest.getBusinessId());
        }

        return this.list(wrapper);
    }

    @Override
    public Map<Long, Integer> statDictNumber(Set<Long> businessIds) {
        HashMap<Long, Integer> resultMap = new HashMap<>();

        if (ObjectUtil.isEmpty(businessIds)) {
            return resultMap;
        }

        LambdaQueryWrapper<MetaUserDict> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(MetaUserDict::getBusinessId, businessIds);
        wrapper.select(MetaUserDict::getBusinessId, MetaUserDict::getMetaUserDictId);
        List<MetaUserDict> metaDictList = this.list(wrapper);
        if (ObjectUtil.isEmpty(metaDictList)) {
            return resultMap;
        }

        return metaDictList.stream().collect(Collectors.groupingBy(MetaUserDict::getBusinessId, Collectors.summingInt(i -> 1)));
    }

    private LambdaQueryWrapper<MetaUserDict> createWrapper(MetaUserDictRequest metaUserDictRequest) {
        LambdaQueryWrapper<MetaUserDict> queryWrapper = new LambdaQueryWrapper<>();

        String searchText = metaUserDictRequest.getSearchText();
        if (StrUtil.isNotBlank(searchText)) {
            queryWrapper.like(MetaUserDict::getDictTypeCode, searchText)
                    .or().like(MetaUserDict::getDictTypeName, searchText);
        }

        Long businessId = metaUserDictRequest.getBusinessId();
        if (ObjectUtil.isNotEmpty(businessId)) {
            queryWrapper.eq(MetaUserDict::getBusinessId, businessId);
        }

        return queryWrapper;
    }
}
