package jnpf.cultivate.v2.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jnpf.cultivate.mapper.FtbCultivateIdentifyCategoriesMapper;
import jnpf.cultivate.mapper.FtbCultivateIdentifyItemsPoolMapper;
import jnpf.cultivate.service.CultivateIdentifyItemsService;
import jnpf.cultivate.service.CultivateIdentifyTableService;
import jnpf.cultivate.utils.UserApiV2Util;
import jnpf.cultivate.v2.service.FtbCultivateIdentifyItemsPoolService;
import jnpf.entity.cultivate.CultivateIdentifyItems;
import jnpf.entity.cultivate.CultivateIdentifyTable;
import jnpf.enums.AppraisalScoreTypeEnum;
import jnpf.enums.cultivate.IdentifyItemExceptionEnum;
import jnpf.model.cultivate.po.FtbCultivateIdentifyCategories;
import jnpf.model.cultivate.po.FtbCultivateIdentifyItemsPool;
import jnpf.model.cultivate.v2.common.req.V2BatchByPrimaryIdReq;
import jnpf.model.cultivate.v2.item_pool.req.IdentifyItemsPoolReq;
import jnpf.model.cultivate.v2.item_pool.req.SaveCultivateIdentifyItemsPoolReq;
import jnpf.model.cultivate.v2.item_pool.vo.FtbCultivateIdentifyItemsPoolVo;
import jnpf.model.cultivate.v2.item_pool.vo.V2IdentifyItemVo;
import jnpf.model.cultivate.v2.position.vo.WebPositionLearningListVo;
import jnpf.model.enums.SelfrowingEnum;
import jnpf.permission.entity.UserEntity;
import jnpf.util.ConstantUtil;
import jnpf.util.SelfGrowthUtil;
import jnpf.util.UserProvider;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 鉴定项池服务实现类
 *
 * @author lingma
 * @since 2026-02-24
 */
@Slf4j
@Service
public class FtbCultivateIdentifyItemsPoolServiceImpl extends ServiceImpl<FtbCultivateIdentifyItemsPoolMapper, FtbCultivateIdentifyItemsPool> implements FtbCultivateIdentifyItemsPoolService {

    @Autowired
    private FtbCultivateIdentifyCategoriesMapper categoriesMapper;

    @Autowired
    private UserApiV2Util userApiV2Util;

    @Autowired
    private CultivateIdentifyTableService cultivateIdentifyTableService;

    @Autowired
    private CultivateIdentifyItemsService itemsService;

    /**
     * 获取鉴定项池信息
     *
     * @param id 主键值
     * @return 实体对象
     */
    @Override
    public FtbCultivateIdentifyItemsPoolVo getInfo(String id) {
        FtbCultivateIdentifyItemsPool entity = baseMapper.selectById(id);
        if (null == entity || entity.getEnabledMark().equals(1)) {
            throw new RuntimeException("数据不存在");
        }
        FtbCultivateIdentifyItemsPoolVo vo = new FtbCultivateIdentifyItemsPoolVo();
        BeanUtil.copyProperties(entity, vo);
        if (StringUtils.isNotEmpty(vo.getCateId())) {
            FtbCultivateIdentifyCategories ftbCultivateIdentifyCategories = categoriesMapper.selectById(vo.getCateId());
            if (ftbCultivateIdentifyCategories != null) {
                vo.setCateName(ftbCultivateIdentifyCategories.getName());
            }
        }
        return vo;
    }

    /**
     * 新增鉴定项池
     *
     * @param req 实体对象
     */
    @Override
    public void addData(SaveCultivateIdentifyItemsPoolReq req) {
        String userId = UserProvider.getUser().getUserId();
        //检测名称是否重复
        QueryWrapper<FtbCultivateIdentifyItemsPool> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(FtbCultivateIdentifyItemsPool::getName, req.getName())
                .eq(FtbCultivateIdentifyItemsPool::getType, req.getType())
                .eq(FtbCultivateIdentifyItemsPool::getEnabledMark, 0);
        if (req.getType().equals(AppraisalScoreTypeEnum.FLOATING.getCode())) {
            wrapper.lambda()
                    .eq(FtbCultivateIdentifyItemsPool::getMinScore, req.getMinScore())
                    .eq(FtbCultivateIdentifyItemsPool::getMaxScore, req.getMaxScore());
        } else {
            wrapper.lambda()
                    .eq(FtbCultivateIdentifyItemsPool::getTotalScore, req.getTotalScore());
        }
        Long count = baseMapper.selectCount(wrapper);
        if (null != count && count > 0) {
            throw new RuntimeException("鉴定项已经存在");
        }
        FtbCultivateIdentifyItemsPool entity = new FtbCultivateIdentifyItemsPool();
        entity.setName(req.getName());
        entity.setCateId(req.getCateId());
        entity.setType(req.getType());
        entity.setTotalScore(req.getTotalScore());
        entity.setMinScore(req.getMinScore());
        entity.setMaxScore(req.getMaxScore());
        entity.setEnabledMark(0);
        entity.setCreatorTime(new java.util.Date());
        entity.setCreatorUserId(userId);
        entity.setLastModifyTime(new java.util.Date());
        entity.setLastModifyUserId(userId);
        entity.setBusinessId(SelfGrowthUtil.provideACustomIDBasedOnTheModule(SelfrowingEnum.ITEM_POOL));
        baseMapper.insert(entity);

    }

