/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.biz.modular.consumptionrecord.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.C;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
import vip.xiaonuo.biz.modular.consumptionrecord.param.*;
import vip.xiaonuo.biz.modular.user.entity.BizUser;
import vip.xiaonuo.biz.modular.user.service.BizUserService;
import vip.xiaonuo.biz.modular.userfundchangerecord.entity.BizUserFundChangeRecord;
import vip.xiaonuo.biz.modular.userfundchangerecord.service.BizUserFundChangeRecordService;
import vip.xiaonuo.common.cache.CommonCacheOperator;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.biz.modular.consumptionrecord.entity.ConsumptionRecord;
import vip.xiaonuo.biz.modular.consumptionrecord.mapper.ConsumptionRecordMapper;
import vip.xiaonuo.biz.modular.consumptionrecord.service.ConsumptionRecordService;
import vip.xiaonuo.common.util.CommonCryptogramUtil;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 消费记录Service接口实现类
 *
 * @author fanzherong
 * @date  2025/02/06 08:56
 **/
@Service
public class ConsumptionRecordServiceImpl extends ServiceImpl<ConsumptionRecordMapper, ConsumptionRecord> implements ConsumptionRecordService {

    @Resource
    private BizUserService bizUserService;

    @Resource
    private CommonCacheOperator commonCacheOperator;

    @Resource
    private BizUserFundChangeRecordService bizUserFundChangeRecordService;

