package com.cool.store.dao;

import cn.hutool.core.collection.CollStreamUtil;
import com.alibaba.excel.util.CollectionUtils;
import com.cool.store.entity.CloseStoreStageInfoDO;
import com.cool.store.enums.ErrorCodeEnum;
import com.cool.store.enums.close.CloseStoreStageEnum;
import com.cool.store.enums.close.CloseStoreSubStageEnum;
import com.cool.store.enums.close.CloseStoreSubStageStatusEnum;
import com.cool.store.exception.ServiceException;
import com.cool.store.mapper.CloseStoreStageInfoMapper;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author suzhuhong
 * @Date 2025/9/22 16:54
 * @Version 1.0
 */
@Repository
public class CloseStoreStageInfoDAO {

    @Resource
    private CloseStoreStageInfoMapper closeStoreStageInfoMapper;

    /**
     * 根据闭店阶段查询闭店阶段信息
     * @param closeStoreId 闭店申请id
     * @param shopStage 闭店阶段
     * @param shopSubStage 闭店子阶段，非必填
     * @return 闭店阶段信息
     */
    public CloseStoreStageInfoDO getByStage(Long closeStoreId, Integer shopStage, Integer shopSubStage) {
        Example example = new Example(CloseStoreStageInfoDO.class);
        Example.Criteria criteria = example.createCriteria()
                .andEqualTo("closeStoreId", closeStoreId)
                .andEqualTo("shopStage", shopStage)
                .andEqualTo("deleted", 0);
        if (Objects.nonNull(shopSubStage)) {
            criteria.andEqualTo("shopSubStage", shopSubStage);
        }
        return closeStoreStageInfoMapper.selectOneByExample(example);
    }

    /**
     * 根据子阶段查询闭店阶段信息
     * @param closeStoreId 闭店申请id
     * @param subStageList 子阶段列表
     * @return 阶段信息列表
     */
    public List<CloseStoreStageInfoDO> getBySubStage(Long closeStoreId, List<Integer> subStageList) {
        if (CollectionUtils.isEmpty(subStageList)) {
            return Collections.emptyList();
        }
        Example example = new Example(CloseStoreStageInfoDO.class);
        example.createCriteria()
                .andEqualTo("closeStoreId", closeStoreId)
                .andIn("shopSubStage", subStageList)
                .andEqualTo("deleted", 0);
        return closeStoreStageInfoMapper.selectByExample(example);
    }

    /**
     * 查询闭店阶段信息
     * @param closeStoreId 闭店申请id
     * @return 阶段信息列表
     */
    public List<CloseStoreStageInfoDO> getList(Long closeStoreId) {
        Example example = new Example(CloseStoreStageInfoDO.class);
        example.createCriteria()
                .andEqualTo("closeStoreId", closeStoreId)
                .andEqualTo("deleted", 0);
        example.setOrderByClause("shop_sub_stage ASC");
        return closeStoreStageInfoMapper.selectByExample(example);
    }

    /**
     * 存在未完成的闭店阶段
     * @param closeStoreId 闭店申请id
     * @return boolean
     */
    public boolean existUnfinishedStage(Long closeStoreId) {
        return closeStoreStageInfoMapper.selectCount(
                CloseStoreStageInfoDO.builder()
                        .closeStoreId(closeStoreId)
                        .isTerminated(0)
                        .deleted(0)
                        .build()
        ) > 0;
    }

    /**
     * 校验闭店阶段流程是否为期望流程
     * @param closeStoreId 闭店申请id
     * @param shopStage 闭店阶段
     * @param shopSubStage 闭店子阶段
     * @param expectedStageStatus 期望闭店子阶段状态
     */
    public void verifyStage(Long closeStoreId, CloseStoreStageEnum shopStage, CloseStoreSubStageEnum shopSubStage, CloseStoreSubStageStatusEnum... expectedStageStatus) {
        CloseStoreStageInfoDO stageInfoDO = getByStage(closeStoreId, shopStage.getCloseStoreStage(), Objects.nonNull(shopSubStage) ? shopSubStage.getCloseStoreSubStage() : null);
        if (Objects.isNull(stageInfoDO)) {
            throw new RuntimeException("未查询到审批阶段信息");
        }
        if (Objects.nonNull(expectedStageStatus) && expectedStageStatus.length > 0) {
            for (CloseStoreSubStageStatusEnum stageStatus : expectedStageStatus) {
                if (stageStatus.getShopSubStageStatus().equals(stageInfoDO.getShopSubStageStatus())) {
                    return;
                }
            }
            throw new ServiceException(ErrorCodeEnum.CLOSE_STORE_SUB_STAGE_ERROR);
        }
    }