    /**
     * 修改鉴定项池
     *
     * @param id  主键值
     * @param req 实体对象
     */
    @Override
    @Transactional
    public void updateData(String id, SaveCultivateIdentifyItemsPoolReq req) {
        FtbCultivateIdentifyItemsPool oldEntity = queryAndCheckById(id);
        //检测名称是否重复
        QueryWrapper<FtbCultivateIdentifyItemsPool> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(FtbCultivateIdentifyItemsPool::getName, req.getName())
                .ne(FtbCultivateIdentifyItemsPool::getId, id)
                .eq(FtbCultivateIdentifyItemsPool::getType, req.getType())
                .eq(FtbCultivateIdentifyItemsPool::getEnabledMark, 0);

        if (req.getType().equals(AppraisalScoreTypeEnum.FLOATING.getCode())) {
            wrapper.lambda()
                    .eq(FtbCultivateIdentifyItemsPool::getMinScore, req.getMinScore())
                    .eq(FtbCultivateIdentifyItemsPool::getMaxScore, req.getMaxScore());
        } else {
            wrapper.lambda()
                    .eq(FtbCultivateIdentifyItemsPool::getTotalScore, req.getTotalScore());
        }
        Long count = baseMapper.selectCount(wrapper);
        if (null != count && count > 0) {
            throw new RuntimeException("鉴定项已经存在");
        }
        FtbCultivateIdentifyItemsPool entity = req.convertData(id);
        String userId = UserProvider.getUser().getUserId();
        //修改分类
        entity.setLastModifyUserId(userId);
        baseMapper.updateById(entity);

        syncIdentifyTableForUpdate(oldEntity, entity);
    }

    private void syncIdentifyTableForUpdate(FtbCultivateIdentifyItemsPool oldEntity, FtbCultivateIdentifyItemsPool entity) {
        IdentifyItemExceptionEnum exceptionEnum = IdentifyItemExceptionEnum.NORMAL;
        if (!oldEntity.getType().equals(entity.getType())) {
            exceptionEnum = IdentifyItemExceptionEnum.MODIFY_EXCEPTION;
        } else {
            if (oldEntity.getType().equals(AppraisalScoreTypeEnum.FIXED.getCode())) {
                if (!oldEntity.getTotalScore().equals(entity.getTotalScore())) {
                    exceptionEnum = IdentifyItemExceptionEnum.MODIFY_EXCEPTION;
                }
            } else {
                if (!oldEntity.getMinScore().equals(entity.getMinScore()) || !oldEntity.getMaxScore().equals(entity.getMaxScore())) {
                    exceptionEnum = IdentifyItemExceptionEnum.MODIFY_EXCEPTION;
                }
            }
        }
        if (exceptionEnum == IdentifyItemExceptionEnum.NORMAL && entity.getName().equals(oldEntity.getName())) {
            return;
        }
        addAbnormalTag(entity, exceptionEnum);

    }

    private void addAbnormalTag(FtbCultivateIdentifyItemsPool entity, IdentifyItemExceptionEnum exceptionEnum) {
        List<CultivateIdentifyItems> itemList = itemsService.list(Wrappers.<CultivateIdentifyItems>lambdaQuery()
                .eq(CultivateIdentifyItems::getPoolId, entity.getId())
                .eq(CultivateIdentifyItems::getDeleteMark, ConstantUtil.NUM_FALSE));
        if (CollUtil.isEmpty(itemList)) {
            return;
        }
        Set<String> tableIds = new HashSet<>();
        for (CultivateIdentifyItems item : itemList) {
            item.setIsAbnormal(exceptionEnum.getCode());
            item.setType(entity.getType());
            if (entity.getType().equals(AppraisalScoreTypeEnum.FIXED.getCode())) {
                item.setScore(BigDecimal.valueOf(entity.getTotalScore()));
            } else {
                item.setMinScore(entity.getMinScore());
                item.setMaxScore(entity.getMaxScore());
            }

            item.setCateId(entity.getCateId());
            if (exceptionEnum == IdentifyItemExceptionEnum.NORMAL) {
                item.setName(entity.getName());
            }
            tableIds.add(item.getTableId());
        }
        itemsService.updateBatchById(itemList);

        LambdaUpdateWrapper<CultivateIdentifyTable> updateTableWrapper = new LambdaUpdateWrapper<CultivateIdentifyTable>()
                .in(CultivateIdentifyTable::getId, tableIds)
                .eq(CultivateIdentifyTable::getIsAbnormal, ConstantUtil.NUM_FALSE)
                .set(CultivateIdentifyTable::getIsAbnormal, IdentifyItemExceptionEnum.MODIFY_EXCEPTION.getCode());
        cultivateIdentifyTableService.update(updateTableWrapper);
    }

