package com.bizzan.bitrade.consumer;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bizzan.bitrade.constant.ActivityRewardType;
import com.bizzan.bitrade.constant.BooleanEnum;
import com.bizzan.bitrade.constant.RewardRecordType;
import com.bizzan.bitrade.constant.TransactionType;
import com.bizzan.bitrade.entity.*;
import com.bizzan.bitrade.es.ESUtils;
import com.bizzan.bitrade.service.*;
import com.bizzan.bitrade.util.BigDecimalUtils;
import com.bizzan.bitrade.util.DateUtil;
import com.bizzan.bitrade.util.GeneratorUtil;
import com.bizzan.bitrade.util.HttpClientUtil;
import com.bizzan.bitrade.util.InnerInvokeUtil;
import com.bizzan.bitrade.util.MessageResult;

import org.apache.commons.lang.StringUtils;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import com.spark.bipay.constant.CoinType;
import com.spark.bipay.entity.Address;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;

@Component
public class MemberConsumer {
    private Logger logger = LoggerFactory.getLogger(MemberConsumer.class);
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private CoinService coinService;
    @Autowired
    private MemberWalletService memberWalletService;
    @Autowired
    private MemberWalletAddressBackupService memberWalletAddressBackupService;
    @Autowired
    private RewardActivitySettingService rewardActivitySettingService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private RewardRecordService rewardRecordService;
    @Autowired
    private MemberTransactionService memberTransactionService;
    @Autowired
    private ESUtils esUtils ;
    @Autowired
    private BiPayService biPayService;
    //@Autowired
    //private InnerInvokeUtil invokeUtil;
    
    /**
     * 重置用户钱包地址
     * @param record
     */
    @KafkaListener(topics = {"${kafka.topic.reset-member-address:reset-member-address}"})
    public void resetAddress(ConsumerRecord<String,String> record){
        try {
            doResetAddress(record);
        } catch (Exception e) {
            logger.error("[resetAddress] 处理异常, key={}, value={}", record != null ? record.key() : null, record != null ? record.value() : null, e);
        }
    }

    private void doResetAddress(ConsumerRecord<String,String> record){
        if (record == null) {
            logger.warn("[resetAddress] record is null");
            return;
        }
        String content = record.value();
        if (StringUtils.isEmpty(content)) {
            logger.warn("[resetAddress] content is empty, key={}", record.key());
            return;
        }
        JSONObject json = JSON.parseObject(content);
        if (json == null) {
            logger.warn("[resetAddress] json parse failed, content={}", content);
            return;
        }
        String coinUnit = record.key();
        if (StringUtils.isEmpty(coinUnit)) {
            logger.warn("[resetAddress] record.key() is empty");
            return;
        }
        Coin coin = coinService.findByUnit(coinUnit);
        if (coin == null) {
            logger.warn("[resetAddress] coin not found, unit={}", coinUnit);
            return;
        }
        Long uid = json.getLong("uid");
        if (uid == null || uid <= 0) {
            logger.warn("[resetAddress] uid invalid, content={}", content);
            return;
        }
        logger.info("[Udun-resetAddress] 步骤1-调用Udun创建地址 unit={}, uid={}", coin.getUnit(), uid);
        Address addressBack = biPayService.createCoinAddress(CoinType.unitOf(coin.getUnit()), null, null);
        logger.info("[Udun-resetAddress] 步骤2-Udun返回 address={}", addressBack != null ? addressBack.getAddress() : null);
        if (addressBack == null) {
            logger.warn("[resetAddress] createCoinAddress returned null, unit={}, uid={}", coin.getUnit(), uid);
            return;
        }
        String address = addressBack.getAddress();
        if (StringUtils.isEmpty(address)) {
            logger.warn("[resetAddress] address is empty, unit={}, uid={}", coin.getUnit(), uid);
            return;
        }
        MemberWallet memberWallet = memberWalletService.findByCoinUnitAndMemberId(coinUnit, uid);
        if (memberWallet == null) {
            logger.warn("[resetAddress] memberWallet not found, unit={}, uid={}", coinUnit, uid);
            return;
        }
        memberWallet.setAddress(address);
        memberWalletService.save(memberWallet);
        logger.info("[resetAddress] success, unit={}, uid={}, address={}", coinUnit, uid, address);
    }



