package com.fjhx.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.base.BaseEntity;
import com.fjhx.constants.ErrorMsgConstant;
import com.fjhx.constants.LibrarySupplyLockConstant;
import com.fjhx.entity.BackGoods;
import com.fjhx.enums.BackGoodsStatusEnum;
import com.fjhx.mapper.BackGoodsMapper;
import com.fjhx.service.BackGoodsService;
import com.fjhx.utils.Assert;
import org.springblade.core.redis.lock.RedisLockClient;
import org.springblade.core.secure.utils.AuthUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.function.Supplier;

/**
 * <p>
 * 退货单 服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2022-08-25
 */
@Service
public class BackGoodsServiceImpl extends ServiceImpl<BackGoodsMapper, BackGoods> implements BackGoodsService {

    @Resource
    private RedisLockClient redisLockClient;

    @Override
    public void launchBackGoods(BackGoods backGoods) {

        launchBackGoodsFun(backGoods, () -> {
            String code = backGoods.getCode();
            Assert.notEmpty(code, "退货单号不能为空");

            Long count = count(Wrappers.<BackGoods>lambdaQuery()
                    .eq(BackGoods::getCode, code)
                    .eq(BaseEntity::getTenantId, AuthUtil.getTenantId()));
            Assert.eqZero(count, "退货单号已存在");

            return code;
        });
    }

    @Override
    public void launchBackGoodsAuto(BackGoods backGoods, String codePrefix) {
        launchBackGoodsFun(backGoods, () -> createBackGoodsCode(codePrefix));
    }

    @Override
    public void launchBackGoodsAuto(BackGoods backGoods) {
        String codePrefix = "PB" + DateUtil.format(new Date(), "yyMMdd-");
        launchBackGoodsAuto(backGoods, codePrefix);
    }

    @Override
    public void flowNotPass(Long backGoodsId) {
        updateStatus(backGoodsId, BackGoodsStatusEnum.NOT_PASS);
    }

    @Override
    public void flowPass(Long backGoodsId) {
        updateStatus(backGoodsId, BackGoodsStatusEnum.PASS);
    }

    @Override
    public void refund(Long backGoodsId, BigDecimal price) {

        BackGoods backGoods = getById(backGoodsId);
        Assert.notEmpty(backGoods, "退款单不存在");

        // 赋值回款金额
        BigDecimal collectionPrice = backGoods.getCollectionPrice().add(price);
        backGoods.setCollectionPrice(collectionPrice);

        if (collectionPrice.compareTo(backGoods.getBackPrice()) >= 0) {
            backGoods.setStatus(BackGoodsStatusEnum.REFUND.getValue());
        } else {
            backGoods.setStatus(BackGoodsStatusEnum.PART_REFUND.getValue());
        }

        boolean b = updateById(backGoods);
        Assert.eqTrue(b, ErrorMsgConstant.SYSTEM_BUSY_ERROR);

    }

    /**
     * 发起退货
     *
     * @param backGoods 退货实体
     * @param fun       发起退货方法
     */
    private void launchBackGoodsFun(BackGoods backGoods, Supplier<String> fun) {
        String tenantId = AuthUtil.getTenantId();

        Boolean b = redisLockClient.lockFair(LibrarySupplyLockConstant.BACK_GOODS_CODE_LOCK + tenantId, () -> {

            BigDecimal unitPrice = backGoods.getUnitPrice();
            BigDecimal backQuantity = backGoods.getBackQuantity();

            Assert.notEmpty(backGoods.getSupplierId(), "供应商id不能为空");
            Assert.notEmpty(backGoods.getGoodsId(), "物品id不能为空");
            Assert.notEmpty(unitPrice, "退货单价不能为空");
            Assert.notEmpty(backQuantity, "退货数量不能为空");

            // 退款金额
            backGoods.setBackPrice(unitPrice.multiply(backQuantity));

            // 回款金额
            backGoods.setCollectionPrice(BigDecimal.ZERO);

            // 审批中
            backGoods.setStatus(BackGoodsStatusEnum.IN_APPROVAL.getValue());

            String code = fun.get();
            backGoods.setCode(code);
            save(backGoods);

            return true;
        });

        Assert.eqTrue(b, ErrorMsgConstant.SYSTEM_BUSY_ERROR);
    }

    /**
     * 自动生成申购单编号
     */
    public String createBackGoodsCode(String codePrefix) {
        StringBuilder builder = new StringBuilder();
        builder.append(codePrefix);

        BackGoods backGoods = getOne(Wrappers.<BackGoods>lambdaQuery()
                .select(BackGoods::getCode)
                .eq(BaseEntity::getTenantId, AuthUtil.getTenantId())
                .likeRight(BackGoods::getCode, codePrefix)
                .orderByDesc(BackGoods::getCode)
                .last("limit 1")
        );

        if (backGoods == null) {
            return builder.append("001").toString();
        }

        int codeNum = Integer.parseInt(backGoods.getCode().replace(codePrefix, ""));

        return builder.append(codeNum < 9 ? "00" : codeNum < 99 ? "0" : "").append(codeNum + 1).toString();
    }

    /**
     * 修改退款状态
     */
    private void updateStatus(Long backGoodsId, BackGoodsStatusEnum backGoodsStatusEnum) {
        update(Wrappers.<BackGoods>lambdaUpdate()
                .eq(BaseEntity::getId, backGoodsId)
                .set(BackGoods::getStatus, backGoodsStatusEnum.getValue())
                .set(BaseEntity::getUpdateUser, AuthUtil.getUserId())
                .set(BaseEntity::getUpdateTime, new Date())
        );
    }

}