    /**
     * 删除鉴定项池
     *
     * @param id 主键值
     */
    @Override
    public void deleteData(String id) {
        FtbCultivateIdentifyItemsPool entity = queryAndCheckById(id);
        entity.setEnabledMark(1);
        baseMapper.updateById(entity);
        syncIdentifyTableForDelete(entity);
    }

    private void syncIdentifyTableForDelete(FtbCultivateIdentifyItemsPool entity) {
        IdentifyItemExceptionEnum exceptionEnum = IdentifyItemExceptionEnum.DELETE_EXCEPTION;
        addAbnormalTag(entity, exceptionEnum);
    }

    /**
     * 获取鉴定项池列表
     *
     * @return
     */
    @Override
    public Page<FtbCultivateIdentifyItemsPoolVo> webPageList(IdentifyItemsPoolReq req) {
        Page<WebPositionLearningListVo> page = Page.of(req.getCurrentPage(), req.getPageSize());

        Page<FtbCultivateIdentifyItemsPoolVo> result = baseMapper.webPageList(page, req);
        List<FtbCultivateIdentifyItemsPoolVo> records = result.getRecords();
        if (CollUtil.isEmpty(records)) {
            return result;
        }
        List<String> userIds = records.stream()
                .map(FtbCultivateIdentifyItemsPoolVo::getUserId)
                .collect(Collectors.toList());

        Map<String, UserEntity> userMap = userApiV2Util.getUserNameAndCopyForUserIds(userIds);

        records.forEach(item -> {
            UserEntity userEntity = userMap.get(item.getUserId());
            if (userEntity != null && userEntity.getRealName() != null) {
                item.setUserName(userEntity.getRealName());
            }
        });
        return result;
    }

    /**
     * 获取鉴定项池列表
     *
     * @return 鉴定项池列表
     */
    @Override
    public List<FtbCultivateIdentifyItemsPool> listAll() {
        return baseMapper.selectList(new LambdaQueryWrapper<FtbCultivateIdentifyItemsPool>()
                .eq(FtbCultivateIdentifyItemsPool::getEnabledMark, 0));
    }

    @Override
    @Transactional
    public void batchDel(V2BatchByPrimaryIdReq req) {
        List<FtbCultivateIdentifyItemsPool> oldList = baseMapper.selectBatchIds(req.getIds());
        if (CollUtil.isNotEmpty(oldList)) {
            for (FtbCultivateIdentifyItemsPool ftbCultivateIdentifyItemsPool : oldList) {
                syncIdentifyTableForDelete(ftbCultivateIdentifyItemsPool);
            }
        }
        baseMapper.update(null, new LambdaUpdateWrapper<FtbCultivateIdentifyItemsPool>()
                .in(FtbCultivateIdentifyItemsPool::getId, req.getIds())
                .set(FtbCultivateIdentifyItemsPool::getEnabledMark, 1));
    }

    @Override
    public void batchAddData(List<V2IdentifyItemVo> normal) {
        if (CollUtil.isEmpty(normal)) {
            return;
        }
        String userId = UserProvider.getUser().getUserId();
        List<FtbCultivateIdentifyItemsPool> list = new ArrayList<>();
        for (V2IdentifyItemVo req : normal) {
            FtbCultivateIdentifyItemsPool entity = req.convertData(userId);
            entity.setBusinessId(SelfGrowthUtil.provideACustomIDBasedOnTheModule(SelfrowingEnum.ITEM_POOL));
            list.add(entity);
        }
        this.saveBatch(list);

    }

    /**
     * 根据id查询鉴定项
     *
     * @param id 主键值
     * @return 鉴定项
     */
    public FtbCultivateIdentifyItemsPool queryAndCheckById(String id) {
        FtbCultivateIdentifyItemsPool entity = baseMapper.selectById(id);
        if (null == entity) {
            throw new RuntimeException("鉴定项不存在");
        }
        if (entity.getEnabledMark().equals(1)) {
            throw new RuntimeException("鉴定项已经删除");
        }
        return entity;
    }
}