package com.slodon.b2b2c.controller.member.front;

import com.slodon.b2b2c.core.constant.MemberWithdrawConst;
import com.slodon.b2b2c.core.controller.BaseController;
import com.slodon.b2b2c.core.response.JsonResult;
import com.slodon.b2b2c.core.response.PageVO;
import com.slodon.b2b2c.core.response.PagerInfo;
import com.slodon.b2b2c.core.response.SldResponse;
import com.slodon.b2b2c.core.util.*;
import com.slodon.b2b2c.member.example.MemberApplyCashExample;
import com.slodon.b2b2c.member.pojo.Member;
import com.slodon.b2b2c.member.pojo.MemberApplyCash;
import com.slodon.b2b2c.model.member.MemberApplyCashModel;
import com.slodon.b2b2c.model.member.MemberModel;
import com.slodon.b2b2c.starter.redisson.SlodonLock;
import com.slodon.b2b2c.starter.redisson.constant.LockKeyConst;
import com.slodon.b2b2c.vo.member.FrontMemberApplyCashVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @author slodon
 */
@Api(tags = "front-提现记录管理")
@RestController
@RequestMapping("v3/member/front/member/cash/log")
public class FrontMemberCashLogController extends BaseController {

    @Resource
    private MemberModel memberModel;
    @Resource
    private MemberApplyCashModel memberApplyCashModel;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private SlodonLock slodonLock;

    @ApiOperation("提现记录列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "state", value = "状态：1、待处理；2、提现成功；3、提现失败", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "分页大小", defaultValue = "20", paramType = "query"),
            @ApiImplicitParam(name = "current", value = "当前页面位置", defaultValue = "1", paramType = "query")
    })
    @GetMapping("list")
    public JsonResult<PageVO<FrontMemberApplyCashVO>> getList(HttpServletRequest request, Integer state) {
        AssertUtil.isTrue(!"1".equals(stringRedisTemplate.opsForValue().get("withdraw_is_enable")), "提现未开启");

        Member member = UserUtil.getUser(request, Member.class);

        PagerInfo pager = WebUtil.handlerPagerInfo(request);
        MemberApplyCashExample example = new MemberApplyCashExample();
        example.setMemberId(member.getMemberId());
        if (!StringUtil.isNullOrZero(state)) {
            if (state == MemberWithdrawConst.STATE_3) {
                example.setStateIn(MemberWithdrawConst.STATE_3 + ", " + MemberWithdrawConst.STATE_4);
            } else {
                example.setState(state);
            }
        }
        List<MemberApplyCash> list = memberApplyCashModel.getMemberApplyCashList(example, pager);
        List<FrontMemberApplyCashVO> vos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(memberApplyCash -> {
                vos.add(new FrontMemberApplyCashVO(memberApplyCash));
            });
        }
        return SldResponse.success(new PageVO<>(vos, pager));
    }

    @ApiOperation("提现详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cashId", value = "提现id", required = true)
    })
    @GetMapping("detail")
    public JsonResult<FrontMemberApplyCashVO> detail(HttpServletRequest request, @RequestParam(name = "cashId") Integer cashId) {
        AssertUtil.isTrue(!"1".equals(stringRedisTemplate.opsForValue().get("withdraw_is_enable")), "提现未开启");

        Member member = UserUtil.getUser(request, Member.class);
        //查询提现信息
        MemberApplyCash memberApplyCash = memberApplyCashModel.getMemberApplyCashByCashId(cashId);
        AssertUtil.notNull(memberApplyCash, "提现记录不存在");
        AssertUtil.isTrue(!memberApplyCash.getMemberId().equals(member.getMemberId()), "非法操作");
        return SldResponse.success(new FrontMemberApplyCashVO(memberApplyCash));
    }

    @ApiOperation("申请提现")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "accountId", value = "账号id"),
            @ApiImplicitParam(name = "cashAmount", value = "提现金额", required = true),
            @ApiImplicitParam(name = "payPwd", value = "支付密码", required = true),
            @ApiImplicitParam(name = "accountName", value = "真实姓名"),
            @ApiImplicitParam(name = "accountNumber", value = "支付宝账号")
    })
    @PostMapping("applyWithdraw")
    public JsonResult<Object> applyWithdraw(HttpServletRequest request, Integer accountId,
                                    @RequestParam(name = "cashAmount") BigDecimal cashAmount,
                                    @RequestParam(name = "payPwd") String payPwd, String accountName, String accountNumber) {
        AssertUtil.isTrue(!"1".equals(stringRedisTemplate.opsForValue().get("withdraw_is_enable")), "提现未开启");

        Member member = UserUtil.getUser(request, Member.class);

        //对用户加锁，防止同一用户在不同客户端重复提现
        String memberLockKey = LockKeyConst.MEMBER_WITHDRAW_PREFIX + member.getMemberId();
        slodonLock.lock(memberLockKey);
        try {
            //查询会员信息
            Member memberDb = memberModel.getMemberByMemberId(member.getMemberId());
            //校验密码
            AssertUtil.isTrue(!Md5.getMd5String(payPwd).equals(memberDb.getPayPwd()), "密码输入错误，请重新输入");
            //最低提现金额
            String minWithdrawAmount = stringRedisTemplate.opsForValue().get("min_withdraw_amount");
            if (!StringUtil.isEmpty(minWithdrawAmount) && !"0".equals(minWithdrawAmount)) {
                AssertUtil.isTrue(memberDb.getBalanceAvailable().compareTo(new BigDecimal(minWithdrawAmount)) < 0, "剩余可提现金额不足");
                AssertUtil.isTrue(cashAmount.compareTo(new BigDecimal(minWithdrawAmount)) < 0, "提现金额不可低于最低提现金额");
            }
            memberApplyCashModel.applyWithdraw(accountId, cashAmount, memberDb, accountName, accountNumber);

            return SldResponse.success("申请提交成功");
        } finally {
            slodonLock.unlock(memberLockKey);
        }
    }

    @ApiOperation("验证支付密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "payPwd", value = "支付密码", required = true)
    })
    @GetMapping("verifyPwd")
    public JsonResult<Object> verifyPwd(HttpServletRequest request, @RequestParam(name = "payPwd") String payPwd) {
        Member member = UserUtil.getUser(request, Member.class);
        Member memberDb = memberModel.getMemberByMemberId(member.getMemberId());
        //校验密码
        AssertUtil.isTrue(!Md5.getMd5String(payPwd).equals(memberDb.getPayPwd()), "密码输入错误，请重新输入");
        return SldResponse.success();
    }
}
