package org.mengyun.tcctransaction.sample.http.redpacket.service;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.mengyun.tcctransaction.api.Compensable;
import org.mengyun.tcctransaction.api.TransactionContext;
import org.mengyun.tcctransaction.context.MethodTransactionContextEditor;
import org.mengyun.tcctransaction.sample.http.redpacket.api.RedPacketTradeOrderService;
import org.mengyun.tcctransaction.sample.http.redpacket.api.dto.RedPacketTradeOrderDto;
import org.mengyun.tcctransaction.sample.http.redpacket.domain.entity.RedPacketAccount;
import org.mengyun.tcctransaction.sample.http.redpacket.domain.entity.TradeOrder;
import org.mengyun.tcctransaction.sample.http.redpacket.domain.repository.RedPacketAccountRepository;
import org.mengyun.tcctransaction.sample.http.redpacket.domain.repository.TradeOrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.Calendar;

/**
 * Created by changming.xie on 4/2/16.
 */
public class RedPacketTradeOrderServiceImpl implements RedPacketTradeOrderService {

    @Autowired
    RedPacketAccountRepository redPacketAccountRepository;

    @Autowired
    TradeOrderRepository tradeOrderRepository;

    @Override
    @Compensable(confirmMethod = "confirmRecord", cancelMethod = "cancelRecord", transactionContextEditor = MethodTransactionContextEditor.class)
    @Transactional
    public String record(TransactionContext transactionContext, RedPacketTradeOrderDto tradeOrderDto) {
        System.out.println("red packet try record called. time seq:" + DateFormatUtils.format(Calendar.getInstance(), "yyyy-MM-dd HH:mm:ss"));

        try {
            Thread.sleep(1000l);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        TradeOrder tradeOrder = new TradeOrder(
                tradeOrderDto.getSelfUserId(),
                tradeOrderDto.getOppositeUserId(),
                tradeOrderDto.getMerchantOrderNo(),
                tradeOrderDto.getAmount()
        );

        tradeOrderRepository.insert(tradeOrder);

        RedPacketAccount transferFromAccount = redPacketAccountRepository.findByUserId(tradeOrderDto.getSelfUserId());

        transferFromAccount.transferFrom(tradeOrderDto.getAmount());

        redPacketAccountRepository.save(transferFromAccount);

        return "success";
    }

    @Transactional
    public void confirmRecord(TransactionContext transactionContext, RedPacketTradeOrderDto tradeOrderDto) {
        System.out.println("red packet confirm record called. time seq:" + DateFormatUtils.format(Calendar.getInstance(), "yyyy-MM-dd HH:mm:ss"));

        try {
            Thread.sleep(1000l);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        TradeOrder tradeOrder = tradeOrderRepository.findByMerchantOrderNo(tradeOrderDto.getMerchantOrderNo());

        if (null != tradeOrder && "DRAFT".equals(tradeOrder.getStatus())) {
            tradeOrder.confirm();
            tradeOrderRepository.update(tradeOrder);

            RedPacketAccount transferToAccount = redPacketAccountRepository.findByUserId(tradeOrderDto.getOppositeUserId());

            transferToAccount.transferTo(tradeOrderDto.getAmount());

            redPacketAccountRepository.save(transferToAccount);
        }
    }

    @Transactional
    public void cancelRecord(TransactionContext transactionContext, RedPacketTradeOrderDto tradeOrderDto) {
        System.out.println("red packet cancel record called. time seq:" + DateFormatUtils.format(Calendar.getInstance(), "yyyy-MM-dd HH:mm:ss"));

        try {
            Thread.sleep(1000l);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        TradeOrder tradeOrder = tradeOrderRepository.findByMerchantOrderNo(tradeOrderDto.getMerchantOrderNo());

        if (null != tradeOrder && "DRAFT".equals(tradeOrder.getStatus())) {
            tradeOrder.cancel();
            tradeOrderRepository.update(tradeOrder);

            RedPacketAccount capitalAccount = redPacketAccountRepository.findByUserId(tradeOrderDto.getSelfUserId());

            capitalAccount.cancelTransfer(tradeOrderDto.getAmount());

            redPacketAccountRepository.save(capitalAccount);
        }
    }
}

@@ -1554,151 +1554,8 @@
 o) %7B
-%0A        System.out.println(%22red packet try record called. time seq:%22 + DateFormatUtils.format(Calendar.getInstance(), %22yyyy-MM-dd HH:mm:ss%22));
 %0A%0A  
@@ -1688,32 +1688,176 @@
 (e);%0A        %7D%0A%0A
+        System.out.println(%22red packet try record called. time seq:%22 + DateFormatUtils.format(Calendar.getInstance(), %22yyyy-MM-dd HH:mm:ss%22));%0A%0A
         TradeOrd
@@ -2548,32 +2548,177 @@
 radeOrderDto) %7B%0A
+%0A        try %7B%0A            Thread.sleep(1000l);%0A        %7D catch (InterruptedException e) %7B%0A            throw new RuntimeException(e);%0A        %7D%0A%0A
         System.o
@@ -2853,152 +2853,8 @@
 );%0A%0A
-        try %7B%0A            Thread.sleep(1000l);%0A        %7D catch (InterruptedException e) %7B%0A            throw new RuntimeException(e);%0A        %7D%0A%0A
     
@@ -3526,24 +3526,169 @@
 OrderDto) %7B%0A
+%0A        try %7B%0A            Thread.sleep(1000l);%0A        %7D catch (InterruptedException e) %7B%0A            throw new RuntimeException(e);%0A        %7D%0A%0A
         Syst
@@ -3826,152 +3826,8 @@
 );%0A%0A
-        try %7B%0A            Thread.sleep(1000l);%0A        %7D catch (InterruptedException e) %7B%0A            throw new RuntimeException(e);%0A        %7D%0A%0A
     

update the sample.