/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.qs.mp.web.controller.api.channel;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qs.mp.channel.domain.Channel;
import com.qs.mp.channel.domain.ChannelBankCard;
import com.qs.mp.channel.domain.ChannelCart;
import com.qs.mp.channel.domain.ChannelWithdraw;
import com.qs.mp.channel.domain.param.ChannelCartParam;
import com.qs.mp.channel.domain.param.ChannelWithdrawParam;
import com.qs.mp.channel.domain.vo.ChannelCartVO;
import com.qs.mp.channel.domain.vo.ChannelOrderSettleVO;
import com.qs.mp.channel.service.IChannelBankCardService;
import com.qs.mp.channel.service.IChannelCartService;
import com.qs.mp.channel.service.IChannelService;
import com.qs.mp.channel.service.IChannelWithdrawService;
import com.qs.mp.common.core.domain.AjaxResult;
import com.qs.mp.common.core.redis.RedisCache;
import com.qs.mp.common.domain.param.BatchLongIdsParam;
import com.qs.mp.common.enums.ChannelStatusEnum;
import com.qs.mp.common.utils.StringUtils;
import com.qs.mp.system.service.ISysConfigService;
import com.qs.mp.utils.SecurityUtils;
import com.qs.mp.web.controller.common.BaseApiController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.validation.Valid;
import lombok.AllArgsConstructor;
import ma.glasnost.orika.MapperFacade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
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;


@RestController
@RequestMapping("/api/v1/mp/channel")
@Api(tags = "渠道提现接口")
@AllArgsConstructor
public class ChannelWithdrawController extends BaseApiController {


  @Autowired
  private IChannelWithdrawService channelWithdrawService;

  @Autowired
  private IChannelService channelService;

  @Autowired
  private IChannelBankCardService channelBankCardService;

  @Autowired
  private RedisCache redisCache;

  private final String CHANNEL_WITHDRAW_CACHE_KEY = "channel_settle_withdraw_";

  @Autowired
  private ISysConfigService configService;

  /**
   * 提现费率配置key
   */
  private final String FEE_RATE_CONFIG_KEY = "channel.withdraw.feeRate";
  /**
   * 提现费率默认值
   */
  private final String FEE_RATE_DEFAULT_VALUE = "0.8";

  /**
   * 渠道提现计算手续费
   */
  @PostMapping("/withdraw/settle")
  @ApiOperation(value = "提现" , notes = "提现计费")
  public AjaxResult settle(@Valid @RequestBody ChannelWithdrawParam param) {
    String feeRateValue = configService.selectConfigByKey(FEE_RATE_CONFIG_KEY);
    BigDecimal feeRate = new BigDecimal(
        StringUtils.isNotBlank(feeRateValue) ? feeRateValue : FEE_RATE_DEFAULT_VALUE);
    Long channelId = SecurityUtils.getLoginUser().getChannelId();
    Channel channel = channelService.getById(channelId);
    if (channel.getStatus() == ChannelStatusEnum.OFF) {
      return AjaxResult.error("账号异常");
    }
    if (param.getMoney() > channel.getMoney() ) {
      return AjaxResult.error("提现金额超出了余额");
    }
    int feeAmt = new BigDecimal(param.getMoney()).multiply(feeRate)
        .divide(new BigDecimal(100), 0, RoundingMode.HALF_UP).intValue();
    ChannelWithdraw channelWithdraw = new ChannelWithdraw();
    if (param.getMoney() + feeAmt > channel.getMoney()) {
      channelWithdraw.setMoney(new BigDecimal(channel.getMoney()).divide(new BigDecimal(1).add(feeRate.divide(new BigDecimal(100), 4, RoundingMode.HALF_UP)), 0, RoundingMode.HALF_UP).intValue());
      channelWithdraw.setChargeAmt(channel.getMoney() - channelWithdraw.getMoney());
    } else {
      channelWithdraw.setMoney(param.getMoney());
      channelWithdraw.setChargeAmt(feeAmt);
  }
    channelWithdraw.setUserName(param.getUserName());
    channelWithdraw.setCardNo(param.getCardNo());
    channelWithdraw.setBankName(param.getBankName());
    channelWithdraw.setBranchName(param.getBranchName());

    // 缓存订单结算对象
    redisCache.setCacheObject(CHANNEL_WITHDRAW_CACHE_KEY + channelId, channelWithdraw, 1, TimeUnit.MINUTES);

    JSONObject jsonObject = new JSONObject();
    jsonObject.put("withdrawAmt", channelWithdraw.getMoney());
    jsonObject.put("chargeAmt", channelWithdraw.getChargeAmt());
    jsonObject.put("chargeRate", feeRate);
    return AjaxResult.success(jsonObject);
  }

  /**
   * 渠道提现申请提交
   */
  @PostMapping("/withdraw/apply")
  @ApiOperation(value = "提交提现申请" , notes = "确认服务费后提交")
  public AjaxResult apply(@RequestBody ChannelWithdrawParam param) {
    Long channelId = SecurityUtils.getLoginUser().getChannelId();
    ChannelWithdraw channelWithdraw = redisCache.getCacheObject(CHANNEL_WITHDRAW_CACHE_KEY + channelId);
    if (null == channelWithdraw) {
      return AjaxResult.error("申请已过期，请重新提交");
    }
    Channel channel = channelService.getById(channelId);
    if (channelWithdraw.getMoney() + channelWithdraw.getChargeAmt() > channel.getMoney() ) {
      return AjaxResult.error("提现金额超出账户余额");
    }

    channelWithdraw.setChannelId(channelId);
    channelWithdraw.setAvailableMoney(channel.getMoney());

    channelWithdrawService.apply(channel, channelWithdraw);

    // 缓存提现结算对象
    redisCache.deleteObject(CHANNEL_WITHDRAW_CACHE_KEY + channelId);

    return AjaxResult.success("提现申请成功");
  }

  /**
   * 渠道提现查询银行卡
   */
  @PostMapping("/withdraw/card/query")
  @ApiOperation(value = "查询银行卡" , notes = "查询银行卡信息")
  public AjaxResult queryCard(@RequestBody ChannelWithdrawParam param) {
    Long channelId = SecurityUtils.getLoginUser().getChannelId();
    ChannelBankCard bankCard = channelBankCardService.getOne(new LambdaQueryWrapper<ChannelBankCard>()
        .eq(ChannelBankCard::getChannelId, channelId));

    return AjaxResult.success(bankCard);
  }
}