    /**
     * 客户注册消息
     * @param content
     */
    @KafkaListener(topics = {"${kafka.topic.member-register:member-register}"})
    public void handle(String content) {
        logger.info("[注册流程-wallet] 收到member-register消息, data={}", content);
        if (StringUtils.isEmpty(content)) {
            logger.warn("[注册流程-wallet] 消息内容为空, 忽略");
            return;
        }
        JSONObject json = JSON.parseObject(content);
        if(json == null) {
            logger.warn("[注册流程-wallet] JSON解析失败, 忽略");
            return ;
        }
        Long memberId = json.getLong("uid");
        logger.info("[注册流程-wallet] 开始为memberId={}创建钱包", memberId);
        //获取所有支持的币种
        List<Coin> coins =  coinService.findAll();
        for(Coin coin:coins) {
            logger.info("[注册流程-wallet] 创建币种钱包 memberId={}, unit={}", memberId, coin.getUnit());
            MemberWallet wallet = new MemberWallet();
            wallet.setCoin(coin);
            wallet.setMemberId(json.getLong("uid"));
            wallet.setBalance(new BigDecimal(0));
            wallet.setFrozenBalance(new BigDecimal(0));
            wallet.setAddress("");
            
/** 此处获取地址注释掉，所有币种地址由用户主动获取才生成  **/
//            if(coin.getEnableRpc() == BooleanEnum.IS_TRUE) {
//                String account = "U" + json.getLong("uid");
//                //远程RPC服务URL,后缀为币种单位
//                String serviceName = "SERVICE-RPC-" + coin.getUnit();
//                try{
//                    String url = "http://" + serviceName + "/rpc/address/{account}";
//                    ResponseEntity<MessageResult> result = restTemplate.getForEntity(url, MessageResult.class, account);
//                    logger.info("remote call:service={},result={}", serviceName, result);
//                    if (result.getStatusCode().value() == 200) {
//                        MessageResult mr = result.getBody();
//                        logger.info("mr={}", mr);
//                        if (mr.getCode() == 0) {
//                            //返回地址成功，调用持久化
//                            String address = (String) mr.getData();
//                            wallet.setAddress(address);
//                        }
//                    }
//                }
//                catch (Exception e){
//                    logger.error("call {} failed,error={}",serviceName,e.getMessage());
//                    wallet.setAddress("");
//                }
//            }
//            else{
//                wallet.setAddress("");
//            }
            //保存
            memberWalletService.save(wallet);
        }
        logger.info("[注册流程-wallet] 已为memberId={}创建{}个币种钱包", memberId, coins.size());
        //invokeUtil.initWallets(json.getLong("uid"));
        //注册活动奖励
        RewardActivitySetting rewardActivitySetting = rewardActivitySettingService.findByType(ActivityRewardType.REGISTER);
        if (rewardActivitySetting!=null){
            MemberWallet memberWallet=memberWalletService.findByCoinAndMemberId(rewardActivitySetting.getCoin(),json.getLong("uid"));
            if (memberWallet==null){return;}
            // 奖励币
            BigDecimal amount3=JSONObject.parseObject(rewardActivitySetting.getInfo()).getBigDecimal("amount");
            memberWallet.setBalance(BigDecimalUtils.add(memberWallet.getBalance(),amount3));
            memberWalletService.save(memberWallet);
            // 保存奖励记录
            Member member = memberService.findOne(json.getLong("uid"));
            RewardRecord rewardRecord3 = new RewardRecord();
            rewardRecord3.setAmount(amount3);
            rewardRecord3.setCoin(rewardActivitySetting.getCoin());
            rewardRecord3.setMember(member);
            rewardRecord3.setRemark(rewardActivitySetting.getType().getCnName());
            rewardRecord3.setType(RewardRecordType.ACTIVITY);
            rewardRecordService.save(rewardRecord3);
            // 保存资产变更记录
            MemberTransaction memberTransaction = new MemberTransaction();
            memberTransaction.setFee(BigDecimal.ZERO);
            memberTransaction.setAmount(amount3);
            memberTransaction.setSymbol(rewardActivitySetting.getCoin().getUnit());
            memberTransaction.setType(TransactionType.ACTIVITY_AWARD);
            memberTransaction.setMemberId(member.getId());
            memberTransaction.setDiscountFee("0");
            memberTransaction.setRealFee("0");
            memberTransaction.setCreateTime(DateUtil.getCurrentDate());
            memberTransaction = memberTransactionService.save(memberTransaction);
            logger.info("[注册流程-wallet] 已发放注册活动奖励, memberId={}, amount={}", memberId, amount3);
        } else {
            logger.info("[注册流程-wallet] 无注册活动奖励配置");
        }
        logger.info("[注册流程-wallet] member-register处理完成, memberId={}", memberId);
    }
}
