package com.ruoyi.frequency.integralrecord.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.code.PublicCommon;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.exception.enums.CoreExceptionEnum;
import com.ruoyi.common.page.PageResult;
import com.ruoyi.controller.resp.IntegralPageResp;
import com.ruoyi.enums.IntegralDetailEnums;
import com.ruoyi.frequency.customer.entity.Customer;
import com.ruoyi.frequency.customer.mapper.CustomerMapper;
import com.ruoyi.frequency.customer.service.CustomerService;
import com.ruoyi.frequency.integralrecord.entity.IntegralRecord;
import com.ruoyi.frequency.integralrecord.mapper.IntegralRecordMapper;
import com.ruoyi.frequency.integralrecord.service.IntegralRecordService;
import com.ruoyi.frequency.store.entity.Store;
import com.ruoyi.frequency.store.mapper.StoreMapper;
import com.ruoyi.frequency.store.service.StoreService;
import com.ruoyi.frequency.wallerecord.model.result.WalletRecordCount;
import com.ruoyi.response.ResponseData;
import com.ruoyi.utils.BusinessUtil;
import com.ruoyi.vo.PageBasic;
import com.ruoyi.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * 积分记录Service业务层处理
 *
 * @author liwenlong
 * @date 2024-01-29
 */
@Service
public class IntegralRecordServiceImpl extends ServiceImpl<IntegralRecordMapper, IntegralRecord> implements IntegralRecordService {
    @Autowired
    private IntegralRecordMapper integralRecordMapper;

    /**
     * 查询积分记录
     *
     * @param id 积分记录主键
     * @return 积分记录
     */
    @Override
    public IntegralRecord selectIntegralRecordById(Long id) {
        return integralRecordMapper.selectIntegralRecordById(id);
    }

    /**
     * 查询积分记录列表
     *
     * @param integralRecord 积分记录
     * @return 积分记录
     */
    @Override
    public List<IntegralRecord> selectIntegralRecordList(IntegralRecord integralRecord) {
        List<IntegralRecord> integralRecords = integralRecordList(integralRecord);

        return integralRecords;
    }

    private List<IntegralRecord> integralRecordList(IntegralRecord integralRecord){
        List<IntegralRecord> integralRecords = integralRecordMapper.selectIntegralRecordList(integralRecord);

        if (integralRecords.size() > 0) {
            integralRecords.stream().forEach(s -> {
                s.setRecordName(IntegralDetailEnums.getName(s.getRecord()));
            });
        }
        return integralRecords;
    }

    /**
     * 新增积分记录
     *
     * @param integralRecord 积分记录
     * @return 结果
     */
    @Override
    public int insertIntegralRecord(IntegralRecord integralRecord) {
        integralRecord.setCreateData();
        return integralRecordMapper.insert(integralRecord);
    }

    /**
     * 修改积分记录
     *
     * @param integralRecord 积分记录
     * @return 结果
     */
    @Override
    public int updateIntegralRecord(IntegralRecord integralRecord) {
        integralRecord.setUpdateData();
        return integralRecordMapper.updateIntegralRecord(integralRecord);
    }

    /**
     * 批量删除积分记录
     *
     * @param ids 需要删除的积分记录主键
     * @return 结果
     */
    @Override
    public int deleteIntegralRecordByIds(Long[] ids, Integer delFlag) {
        this.lambdaUpdate().set(IntegralRecord::getDelFlag, delFlag).in(IntegralRecord::getId, ids).update();
        return ids.length;
    }

    @Autowired
    private CustomerMapper customerMapper;

    @Autowired
    private StoreMapper storeMapper;

