package com.liquidnet.service.adam.controller;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.liquidnet.commons.lang.util.DESUtils;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.adam.dto.rsc.AdamChimeUinfoDto;
import com.liquidnet.service.adam.dto.rsc.AdamChimeUinfoReq;
import com.liquidnet.service.adam.dto.vo.*;
import com.liquidnet.service.adam.service.AdamRdmService;
import com.liquidnet.service.adam.service.IAdamUserService;
import com.liquidnet.service.adam.util.ObjectUtil;
import com.liquidnet.service.adam.util.QueueUtils;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.UserPathDto;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@ApiSupport(order = 10080)
@Api(tags = "@API:RSC")
@Slf4j
@Validated
@RestController
@RequestMapping("rsc")
public class AdamRscController {
    @Autowired
    AdamRdmService adamRdmService;
    @Autowired
    IAdamUserService adamUserService;

    @Autowired
    private QueueUtils queueUtils;


    @ApiOperationSupport(order = 10)
    @ApiOperation(value = "@API:手机号注册", notes = "用于小程序活动用户注册，不登录")
    @ApiImplicitParams({
            @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "mobile", value = "手机号"),
    })
    @PostMapping(value = {"reg/mobile"})
    public ResponseDto<AdamUserInfoVo> registerByMobile(@Pattern(regexp = "\\d{11}", message = "手机号格式有误")
                                                        @RequestParam String mobile) {
        AdamUserInfoVo userInfoVo;
        String uid = adamRdmService.getUidByMobile(mobile);
        if (StringUtils.isEmpty(uid)) {
            userInfoVo = adamUserService.register(mobile, 1);
            log.info(UserPathDto.setData("注册", mobile, userInfoVo));
        } else {
            userInfoVo = adamRdmService.getUserInfoVoByUid(uid);
            log.info(UserPathDto.setData("已注册", mobile, uid));
        }
        return ResponseDto.success(userInfoVo);
    }

    @ApiOperationSupport(order = 20)
    @ApiOperation(value = "@API:入场人列表", notes = "查取用户指定入场人列表")
    @GetMapping("inquire/enters")
    public ResponseDto<List<AdamEntersVo>> querysEnters(@NotBlank(message = "入场人ID不能为空") @RequestParam String entersIds,
                                                        @NotBlank(message = "用户ID不能为空") @RequestParam String uid) {
        List<AdamEntersVo> vos = entersIds.isEmpty() ? null : adamRdmService.getEntersVoByUidEntersIds(uid, Arrays.asList(entersIds.split(",")));
        return CollectionUtils.isEmpty(vos) ? ResponseDto.failure(ErrorMapping.get("10105")) : ResponseDto.success(vos);
    }

    @ApiOperationSupport(order = 21)
    @ApiOperation(value = "@API:会员信息")
    @GetMapping("inquire/member")
    public ResponseDto<AdamUserMemberVo> queryMember(@NotBlank(message = "用户ID不能为空") @RequestParam String uid) {
        return ResponseDto.success(adamRdmService.getUserMemberVoByUid(uid));
    }

    @ApiOperationSupport(order = 22)
    @ApiOperation(value = "@API:用户创建日期")
    @GetMapping("inquire/createdAt")
    public ResponseDto<LocalDateTime> queryCreatedAt(@NotBlank(message = "用户ID不能为空") @RequestParam String uid) {
        AdamUserInfoVo vo = adamRdmService.getUserInfoVoByUid(uid);
        if (vo == null) {
            return ResponseDto.success(LocalDateTime.of(2222, 1, 1, 1, 1, 1, 1));
        }
        return ResponseDto.success(vo.getCreateAt());
    }

