package com.jeesharp.business.modules.member.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jeesharp.business.modules.member.entity.MemberPointsRule;
import com.jeesharp.business.modules.member.entity.MemberPointsRuleLevel;
import com.jeesharp.business.modules.member.mapper.MemberPointsRuleLevelMapper;
import com.jeesharp.business.modules.member.mapper.MemberPointsRuleMapper;
import com.jeesharp.business.modules.member.service.MemberPointsRuleService;
import com.jeesharp.business.modules.member.vo.MemberPointsRuleQueryVO;
import com.jeesharp.framework.exception.BizErrorException;
import com.jeesharp.framework.mybatis.core.service.CrudService;
import com.jeesharp.framework.pojo.Page;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 积分规则领域服务实现。
 *
 * @author jeesharp
 * @since 2026-06-23
 */
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class MemberPointsRuleServiceImpl
        extends CrudService<MemberPointsRuleMapper, MemberPointsRule, MemberPointsRuleQueryVO>
        implements MemberPointsRuleService {

    private final MemberPointsRuleLevelMapper memberPointsRuleLevelMapper;

    @Override
    public MemberPointsRule getEnabledBySceneCode(String sceneCode) {
        if (StrUtil.isBlank(sceneCode)) {
            return null;
        }
        LambdaQueryWrapper<MemberPointsRule> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MemberPointsRule::getSceneCode, sceneCode.trim());
        wrapper.eq(MemberPointsRule::getStatus, 1);
        wrapper.eq(MemberPointsRule::getDelFlag, "0");
        wrapper.last("LIMIT 1");
        return getBaseMapper().selectOne(wrapper);
    }

    @Override
    public List<MemberPointsRuleLevel> listEnabledLevels(String ruleId) {
        LambdaQueryWrapper<MemberPointsRuleLevel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MemberPointsRuleLevel::getRuleId, ruleId);
        wrapper.eq(MemberPointsRuleLevel::getStatus, 1);
        wrapper.eq(MemberPointsRuleLevel::getDelFlag, "0");
        return memberPointsRuleLevelMapper.selectList(wrapper);
    }

    @Override
    public MemberPointsRuleLevel resolveLevelDetail(String ruleId, String levelId) {
        if (StrUtil.isNotBlank(levelId)) {
            LambdaQueryWrapper<MemberPointsRuleLevel> byLevel = new LambdaQueryWrapper<>();
            byLevel.eq(MemberPointsRuleLevel::getRuleId, ruleId);
            byLevel.eq(MemberPointsRuleLevel::getLevelId, levelId);
            byLevel.eq(MemberPointsRuleLevel::getStatus, 1);
            byLevel.eq(MemberPointsRuleLevel::getDelFlag, "0");
            byLevel.last("LIMIT 1");
            MemberPointsRuleLevel hit = memberPointsRuleLevelMapper.selectOne(byLevel);
            if (hit != null) {
                return hit;
            }
        }
        List<MemberPointsRuleLevel> levels = listEnabledLevels(ruleId);
        return levels.isEmpty() ? null : levels.get(0);
    }

    @Override
    public Page<MemberPointsRule> findPage(Page<MemberPointsRule> page, MemberPointsRuleQueryVO query) {
        return super.findPage(page, query);
    }

    @Override
    public MemberPointsRule getRule(String id) {
        return get(id);
    }

    @Override
    public boolean existsSceneCode(String sceneCode, String excludeId) {
        if (StrUtil.isBlank(sceneCode)) {
            return false;
        }
        LambdaQueryWrapper<MemberPointsRule> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MemberPointsRule::getSceneCode, sceneCode.trim());
        wrapper.eq(MemberPointsRule::getDelFlag, "0");
        if (StrUtil.isNotBlank(excludeId)) {
            wrapper.ne(MemberPointsRule::getId, excludeId);
        }
        return getBaseMapper().selectCount(wrapper) > 0;
    }

    @Override
    @Transactional(readOnly = false)
    public MemberPointsRule createRule(MemberPointsRule rule) {
        if (StrUtil.isNotBlank(rule.getId())) {
            throw new BizErrorException("新增规则不应预置主键");
        }
        getBaseMapper().insert(rule);
        return rule;
    }

    @Override
    @Transactional(readOnly = false)
    public void updateRule(MemberPointsRule rule) {
        if (StrUtil.isBlank(rule.getId())) {
            throw new BizErrorException("更新规则主键不能为空");
        }
        if (getRule(rule.getId()) == null) {
            throw new BizErrorException("积分规则不存在");
        }
        getBaseMapper().updateById(rule);
    }

    @Override
    @Transactional(readOnly = false)
    public void batchDeleteRules(List<String> ids) {
        if (ids == null || ids.isEmpty()) {
            return;
        }
        batchDelete(ids);
    }

    @Override
    public List<MemberPointsRuleLevel> listLevelsByRuleId(String ruleId) {
        LambdaQueryWrapper<MemberPointsRuleLevel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MemberPointsRuleLevel::getRuleId, ruleId);
        wrapper.eq(MemberPointsRuleLevel::getDelFlag, "0");
        wrapper.orderByAsc(MemberPointsRuleLevel::getLevelCode);
        return memberPointsRuleLevelMapper.selectList(wrapper);
    }

    @Override
    @Transactional(readOnly = false)
    public void replaceRuleLevels(String ruleId, List<MemberPointsRuleLevel> levels) {
        LambdaQueryWrapper<MemberPointsRuleLevel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MemberPointsRuleLevel::getRuleId, ruleId);
        memberPointsRuleLevelMapper.delete(wrapper);
        if (levels == null || levels.isEmpty()) {
            return;
        }
        for (MemberPointsRuleLevel level : levels) {
            level.setId(null);
            level.setRuleId(ruleId);
            if (level.getStatus() == null) {
                level.setStatus(1);
            }
            memberPointsRuleLevelMapper.insert(level);
        }
    }
}
