package com.cool.store.dao.tp;

import cn.hutool.core.collection.CollStreamUtil;
import com.cool.store.entity.tp.TpApplyFormDO;
import com.cool.store.enums.tp.TpFormStatusEnum;
import com.cool.store.enums.tp.TpFormTypeEnum;
import com.cool.store.enums.tp.TpPayStatusEnum;
import com.cool.store.mapper.tp.TpApplyFormMapper;
import com.cool.store.request.tp.TpApplyQueryRequest;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.entity.Example;

import java.time.LocalDate;
import java.util.*;

/**
 * <p>
 * 十二分制-申请单DAO
 * </p>
 *
 * @author wangff
 * @since 2025/11/5
 */
@Repository
@RequiredArgsConstructor
public class TpApplyFormDAO {
    private final TpApplyFormMapper tpApplyFormMapper;

    /**
     * 新增
     */
    public boolean insertSelective(TpApplyFormDO tpApplyFormDO) {
        return tpApplyFormMapper.insertSelective(tpApplyFormDO) > 0;
    }

    /**
     * 编辑
     */
    public boolean updateSelective(TpApplyFormDO tpApplyFormDO) {
        return tpApplyFormMapper.updateByPrimaryKeySelective(tpApplyFormDO) > 0;
    }

    public boolean insertOrUpdate(TpApplyFormDO tpApplyFormDO) {
        if (Objects.isNull(tpApplyFormDO.getId())) {
            return tpApplyFormMapper.insertSelective(tpApplyFormDO) > 0;
        } else {
            return tpApplyFormMapper.updateByPrimaryKeySelective(tpApplyFormDO) > 0;
        }
    }

    /**
     * 一个月内是否存在相同加分申请
     * @param storeId 门店id
     * @param ruleId 规则id
     * @return 是否存在
     */
    public boolean existPassRewardForm(String storeId, Long ruleId) {
        Example example = new Example(TpApplyFormDO.class);
        example.createCriteria()
                .andEqualTo("type", 0)
                .andEqualTo("storeId", storeId)
                .andEqualTo("ruleId", ruleId)
                .andEqualTo("status", TpFormStatusEnum.PASS.getStatus())
                .andGreaterThan("approveTime", LocalDate.now().minusMonths(1));
        return tpApplyFormMapper.selectCountByExample(example) > 0;
    }

    /**
     * 根据id查询
     */
    public TpApplyFormDO getById(Long id) {
        return tpApplyFormMapper.selectByPrimaryKey(id);
    }

    /**
     * 根据id查询有效申请单
     */
    public TpApplyFormDO getEffectiveById(Long id) {
        return tpApplyFormMapper.selectOne(TpApplyFormDO.builder().id(id).deleted(0).build());
    }

    /**
     * 查询有效记录列表
     * @param request 申请单查询Request
     * @return 申请单列表
     */
    public List<TpApplyFormDO> getEffectiveList(TpApplyQueryRequest request) {
        return tpApplyFormMapper.getEffectiveList(request);
    }

    /**
     * 查询门店相同规则的惩处单数量
     * @param storeId 门店id
     * @param ruleId 规则id
     * @return 数量
     */
    public int getPenaltyCount(String storeId, Long ruleId) {
        Example example = new Example(TpApplyFormDO.class);
        example.createCriteria()
                .andEqualTo("storeId", storeId)
                .andEqualTo("ruleId", ruleId)
                .andNotEqualTo("status", TpFormStatusEnum.CANCEL.getStatus())
                .andIn("type", Arrays.asList(TpFormTypeEnum.WARNING.getType(), TpFormTypeEnum.PENALTY.getType()))
                .andEqualTo("deleted", 0);
        return tpApplyFormMapper.selectCountByExample(example);
    }

    /**
     * 是否存在待审批的申请单
     * @param storeId 门店id
     * @param ruleId 规则id
     * @param types 单据类型
     * @return 是否存在
     */
    public boolean existsPendingApply(String storeId, Long ruleId, List<Integer> types) {
        Example example = new Example(TpApplyFormDO.class);
        Example.Criteria criteria = example.createCriteria()
                .andEqualTo("storeId", storeId)
                .andEqualTo("ruleId", ruleId)
                .andEqualTo("status", TpFormStatusEnum.PENDING.getStatus())
                .andEqualTo("isDraft", 0)
                .andEqualTo("deleted", 0);
        if (CollectionUtils.isNotEmpty(types)) {
            criteria.andIn("type", types);
        }
        return tpApplyFormMapper.selectCountByExample(example) > 0;
    }