    @Override
    public void updateIntegral(UserVo userVo, Long objectId, BigDecimal integral, IntegralDetailEnums integralDetailEnums,String remark) {
        if (integral.compareTo(BigDecimal.ZERO) == 0) {
            throw new CustomException(CoreExceptionEnum.ERROR_PARAM);
        }

        switch (userVo.getUserType()) {
            case 1:
                if (integral.compareTo(BigDecimal.ZERO) == 1) {
                    customerMapper.addIntegral(userVo.getUserId(), integral);
                } else {
                    boolean subBalance = customerMapper.subIntegral(userVo.getUserId(), integral.negate());
                    if (!subBalance) {
                        throw new CustomException(CoreExceptionEnum.BALANCE_INSUFFICIENT);
                    }
                }
                break;
            case 2:
                if (integral.compareTo(BigDecimal.ZERO) == 1) {
                    storeMapper.addIntegral(userVo.getUserId(), integral);
                } else {
                    boolean subBalance = storeMapper.subIntegral(userVo.getUserId(), integral.negate());
                    if (!subBalance) {
                        throw new CustomException(CoreExceptionEnum.BALANCE_INSUFFICIENT);
                    }
                }
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + userVo.getUserType());
        }

        //添加积分记录
        addIntegralRecord(userVo, objectId, integral, integralDetailEnums,remark);
    }

    @Autowired
    private BusinessUtil businessUtil;

    @Autowired
    private CustomerService customerService;

    @Autowired
    private StoreService storeService;

    private void addIntegralRecord(UserVo userVo, Long objectId, BigDecimal integral, IntegralDetailEnums integralDetailEnums,String remark) {
        IntegralRecord integralRecord = new IntegralRecord();
        integralRecord.setUserType(userVo.getUserType());
        integralRecord.setUserId(userVo.getUserId());
        integralRecord.setDelFlag(PublicCommon.启用);
        integralRecord.setRecord(integralDetailEnums.getCode());
        integralRecord.setIntegral(integral);
        integralRecord.setRemark(remark);
        if (objectId != null) {
            integralRecord.setObjectId(objectId);
        }

        //获取当前积分余额
        BigDecimal userIntegral = businessUtil.getUserIntegral(userVo);

        integralRecord.setCurrentBalance(userIntegral);
        this.save(integralRecord);

        //收益添加用户累计积分
        if (ObjectUtil.equal(IntegralDetailEnums.SHARE_TEAM_COMMISSION, integralDetailEnums) || ObjectUtil.equal(IntegralDetailEnums.REFEREE_SEND, integralDetailEnums)) {
            switch (userVo.getUserType()) {
                case 1:
                    customerService.lambdaUpdate().setSql("accumulate_integral = accumulate_integral + " + integral)
                            .eq(Customer::getId, userVo.getUserId())
                            .update();
                    break;
                case 2:
                    storeService.lambdaUpdate().setSql("accumulate_integral = accumulate_integral + " + integral)
                            .eq(Store::getId, userVo.getUserId())
                            .update();
                    break;
            }
        }
    }

    @Override
    public ResponseData integralPage(PageBasic req, UserVo userVo) {
        Page<IntegralPageResp> page = this.baseMapper.integralPage(new Page<>(req.getPageNo(), req.getPageSize()), userVo);

        if (page.getRecords().size() > 0) {
            page.getRecords().stream().forEach(s -> {
                s.setRecordName(IntegralDetailEnums.getName(s.getRecord()));
            });
        }

        return ResponseData.success(new PageResult<>(page));
    }

    @Override
    public WalletRecordCount statistics(IntegralRecord integralRecord) {
        List<IntegralRecord> integralRecords = integralRecordList(integralRecord);
        WalletRecordCount count = new WalletRecordCount();

        integralRecords.stream().forEach(x -> {
            if (x.getIntegral().compareTo(BigDecimal.ZERO) == 1) {
                count.setIncome(count.getIncome().add(x.getIntegral()));
            } else if (x.getIntegral().compareTo(BigDecimal.ZERO) == -1) {
                count.setExpenditure(count.getExpenditure().add(x.getIntegral()));
            }
        });

        return count;
    }
}
