package com.bizzan.bitrade.consumer;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bizzan.bitrade.constant.BooleanEnum;
import com.bizzan.bitrade.constant.WithdrawStatus;
import com.bizzan.bitrade.dao.WithdrawRecordDao;
import com.bizzan.bitrade.entity.Coin;
import com.bizzan.bitrade.entity.Member;
import com.bizzan.bitrade.entity.MemberWallet;
import com.bizzan.bitrade.entity.WithdrawRecord;
import com.bizzan.bitrade.service.BiPayService;
import com.bizzan.bitrade.service.CoinService;
import com.bizzan.bitrade.service.MemberService;
import com.bizzan.bitrade.service.MemberWalletService;
import com.bizzan.bitrade.service.WithdrawRecordService;
import com.bizzan.bitrade.util.MessageResult;
import com.spark.bipay.constant.CoinType;
import com.spark.bipay.http.ResponseMessage;

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.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;

@Component
public class FinanceConsumer {
    private Logger logger = LoggerFactory.getLogger(FinanceConsumer.class);
    @Autowired
    private CoinService coinService;
    @Autowired
    private MemberWalletService walletService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;
    
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private WithdrawRecordService withdrawRecordService;
    @Autowired
    private BiPayService biPayService;
    @Autowired
    private WithdrawRecordDao withdrawApplyDao;

    /**
     * 处理充值消息，key值为币种的名称（注意是全称，如Bitcoin）
     *
     * @param record
     */
    @KafkaListener(topics = {"${kafka.topic.deposit:deposit}"})
    public void handleDeposit(ConsumerRecord<String, String> record) {
        logger.info("topic={},key={},value={}", record.topic(), record.key(), record.value());
        if (StringUtils.isEmpty(record.value())) {
            return;
        }
        JSONObject json = JSON.parseObject(record.value());
        if (json == null) {
            return;
        }
        BigDecimal amount = json.getBigDecimal("amount");
        String txid = json.getString("txid");
        String address = json.getString("address");
        Coin coin = coinService.findOne(record.key());
        
        logger.info("coin={}", coin);
        
        /*if(coin.getAccountType() == 1) {
        	Long memoId = json.getLong("userId"); // 备注Memo
        	Long userId = memoId - 345678; // 注意，此处与前端memo必须保持一致
        	Member m = memberService.findOne(userId);
        	if(m != null && walletService.findDepositByTxid(txid) == null) {
        		MessageResult mr = walletService.recharge2(userId, coin, address, amount, txid);
	            logger.info("wallet recharge result:{}", mr);
        	}
        }else {
	    */    if (coin != null && walletService.findDeposit(address, txid) == null) {
	            MessageResult mr = walletService.recharge(coin, address, amount, txid);
	            logger.info("wallet recharge result:{}", mr);
	        }
        //}
    }