    /**
     * 初始化闭店阶段信息
     * @param closeStoreId 闭店申请id
     */
    public void initStageInfo(Long closeStoreId) {
        List<CloseStoreStageInfoDO> stageInfoList = new ArrayList<>();
        LocalDate now = LocalDate.now();
        for (CloseStoreSubStageEnum subStageEnum : CloseStoreSubStageEnum.values()) {
            CloseStoreSubStageStatusEnum initStatus = subStageEnum.getInitStatus();
            CloseStoreStageInfoDO stageInfo = CloseStoreStageInfoDO.builder()
                    .closeStoreId(closeStoreId)
                    .shopStage(subStageEnum.getCloseStoreStageEnum().getCloseStoreStage())
                    .shopSubStage(subStageEnum.getCloseStoreSubStage())
                    .shopSubStageStatus(Objects.nonNull(initStatus) ? initStatus.getShopSubStageStatus() : CloseStoreSubStageStatusEnum.CLOSE_STORE_SUB_STAGE_STATUS_00.getShopSubStageStatus())
                    .isTerminated(0)
                    .planCompleteTime(subStageEnum.getPlanCompleteTime(now))
                    .build();
            stageInfoList.add(stageInfo);
        }
        closeStoreStageInfoMapper.insertBatch(stageInfoList);
    }

    /**
     * 批量更新Selective
     * @param list 阶段信息列表
     * @return 是否成功
     */
    public Boolean updateBatchSelective(List<CloseStoreStageInfoDO> list) {
        if (CollectionUtils.isEmpty(list)) {
            return false;
        }
        return closeStoreStageInfoMapper.updateBatchSelective(list) > 0;
    }

    /**
     * 更新Selective
     * @param stageInfoDO 阶段信息
     * @return 是否成功
     */
    public Boolean updateSelective(CloseStoreStageInfoDO stageInfoDO) {
        return closeStoreStageInfoMapper.updateByPrimaryKeySelective(stageInfoDO) > 0;
    }

    /**
     * 已完成阶段数
     * @param closeStoreId 闭店申请id
     * @return 已完成阶段数
     */
    public int getCompleteCount(Long closeStoreId) {
        Example example = new Example(CloseStoreStageInfoDO.class);
        example.createCriteria()
                .andEqualTo("closeStoreId", closeStoreId)
                .andEqualTo("isTerminated", 1)
                .andEqualTo("deleted", 0);
        return closeStoreStageInfoMapper.selectCountByExample(example);
    }

    /**
     * 已完成阶段数
     * @param closeStoreIds 闭店申请id列表
     * @return 已完成阶段数
     */
    public Map<Long, Long> getCompleteCountMap(List<Long> closeStoreIds) {
        if (CollectionUtils.isEmpty(closeStoreIds)) {
            return Collections.emptyMap();
        }
        Example example = new Example(CloseStoreStageInfoDO.class);
        example.createCriteria()
                .andIn("closeStoreId", closeStoreIds)
                .andEqualTo("isTerminated", 1)
                .andEqualTo("deleted", 0);
        example.selectProperties("closeStoreId");
        List<CloseStoreStageInfoDO> list = closeStoreStageInfoMapper.selectByExample(example);
        return CollStreamUtil.groupBy(list, CloseStoreStageInfoDO::getCloseStoreId, Collectors.counting());
    }

    /**
     * 修改子阶段状态
     * @param closeStoreId 闭店申请id
     * @param subStatus 子阶段状态枚举类
     */
    public void updateSubStageStatus(Long closeStoreId, CloseStoreSubStageStatusEnum subStatus) {
        CloseStoreSubStageEnum subStage = subStatus.getCloseStoreSubStageEnum();
        Example example = new Example(CloseStoreStageInfoDO.class);
        example.createCriteria()
                .andEqualTo("closeStoreId", closeStoreId)
                .andEqualTo("shopSubStage", subStage.getCloseStoreSubStage())
                .andEqualTo("deleted", 0);
        closeStoreStageInfoMapper.updateByExampleSelective(CloseStoreStageInfoDO.builder().shopSubStageStatus(subStatus.getShopSubStageStatus()).build(), example);
    }
}
