
package com.tmerclub.cloud.multishop.controller.multishop;

import com.tmerclub.cloud.api.multishop.vo.ShopDetailVO;
import com.tmerclub.cloud.api.payment.constant.PaySysType;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.common.security.AuthUserContext;
import com.tmerclub.cloud.multishop.constant.ShopWalletAmountType;
import com.tmerclub.cloud.multishop.constant.ShopWalletChangeReason;
import com.tmerclub.cloud.multishop.constant.ShopWalletIoType;
import com.tmerclub.cloud.multishop.dto.AllinpayRechargeDTO;
import com.tmerclub.cloud.multishop.dto.ShopRechargeInfoDTO;
import com.tmerclub.cloud.multishop.mongo.MongoShopWalletLogBO;
import com.tmerclub.cloud.multishop.service.*;
import com.tmerclub.cloud.multishop.vo.ShopRechargeVO;
import com.tmerclub.cloud.multishop.vo.ShopWalletVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.Objects;

/**
 * 商家店铺余额充值
 * @author chiley
 */
@RestController("multishopRechargeController")
@RequestMapping("/m/shopRecharge")
@Tag(name = "multishop-商家余额充值")
public class ShopRechargeController {

    @Autowired
    private ShopWalletLogService shopWalletLogService;
    @Autowired
    private ShopWalletService shopWalletService;
    @Autowired
    private ShopAllinpayService shopAllinpayService;
    @Autowired
    private ShopDetailService shopDetailService;
    @Autowired
    private ShopRechargeService shopRechargeService;

    @PostMapping("/recharge")
    @Operation(summary = "充值订单", description = "生成余额充值订单，保存充值记录")
    public ServerResponseEntity<Long> save(@Valid @RequestBody ShopRechargeInfoDTO shopRechargeInfoDTO) {
        if (shopAllinpayService.getIsAllinpay()) {
            throw new LuckException("通联充值暂不支持该接口");
        }
        Long shopId = AuthUserContext.get().getTenantId();
        Long amount = checkAndGetAmount(shopRechargeInfoDTO, shopId);
        MongoShopWalletLogBO shopWalletLog = new MongoShopWalletLogBO();
        shopWalletLog.setShopId(shopId);
        shopWalletLog.setShopChangeAmount(amount);
        shopWalletLog.setUserAmount(amount);
        shopWalletLog.setShopIoType(ShopWalletIoType.INCOME.value());
        shopWalletLog.setReason(ShopWalletChangeReason.APPLY_RECHARGE.value());
        shopWalletLog.setAmountType(ShopWalletAmountType.SETTLED_AMOUNT.value());
        shopWalletLog.setCreateTime(new Date());
        shopWalletLog.setPaySysType(PaySysType.DEFAULT.value());
        shopWalletLogService.saveMongo(shopWalletLog);
        return ServerResponseEntity.success(shopWalletLog.getWalletLogId());
    }

    /**
     * @param shopRechargeInfoDTO
     * @return
     */
    @PostMapping("/allinpay_recharge")
    @Operation(summary = "通联充值订单", description = "生成余额充值订单，保存充值记录--通联独有")
    public ServerResponseEntity<ShopRechargeVO> allinpayRecharge(@Valid @RequestBody ShopRechargeInfoDTO shopRechargeInfoDTO) {
        if (!shopAllinpayService.getIsAllinpay()) {
            throw new LuckException("通联支付未开启");
        }
        Long shopId = AuthUserContext.get().getTenantId();
        ShopDetailVO shopDetailVO = shopDetailService.getByShopId(shopId);
        if (Objects.equals(shopDetailVO.getIsBindPhone(), 0)) {
            throw new LuckException("店铺还未绑定手机号码，无法进行充值");
        }

        Long amount = checkAndGetAmount(shopRechargeInfoDTO, shopId);
        MongoShopWalletLogBO shopWalletLog = new MongoShopWalletLogBO();
        shopWalletLog.setShopId(shopId);
        shopWalletLog.setUserAmount(amount);
        shopWalletLog.setShopChangeAmount(amount);
        shopWalletLog.setShopIoType(ShopWalletIoType.INCOME.value());
        shopWalletLog.setReason(ShopWalletChangeReason.APPLY_RECHARGE.value());
        shopWalletLog.setAmountType(ShopWalletAmountType.SETTLED_AMOUNT.value());
        shopWalletLog.setCreateTime(new Date());
        // 补充支付类型（默认支付/通联支付）
        shopWalletLog.setPaySysType(PaySysType.ALLINPAY.value());
        ShopRechargeVO shopRecharge = shopRechargeService.shopRecharge(shopWalletLog, shopRechargeInfoDTO.getReturnUrl());
        return ServerResponseEntity.success(shopRecharge);
    }

    private Long checkAndGetAmount(ShopRechargeInfoDTO shopRechargeInfoDTO, Long shopId) {
        Long amount = shopRechargeInfoDTO.getRechargeAmount().longValue();
        if (amount < 1) {
            throw new LuckException("充值金额有误");
        }
        ShopWalletVO shopWallet = shopWalletService.getByShopId(shopId);
        long userBalance = shopWallet.getSettledAmount() + amount;

        if (userBalance > Constant.MAX_USER_BALANCE) {
            throw new LuckException("此次充值会导致余额超出最大限制，故无法进行此操作,请减少充值金额后重试");
        }
        return amount;
    }

    @Operation(summary = "充值确认支付--暂不调用，采用微信正扫不需要该接口", description = "通联独有")
    @PostMapping("/confirm_recharge_pay")
    public ServerResponseEntity<Void> confirmRechargePay(@RequestBody AllinpayRechargeDTO rechargeDTO) {
        if (Objects.isNull(rechargeDTO.getBizOrderNo()) || Objects.isNull(rechargeDTO.getVerificationCode())) {
            throw new LuckException("短信验证码和订单号不能为空");
        }
        shopRechargeService.confirmRechargePay(rechargeDTO, AuthUserContext.get().getTenantId());
        return ServerResponseEntity.success();
    }

    @Operation(summary = "重新发送充值支付验证码--暂不调用，采用微信正扫不需要该接口", description = "通联独有")
    @PostMapping("/resendPaySms")
    public ServerResponseEntity<Void> resendPaySms(@RequestBody AllinpayRechargeDTO rechargeDTO) {
        if (Objects.isNull(rechargeDTO.getBizOrderNo())) {
            throw new LuckException("充值订单号不能为空");
        }
        shopRechargeService.resendPaySms(rechargeDTO.getBizOrderNo(), AuthUserContext.get().getTenantId());
        return ServerResponseEntity.success();
    }
}
