package com.liquidnet.service.goblin.controller;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.liquidnet.common.exception.LiquidnetServiceException;
import com.liquidnet.commons.lang.constant.LnsRegex;
import com.liquidnet.commons.lang.util.CurrentUtil;
import com.liquidnet.commons.lang.util.IDCardUtil;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.goblin.constant.NftAccStatusEnum;
import com.liquidnet.service.goblin.dto.GoblinUserNftAccInfoVo;
import com.liquidnet.service.goblin.service.IGoblinNftUserService;
import com.liquidnet.service.goblin.util.GoblinRedisUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.Pattern;
import java.time.LocalDateTime;

@Api(tags = "NFT:账号相关")
@Slf4j
@RestController
@RequestMapping("user")
public class GoblinNFTUserController {

    @Autowired
    IGoblinNftUserService goblinNftUserService;
    @Autowired
    GoblinRedisUtils goblinRedisUtils;

    @ApiOperationSupport(order = 11)
    @ApiOperation(value = "业务账号开通", notes = "返回`data`值标识：业务账号状态[1-已开通]")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "bizCode", value = "业务码[NFT_ZX]", allowableValues = "NFT_ZX"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "name", value = "姓名"),
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "idCard", value = "身份证号"),
    })
    @PostMapping(value = "open/account")
    public ResponseDto<GoblinUserNftAccInfoVo> openAccount(@Pattern(regexp = "\\b(NFT_ZX)\\b", message = "业务码无效")
                                            @RequestParam String bizCode,
                                            @RequestParam String name,
                                            @RequestParam String idCard) {
        if (!java.util.regex.Pattern.matches(LnsRegex.Valid.CN_HANZI, name)) {
            return ResponseDto.failure(ErrorMapping.get("140013"));
        }
        if (!java.util.regex.Pattern.matches(LnsRegex.Valid.CN_ID_CARD_REF, idCard)) {
            return ResponseDto.failure(ErrorMapping.get("140014"));
        }
        if (IDCardUtil.getAge(idCard) < 18) {
            return ResponseDto.failure(ErrorMapping.get("140010"));
        }
        try {
            String currentUid = CurrentUtil.getCurrentUid();
            String mobile = (String) CurrentUtil.getTokenClaims().get(CurrentUtil.TOKEN_MOBILE);

            if (goblinRedisUtils.isCertmetaJunk(1, idCard, name, mobile)) {// 实名认证失败缓存命中
                return ResponseDto.failure(ErrorMapping.get("140016"));
            }
            GoblinUserNftAccInfoVo openAccountInfo = goblinRedisUtils.getOpenAccountInfo(currentUid);
            if (null != openAccountInfo) {// 已申请开通或开通处理中
                String code = openAccountInfo.getCode();
                if (!"3000".equals(code) && !"3001".equals(code)) { // 不可重试
                    return ResponseDto.success(openAccountInfo);
                }
            }

            return goblinNftUserService.openNftAccount(currentUid, bizCode, name, idCard, mobile);
        } catch (Exception e) {
            if (e instanceof LiquidnetServiceException) {
                LiquidnetServiceException lsEx = (LiquidnetServiceException) e;
                return ResponseDto.failure(lsEx.getCode(), lsEx.getMessage());
            }
            return ResponseDto.failure(ErrorMapping.get("140015"));
        }
    }

    @ApiOperationSupport(order = 11)
    @ApiOperation(value = "业务账号是否开通 废弃")
    @GetMapping(value = "open/account")
    public ResponseDto<Boolean> openAccount() {
        return ResponseDto.success(goblinRedisUtils.getNftNumAccount(CurrentUtil.getCurrentUid()));
    }

    @ApiOperationSupport(order = 11)
    @ApiOperation(value = "业务账号开通信息")
    @GetMapping(value = "open/account/info")
    public ResponseDto<GoblinUserNftAccInfoVo> openAccountInfo() {
        /*GoblinUserNftAccInfoVo nftAccInfoVo = GoblinUserNftAccInfoVo.getNew();
        nftAccInfoVo.setCode(NftAccStatusEnum.StatusAcc.ING.getCode());
        nftAccInfoVo.setMsg(NftAccStatusEnum.StatusAcc.ING.getMsg());
        nftAccInfoVo.setTime(LocalDateTime.now());
        goblinRedisUtils.setOpenAccountInfo(CurrentUtil.getCurrentUid(), nftAccInfoVo);*/
        return ResponseDto.success(goblinRedisUtils.getOpenAccountInfo(CurrentUtil.getCurrentUid()));
    }

    @ApiOperationSupport(order = 12)
    @ApiOperation(value = "业务账号开通信息-指定UID")
    @GetMapping(value = "open/account/info2")
    public ResponseDto<GoblinUserNftAccInfoVo> openAccountInfoByUid(@RequestParam String uid) {
        return ResponseDto.success(StringUtils.isBlank(uid) ? null : goblinRedisUtils.getOpenAccountInfo(uid));
    }
}