    @Override
    public Page<ConsumptionRecord> page(ConsumptionRecordPageParam consumptionRecordPageParam) {
        QueryWrapper<ConsumptionRecord> queryWrapper = new QueryWrapper<ConsumptionRecord>().checkSqlInjection();
        if(ObjectUtil.isNotEmpty(consumptionRecordPageParam.getUserName())){
            queryWrapper.like("su.name",consumptionRecordPageParam.getUserName());
        }
        if(ObjectUtil.isNotEmpty(consumptionRecordPageParam.getConsumptionOperate())){
            queryWrapper.eq("cr.consumption_operate",consumptionRecordPageParam.getConsumptionOperate());
        }
        if(ObjectUtil.isNotEmpty(consumptionRecordPageParam.getOrgId())){
            queryWrapper.eq("cr.consumption_org",consumptionRecordPageParam.getOrgId());
        }
        if(ObjectUtil.isNotEmpty(consumptionRecordPageParam.getConsumptionTimeBegin()) &&
                ObjectUtil.isNotEmpty(consumptionRecordPageParam.getConsumptionTimeEnd())){
            queryWrapper.between("cr.consumption_time",consumptionRecordPageParam.getConsumptionTimeBegin()+" 00:00:00",consumptionRecordPageParam.getConsumptionTimeEnd()+" 23:59:59");
        }
        // 校验数据范围
        List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
        if (ObjectUtil.isNotEmpty(loginUserDataScope)) {
            queryWrapper.in("cr.consumption_org", loginUserDataScope);
        } else {
            queryWrapper.in("cr.user_id", StpLoginUserUtil.getLoginUser().getId());
        }
        queryWrapper.orderByDesc("cr.create_time");
        Page<ConsumptionRecord> pageList = this.getBaseMapper().getPageList(CommonPageRequest.defaultPage(), queryWrapper);
        for(ConsumptionRecord consumptionRecord : pageList.getRecords()){
            if(ObjectUtil.isNotEmpty(consumptionRecord.getPhone())){
                consumptionRecord.setPhone(CommonCryptogramUtil.doSm4CbcDecrypt(consumptionRecord.getPhone()));
            }
            if(StringUtils.equals(consumptionRecord.getConsumptionOperate(),"3") || StringUtils.equals(consumptionRecord.getConsumptionOperate(),"4")){
                //消费结算，设置下说明
                if(StringUtils.equals(consumptionRecord.getConsumptionType(),"1")){
                    consumptionRecord.setConsumptionRemark("代金券消费"+consumptionRecord.getVoucherMoney().stripTrailingZeros().toPlainString()+"元");
                }
                if(StringUtils.equals(consumptionRecord.getConsumptionType(),"2")){
                    consumptionRecord.setConsumptionRemark("账户余额消费"+consumptionRecord.getAccountMoney().stripTrailingZeros().toPlainString()+"元");
                }
                if(StringUtils.equals(consumptionRecord.getConsumptionType(),"3")){
                    consumptionRecord.setConsumptionRemark("代金券消费"+consumptionRecord.getVoucherMoney().stripTrailingZeros().toPlainString()+"元"+"，账户余额消费"+consumptionRecord.getAccountMoney().stripTrailingZeros().toPlainString()+"元");
                }
            }
        }
        return pageList;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(ConsumptionRecordAddParam consumptionRecordAddParam) {
        //前置参数校验
        checkParam(consumptionRecordAddParam);
        ConsumptionRecord consumptionRecord = BeanUtil.toBean(consumptionRecordAddParam, ConsumptionRecord.class);
        //获取用户信息
        BizUser bizUser = bizUserService.getById(consumptionRecordAddParam.getUserId());
        //记录账户变动信息
        BizUserFundChangeRecord bizUserFundChangeRecord = new BizUserFundChangeRecord();
        bizUserFundChangeRecord.setOldAccountBalance(bizUser.getAccountBalance());
        bizUserFundChangeRecord.setOldVoucherBalance(bizUser.getVoucherBalance());
        //消费记录信息
        consumptionRecord.setVoucherBalance(bizUser.getVoucherBalance());
        consumptionRecord.setAccountBalance(bizUser.getAccountBalance());
        if(StringUtils.equals(consumptionRecordAddParam.getConsumptionOperate(),"1")){
            bizUserFundChangeRecord.setChangeType("4");
            //会员赠送
            if(StringUtils.equals(consumptionRecordAddParam.getConsumptionType(),"1")){
                //判断当前选择的是代金券还是余额 1：代金券   2：余额
                //选择代金券，用户原有代金券金额+本地赠送金额
                bizUser.setVoucherBalance(bizUser.getVoucherBalance().add(consumptionRecordAddParam.getConsumptionMoney()));
                consumptionRecord.setVoucherMoney(consumptionRecordAddParam.getConsumptionMoney());
            }else if(StringUtils.equals(consumptionRecordAddParam.getConsumptionType(),"2")){
                //选择余额，用户原有余额+本次赠送余额金额
                bizUser.setAccountBalance(bizUser.getAccountBalance().add(consumptionRecordAddParam.getConsumptionMoney()));
                consumptionRecord.setAccountMoney(consumptionRecordAddParam.getConsumptionMoney());
            }
        }else if(StringUtils.equals(consumptionRecordAddParam.getConsumptionOperate(),"2")){
            bizUserFundChangeRecord.setChangeType("5");
            if(bizUser.getVoucherBalance().compareTo(BigDecimal.ZERO) == 0){
                throw new CommonException("会员当前代金券余额为0，不可扣减！");
            }
            if(bizUser.getAccountBalance().compareTo(BigDecimal.ZERO) == 0){
                throw new CommonException("会员当前账户余额为0，不可扣减！");
            }
            //会员扣减
            if(StringUtils.equals(consumptionRecordAddParam.getConsumptionType(),"1")){
                //选择代金券，用户原有代金券金额-本次扣减金额
                if(consumptionRecord.getConsumptionMoney().compareTo(bizUser.getVoucherBalance()) > 0){
                    throw new CommonException("会员当前代金券余额不足，不可扣减！");
                }
                bizUser.setVoucherBalance(bizUser.getVoucherBalance().subtract(consumptionRecordAddParam.getConsumptionMoney()));
                consumptionRecord.setVoucherMoney(consumptionRecordAddParam.getConsumptionMoney());
            }else if(StringUtils.equals(consumptionRecordAddParam.getConsumptionType(),"2")){
                //选择账户余额，用户原有余额-本次扣减余额
                if(consumptionRecord.getConsumptionMoney().compareTo(bizUser.getAccountBalance()) > 0){
                    throw new CommonException("会员当前账户余额不足，不可扣减！");
                }
                bizUser.setAccountBalance(bizUser.getAccountBalance().subtract(consumptionRecordAddParam.getConsumptionMoney()));
                consumptionRecord.setAccountMoney(consumptionRecordAddParam.getConsumptionMoney());
            }
        }else{
            bizUserFundChangeRecord.setChangeType("2");
            //正常消费结算
            //人工结算需要短信校验,获取手机验证码
            if(StringUtils.equals(consumptionRecordAddParam.getConsumptionOperate(),"3")){
                Object code = commonCacheOperator.get(consumptionRecordAddParam.getPhoneNumber());
                if(!StringUtils.equals(code.toString(),consumptionRecordAddParam.getPhoneCode())){
                    throw new CommonException("验证码不正确！");
                }else{
                    commonCacheOperator.remove(consumptionRecordAddParam.getPhoneNumber());
                }
            }
            //判断当前消费金额是否大于代金券金额，优先扣减代金券金额
            if(consumptionRecordAddParam.getConsumptionMoney().compareTo(bizUser.getVoucherBalance()) > 0){
                //判断代金券金额是否大于0
                if(bizUser.getVoucherBalance().compareTo(BigDecimal.ZERO) > 0){
                    consumptionRecord.setConsumptionType("3");
                }else{
                    consumptionRecord.setConsumptionType("2");
                }
                //计算本次消费和代金券差额
                BigDecimal subtract = consumptionRecordAddParam.getConsumptionMoney().subtract(bizUser.getVoucherBalance());
                //如果差额大于账户余额，表示账户余额不足
                if(subtract.compareTo(bizUser.getAccountBalance()) > 0){
                    throw new CommonException("账户余额不足，请先充值！");
                }
                //记录消费信息
                consumptionRecord.setVoucherMoney(bizUser.getVoucherBalance());
                //代金券直接清空
                bizUser.setVoucherBalance(new BigDecimal(0));
                //余额扣去差额
                bizUser.setAccountBalance(bizUser.getAccountBalance().subtract(subtract));
                consumptionRecord.setAccountMoney(subtract);
            }else{
                //直接扣减代金券
                bizUser.setVoucherBalance(bizUser.getVoucherBalance().subtract(consumptionRecordAddParam.getConsumptionMoney()));
                consumptionRecord.setVoucherMoney(consumptionRecordAddParam.getConsumptionMoney());
                consumptionRecord.setConsumptionType("1");
            }
        }
        //保存消费记录
        consumptionRecord.setConsumptionOrg(StpLoginUserUtil.getLoginUser().getOrgId());
        consumptionRecord.setConsumptionTime(new Date());
        this.save(consumptionRecord);
        //修改账户余额
        bizUserService.updateById(bizUser);
        //账户变动信息
        bizUserFundChangeRecord.setNewAccountBalance(bizUser.getAccountBalance());
        bizUserFundChangeRecord.setNewVoucherBalance(bizUser.getVoucherBalance());
        bizUserFundChangeRecord.setUserId(bizUser.getId());
        bizUserFundChangeRecordService.save(bizUserFundChangeRecord);
    }

    //会员赠送/扣减
    public void customerConsumption(ConsumptionRecordAddParam consumptionRecordAddParam){

    }

    //参数校验
    public void checkParam(ConsumptionRecordAddParam consumptionRecordAddParam){
        //判断当前操作consumptionOperate  1：会员赠送  2：会员扣减  3：消费结算
        if(ObjectUtil.isEmpty(consumptionRecordAddParam.getConsumptionOperate())){
            throw new CommonException("消费操作consumptionOperate不能为空！");
        }
        if(StringUtils.equals(consumptionRecordAddParam.getConsumptionOperate(),"1") || StringUtils.equals(consumptionRecordAddParam.getConsumptionOperate(),"2")){
            //会员操作填写说明
            if(ObjectUtil.isEmpty(consumptionRecordAddParam.getConsumptionRemark())){
                throw new CommonException("消费说明consumptionRemark不能为空！");
            }
            //选择赠送和扣减操作时要选择代金券还是账户余额
            if(ObjectUtil.isEmpty(consumptionRecordAddParam.getConsumptionType())){
                throw new CommonException("消费方式consumptionType不能为空！");
            }
        }
        if(StringUtils.equals(consumptionRecordAddParam.getConsumptionOperate(),"3")){
            //人工结算，手机号，短信验证码校验
            if(ObjectUtil.isEmpty(consumptionRecordAddParam.getPhoneNumber())){
                throw new CommonException("手机号phoneNumber不能为空！");
            }
            if(ObjectUtil.isEmpty(consumptionRecordAddParam.getPhoneCode())){
                throw new CommonException("短信验证码phoneCode不能为空！");
            }
        }
        if(ObjectUtil.isEmpty(consumptionRecordAddParam.getUserId())){
            throw new CommonException("用户userId不能为空！");
        }
        if(ObjectUtil.isNotEmpty(consumptionRecordAddParam.getPhoneNumber())){
            if (!PhoneUtil.isMobile(consumptionRecordAddParam.getPhoneNumber())) {
                throw new CommonException("手机号码：{}格式错误", consumptionRecordAddParam.getPhoneNumber());
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(ConsumptionRecordEditParam consumptionRecordEditParam) {
        ConsumptionRecord consumptionRecord = this.queryEntity(consumptionRecordEditParam.getId());
        BeanUtil.copyProperties(consumptionRecordEditParam, consumptionRecord);
        this.updateById(consumptionRecord);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<ConsumptionRecordIdParam> consumptionRecordIdParamList) {
        // 执行删除
        this.removeByIds(CollStreamUtil.toList(consumptionRecordIdParamList, ConsumptionRecordIdParam::getId));
    }

    @Override
    public ConsumptionRecord detail(ConsumptionRecordIdParam consumptionRecordIdParam) {
        return this.queryEntity(consumptionRecordIdParam.getId());
    }

    @Override
    public ConsumptionRecord queryEntity(String id) {
        ConsumptionRecord consumptionRecord = this.getById(id);
        if(ObjectUtil.isEmpty(consumptionRecord)) {
            throw new CommonException("消费记录不存在，id值为：{}", id);
        }
        return consumptionRecord;
    }

    @Override
    public ConsumptionResult getRecordTotal() {
        String format = DateUtil.format(DateUtil.date(), "yyyy-MM-dd");
        QueryWrapper<ConsumptionRecord> queryWrapper = new QueryWrapper<>();
        // 校验数据范围
        List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
        if (ObjectUtil.isNotEmpty(loginUserDataScope)) {
            queryWrapper.in("bcr.consumption_org", loginUserDataScope);
        }else{
            ConsumptionResult consumptionResult = new ConsumptionResult();
            consumptionResult.setOrderCount(0);
            consumptionResult.setOrderMoney(new BigDecimal(0));
            return consumptionResult;
        }
        queryWrapper.in("bcr.consumption_operate",'3','4');
        queryWrapper.between("bcr.consumption_time", format+" 00:00:00",format+" 23:59:59");
        return this.getBaseMapper().getRecordTotal(queryWrapper);
    }
}