    /**
     * 根据处罚单id查询复议申请单
     * @param penaltyId 处罚单id
     * @return 申请单
     */
    public TpApplyFormDO getAppealByPenaltyId(Long penaltyId) {
        Example example = new Example(TpApplyFormDO.class);
        example.createCriteria()
                .andEqualTo("penaltyId", penaltyId)
                .andEqualTo("deleted", 0)
                .andIn("status", Arrays.asList(TpFormStatusEnum.PENDING.getStatus(), TpFormStatusEnum.PASS.getStatus(), TpFormStatusEnum.EFFECTIVE.getStatus()));
        return tpApplyFormMapper.selectOneByExample(example);
    }

    /**
     * 根据处罚单id列表查询申请单
     * @param penaltyIds 处罚单id列表
     * @return 申请单列表
     */
    public List<TpApplyFormDO> getByPenaltyIds(List<Long> penaltyIds) {
        if (CollectionUtils.isEmpty(penaltyIds)) {
            return Collections.emptyList();
        }
        Example example = new Example(TpApplyFormDO.class);
        example.createCriteria().andIn("penaltyId", penaltyIds).andEqualTo("deleted", 0);
        return tpApplyFormMapper.selectByExample(example);
    }

    /**
     * 过滤存在正在复议的申请单
     * @param penaltyIds 处罚单id列表
     * @return 存在复议的处罚单id列表
     */
    public Set<Long> filterExistAppeal(List<Long> penaltyIds) {
        if (CollectionUtils.isEmpty(penaltyIds)) {
            return Collections.emptySet();
        }
        Example example = new Example(TpApplyFormDO.class);
        example.createCriteria().andIn("penaltyId", penaltyIds)
                .andEqualTo("type", TpFormTypeEnum.APPEAL.getType())
                .andEqualTo("status", TpFormStatusEnum.PENDING.getStatus())
                .andEqualTo("deleted", 0);
        example.selectProperties("penaltyId");
        List<TpApplyFormDO> list = tpApplyFormMapper.selectByExample(example);
        return CollStreamUtil.toSet(list, TpApplyFormDO::getPenaltyId);
    }

    /**
     * 根据id列表查询
     */
    public List<TpApplyFormDO> getByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyList();
        }
        Example example = new Example(TpApplyFormDO.class);
        example.createCriteria().andIn("id", ids);
        return tpApplyFormMapper.selectByExample(example);
    }

    /**
     * 修改申请单状态
     */
    public void updateStatus(Long applyId, TpFormStatusEnum status) {
        Example example = new Example(TpApplyFormDO.class);
        example.createCriteria().andEqualTo("id", applyId).andEqualTo("deleted", 0);
        tpApplyFormMapper.updateByExampleSelective(TpApplyFormDO.builder().status(status.getStatus()).build(), example);
    }

    public void updateStatusBatch(List<Long> applyIds, TpFormStatusEnum status) {
        if (CollectionUtils.isEmpty(applyIds)) {
            return ;
        }
        Example example = new Example(TpApplyFormDO.class);
        example.createCriteria().andIn("id", applyIds).andEqualTo("deleted", 0);
        tpApplyFormMapper.updateByExampleSelective(TpApplyFormDO.builder().status(status.getStatus()).build(), example);
    }

    /**
     * 修改缴费状态
     */
    public void updatePayStatus(Long applyId, TpPayStatusEnum payStatus) {
        Example example = new Example(TpApplyFormDO.class);
        example.createCriteria().andEqualTo("id", applyId).andEqualTo("deleted", 0);
        tpApplyFormMapper.updateByExampleSelective(TpApplyFormDO.builder().payStatus(payStatus.getStatus()).build(), example);
    }

    /**
     * 根据id删除
     */
    public void deleteByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        Example example = new Example(TpApplyFormDO.class);
        example.createCriteria().andIn("id", ids).andEqualTo("deleted", 0);
        tpApplyFormMapper.updateByExampleSelective(TpApplyFormDO.builder().deleted(1).build(), example);
    }
}