//    @ApiOperationSupport(order = 23)
//    @ApiOperation(value = "@API:用户第三方业务账号")
//    @GetMapping("inquire/bizacc")
//    public ResponseDto<AdamUserBizAcctVo> queryBizacc(@Pattern(regexp = "\\b(NFT_ZX)\\b", message = "业务码无效")
//                                                      @RequestParam String bizCode,
//                                                      @NotBlank(message = "用户ID不能为空") @RequestParam String uid) {
//        List<AdamUserBizAcctVo> userBizAcctVoList = adamRdmService.getBizAcctVosByUid(uid);
//        if (!CollectionUtils.isEmpty(userBizAcctVoList)) {
//            Optional<AdamUserBizAcctVo> optional = userBizAcctVoList.stream().filter(r -> r.getBizCode().equals(bizCode)).findAny();
//            if (optional.isPresent()) return ResponseDto.success(optional.get());
//        }
//        return ResponseDto.success();
//    }

    @ApiOperationSupport(order = 30)
    @ApiOperation(value = "@API:票务下单所需信息查询", notes = "包括是否会员、收货地址及入场人信息")
    @PostMapping("inquire/of_buy_ticket")
    public ResponseDto<AdamRscPolymer01Vo> queryForBuyTicket(@RequestParam(required = false) String addressId,
                                                             @RequestParam(required = false) String entersIds,
                                                             @NotBlank(message = "用户ID不能为空") @RequestParam String uid) {
        AdamRscPolymer01Vo vo = AdamRscPolymer01Vo.getNew();

        AdamUserMemberVo userMemberInfo = adamRdmService.getUserMemberVoByUid(uid);
        AdamMemberVo memberVo = AdamMemberVo.getNew();
        memberVo.setUserMemberVo(userMemberInfo);
        vo.setMembership(memberVo.getStageMarker());

        if (!StringUtils.isEmpty(addressId)) {
            AdamAddressesVo addressesVo = adamRdmService.getAddressesVoByUidAddressesId(uid, addressId);
            vo.setAddressesVo(addressesVo);
        }

        if (!StringUtils.isEmpty(entersIds)) {
            List<AdamEntersVo> entersVos = adamRdmService.getEntersVoByUidEntersIds(uid, Arrays.asList(entersIds.split(",")));
            vo.setEntersVos(entersVos);
        }

        return ResponseDto.success(vo);
    }

    @ApiOperationSupport(order = 40)
    @ApiOperation(value = "@API:社交匹配用户信息", notes = "查询匹配到的用户信息")
    @PostMapping("inquire/cuinfo")
    public ResponseDto<List<AdamChimeUinfoDto>> queryForChimeUserInfo(@RequestBody AdamChimeUinfoReq req) {
        ArrayList<AdamChimeUinfoDto> list = ObjectUtil.getAdamChimeUinfoDtoArrayList();
        if (null == req || null == req.getUidList() || req.getUidList().isEmpty()) {
            return ResponseDto.success(list);
        }
        try {
            List<String> uidList = req.getUidList();
            uidList.forEach(r -> {
                AdamUserInfoVo userInfoVo = adamRdmService.getUserInfoVoByUid(r);
                if (null != userInfoVo) {
                    if (StringUtils.isEmpty(userInfoVo.getProvince())) {// 废弃`area`，兼容老版本处理
                        userInfoVo = adamRdmService.ratingProvince(userInfoVo);
                    }
                    list.add(AdamChimeUinfoDto.getNew().copy(userInfoVo));
                }
            });
        } catch (Exception e) {
            log.error("@API:社交匹配用户信息异常", e);
        }
        return ResponseDto.success(list);
    }

    @ApiOperationSupport(order = 40)
    @ApiOperation(value = "@API:社交用户点击喜欢或不喜欢", notes = "发送点击事件计数")
    @PostMapping("inquire/sendMsgToRedis")
    public ResponseDto<Boolean> sendMsgToRedis(@RequestParam(required = true) String redisKey, @RequestParam(required = true) String jsonParamStr) {
        if (null == redisKey || null == jsonParamStr || redisKey.isEmpty() || jsonParamStr.isEmpty()) {
            return ResponseDto.failure();
        }
        try {
            queueUtils.sendMsgByRedis(redisKey, jsonParamStr);
        } catch (Exception e) {
            log.error("@API:社交用户点击喜欢或不喜欢计数入队", e);
        }
        return ResponseDto.success(true);
    }

    @ApiOperationSupport(order = 50)
    @ApiOperation(value = "@API:NFT三要素", notes = "用于NFT认证成功的用户同步更新用户账号实名信息")
    @PostMapping(value = {"syn/certmeta"})
    public void syncUpdateReal(@NotBlank @RequestBody String certmeta) {
        try {
            String certmetaPlain = DESUtils.DES().decrypt(certmeta);// {uid},{mobile},{证件类型}{证件号},{姓名}
            log.info("NFT三要素同步实名信息:加解密信息[{} => {}]", certmeta, certmetaPlain);
            String[] certmetaPlainArr = certmetaPlain.split(",");

            String uid = certmetaPlainArr[0], mobile = certmetaPlainArr[1], idTypeCardNo = certmetaPlainArr[2];
            String uidByMobile = adamRdmService.getUidByMobile(mobile);
            if (org.apache.commons.lang3.StringUtils.isEmpty(uidByMobile) || !org.apache.commons.lang3.StringUtils.equals(uidByMobile, uid)) {
                log.warn("NFT三要素同步实名信息:手机号未注册/不匹配[{}]", certmetaPlain);
                return;
            }
            AdamRealInfoVo realInfoVoByUidPlain = adamRdmService.getRealInfoVoByUidPlain(uid);
            if (null == realInfoVoByUidPlain || realInfoVoByUidPlain.getNode() == 2) {
                int idType = Integer.parseInt(idTypeCardNo.substring(0, 1));
                adamUserService.identityForUpdate(uid, mobile, idType, 3, idTypeCardNo.substring(1), certmetaPlainArr[3]);
            } else {
                log.warn("NFT三要素同步实名信息:三要素信息已存在[certmetaPlain={},realInfoVoByUidPlain={}]", certmetaPlain, JsonUtils.toJson(realInfoVoByUidPlain));
            }
        } catch (Exception e) {
            log.warn("NFT三要素同步实名信息:参数解析失败[certmeta={}]", certmeta, e);
        }
    }
}