    /**
     * 处理提交请求,调用钱包rpc，自动转账
     *
     * @param record
     */
    @KafkaListener(topics = {"${kafka.topic.withdraw:withdraw}"})
    public void handleWithdraw(ConsumerRecord<String, String> record) {
        logger.info("topic={},key={},value={}", record.topic(), record.key(), record.value());
        if (StringUtils.isEmpty(record.value())) {
            return;
        }
        JSONObject json = JSON.parseObject(record.value());
        Long withdrawId = json.getLong("withdrawId");
        try {
            String serviceName = "SERVICE-RPC-" + record.key().toUpperCase();
            String url = "http://" + serviceName + "/rpc/withdraw?address={1}&amount={2}&fee={3}";

            Coin coin = coinService.findByUnit(record.key());
            logger.info("coin = {}",coin.toString());
            if (coin != null && coin.getCanAutoWithdraw() == BooleanEnum.IS_TRUE) {
                BigDecimal minerFee = coin.getMinerFee();
                MessageResult result = restTemplate.getForObject(url,
                        MessageResult.class, json.getString("address"), json.getBigDecimal("arriveAmount"), minerFee);
                logger.info("=========================rpc 结束================================");
                logger.info("result = {}", result);
                if (result.getCode() == 0 && result.getData() != null) {
                    logger.info("====================== 处理成功,data为txid更新业务 ==================================");
                    //处理成功,data为txid，更新业务订单
                    String txid = (String) result.getData();
                    withdrawRecordService.withdrawSuccess(withdrawId, txid);
                } else {
                    logger.info("====================== 自动转账失败，转为人工处理 ==================================");
                    //自动转账失败，转为人工处理
                    withdrawRecordService.autoWithdrawFail(withdrawId);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("auto withdraw failed,error={}", e.getMessage());
            logger.info("====================== 自动转账失败，转为人工处理 ==================================");
//            自动转账失败，转为人工处理
            withdrawRecordService.autoWithdrawFail(withdrawId);
        }
    }
    
    @KafkaListener(topics = {"${kafka.topic.auto-withdraw:auto-withdraw}"})
    public void handleAutoWithdraw(ConsumerRecord<String, String> record) {
        logger.info("topic={},key={},value={}", record.topic(), record.key(), record.value());
        if (StringUtils.isEmpty(record.value())) {
            return;
        }
        WithdrawRecord withdrawRecord = JSON.parseObject(record.value(), WithdrawRecord.class);
        String orderId = withdrawRecord.getId().toString();
        String unit = withdrawRecord.getCoin().getUnit();
        CoinType coin = CoinType.unitOf(unit);
        String subCoinType = coin.getCode();
        if(unit.equals("TUSDT"))
        	subCoinType = "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t";
        else if(unit.equals("EUSDT"))
        	subCoinType = "0xdac17f958d2ee523a2206206994597c13d831ec7";
        else if(unit.equals("USDT-BEP20"))
        	subCoinType = "0x55d398326f99059ff775485246999027b3197955";
        logger.info("[Udun-autoWithdraw] 步骤1-调用Udun提币 withdrawId={}, orderId={}, unit={}, amount={}, address={}", withdrawRecord.getId(), orderId, unit, withdrawRecord.getArrivedAmount(), withdrawRecord.getAddress());
        ResponseMessage<String> resp = biPayService.transfer(orderId, withdrawRecord.getArrivedAmount(), coin, subCoinType, withdrawRecord.getAddress(), "");
        logger.info("[Udun-autoWithdraw] 步骤2-Udun返回 memberId={}, code={}, msg={}, data={}", withdrawRecord.getMemberId(), resp.getCode(), resp.getMessage(), resp.getData());
    	if(resp.getCode()!=200 && resp.getCode()!=ResponseMessage.ERROR_CODE) {
        	MemberWallet wallet = walletService.findByCoinAndMemberId(coinService.findByUnit("USDT"), withdrawRecord.getMemberId());
        	walletService.thawBalance(wallet.getId(), withdrawRecord.getTotalAmount());
        	
        	kafkaTemplate.send("trading-account-change", wallet.getMemberId()+"");
        	
        	withdrawRecord.setRemark(resp.getMessage());
            withdrawRecord.setStatus(WithdrawStatus.FAIL);
            withdrawRecord.setDealTime(new Date());
            withdrawApplyDao.save(withdrawRecord);
        }
    }


    /**
     * 异步打钱后返回状态
     * @param record
     */
    @KafkaListener(topics = {"${kafka.topic.withdraw-notify:withdraw-notify}"})
    public void withdrawNotify(ConsumerRecord<String, String> record){
        logger.info("topic={},accessKey={},value={}", record.topic(), record.key(), record.value());
        if (StringUtils.isEmpty(record.value())) {
            return;
        }
        JSONObject json = JSON.parseObject(record.value());
        Long withdrawId = json.getLong("withdrawId");
        WithdrawRecord withdrawRecord=withdrawRecordService.findOne(withdrawId);
        if(withdrawRecord==null){
            return;
        }
        String txid=json.getString("txid");
        int status=json.getInteger("status");
        //转账失败，状态变回等待放币
        if(status==0){
            withdrawRecord.setStatus(WithdrawStatus.WAITING);
            withdrawRecordService.save(withdrawRecord);
        }else if(status==1){
            withdrawRecordService.withdrawSuccess(withdrawId, txid);
        }
    }
    
    @KafkaListener(topics = {"${kafka.topic.after-deposit:after-deposit}"})
    public void afterDeposit(ConsumerRecord<String, String> record) {
        logger.info("topic={},key={},value={}", record.topic(), record.key(), record.value());
        if (StringUtils.isEmpty(record.value())) {
            return;
        }
        JSONObject json = JSON.parseObject(record.value());
        if (json == null) {
            return;
        }
    }
}
