package com.iamberry.wechat.service.coupon;

import com.iamberry.wechat.core.entity.coupon.CouponItem;
import com.iamberry.wechat.core.entity.coupon.CouponItemDto;
import com.iamberry.wechat.core.entity.order.Order;
import com.iamberry.wechat.core.entity.welfare.UserAmount;
import com.iamberry.wechat.core.entity.welfare.UserAmountLogs;
import com.iamberry.wechat.core.entity.welfare.UserAtLogs;
import com.iamberry.wechat.core.entity.welfare.WelfareLogs;
import com.iamberry.wechat.face.coupon.WelfareService;
import com.iamberry.wechat.service.mapper.*;
import com.iamberry.wechat.tools.DateTimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @author root
 */
@Service
public class WelfareServiceImpl implements WelfareService {

    @Autowired
    private WelfareLogsMapper welfareLogsMapper;

    @Autowired
    private CouponItemMapper couponItemMapper;

    @Autowired
    private UserAmountLogsMapper amountLogsMapper;

    @Autowired
    private UserAmountMapper amountMapper;

    @Autowired
    private UserAtLogsMapper atLogsMapper;

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Override
    public WelfareLogs get(String openid) {
        return welfareLogsMapper.get(openid);
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, SQLException.class}, isolation = Isolation.REPEATABLE_READ)
    public int draw(String openId) {
        if (welfareLogsMapper.get(openId) != null) {
            return 0;
        }
        int conpon200Id = 30000;
        int conpon200Num = 5;
        CouponItem item = new CouponItem();
        item.setCouponId(conpon200Id);
        item.setCouponItemUseropenid(openId);
        item.setCouponUseEndDate(DateTimeUtil.addMonth(new Date(), 3));
        item.setCouponReceiveDate(new Date());
        item.setCouponIsGive(1);
        item.setCouponUseStatus(1);
        for (int i = 0; i < conpon200Num; i++) {
            item.setCouponItemId(UUID.randomUUID().toString().replace("-", ""));
            couponItemMapper.insertCouponItem(item);
        }

        int conpon100Id = 30001;
        int conpon100Num = 5;
        CouponItem item100 = new CouponItem();
        item100.setCouponId(conpon100Id);
        item100.setCouponItemUseropenid(openId);
        item100.setCouponUseEndDate(DateTimeUtil.addMonth(new Date(), 3));
        item100.setCouponReceiveDate(new Date());
        item100.setCouponIsGive(1);
        item100.setCouponUseStatus(1);
        for (int i = 0; i < conpon100Num; i++) {
            item100.setCouponItemId(UUID.randomUUID().toString().replace("-", ""));
            couponItemMapper.insertCouponItem(item100);
        }

        int conpon188Id = 30002;
        int conpon188Num = 1;
        CouponItem item188 = new CouponItem();
        item188.setCouponId(conpon188Id);
        item188.setCouponItemUseropenid(openId);
        item188.setCouponUseEndDate(DateTimeUtil.addMonth(new Date(), 3));
        item188.setCouponReceiveDate(new Date());
        item188.setCouponIsGive(1);
        item188.setCouponUseStatus(1);
        for (int i = 0; i < conpon188Num; i++) {
            item188.setCouponItemId(UUID.randomUUID().toString().replace("-", ""));
            couponItemMapper.insertCouponItem(item188);
        }

        WelfareLogs welfareLogs = new WelfareLogs();
        welfareLogs.setUserOpenid(openId);
        return welfareLogsMapper.add(welfareLogs);
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, SQLException.class}, isolation = Isolation.REPEATABLE_READ)
    public int drawShareCoupon(String couponId, String openid) {
        CouponItemDto couponItem = couponItemMapper.getCouponItemById(couponId);
        if (couponItem == null) {
            return 0;
        }
        if (openid.equals(couponItem.getUseropenid())) {
            return 0;
        }
        if (System.currentTimeMillis() >= couponItem.getCouponUseEndDate().getTime()) {
            return 0;
        }
        CouponItem coupon = new CouponItem();
        coupon.setCouponIsGive(2);
        coupon.setCouponItemId(couponId);
        couponItemMapper.updateCouponItemById(coupon);
        // 重新为当前用户生成
        CouponItem item188 = new CouponItem();
        item188.setCouponId(couponItem.getCouponId());
        item188.setCouponItemUseropenid(openid);
        item188.setCouponUseEndDate(couponItem.getCouponUseEndDate());
        item188.setCouponReceiveDate(new Date());
        item188.setCouponIsGive(1);
        item188.setCouponUseStatus(1);
        item188.setGiveOpenid(couponItem.getUseropenid());
        item188.setCouponItemId(UUID.randomUUID().toString().replace("-", ""));
        return couponItemMapper.insertCouponItem(item188);
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, SQLException.class}, isolation = Isolation.READ_COMMITTED)
    public int useCoupon(String openid, String orderId, String couponId) {
        CouponItem couponItemDto = couponItemMapper.get(couponId);
        assert couponItemDto != null;
        if (couponItemDto.getGiveOpenid() != null) {
            // 此优惠券为他人赠送，需要生成返利信息
            UserAmount userAmount = amountMapper.get(couponItemDto.getGiveOpenid());
            if (userAmount == null) {
                userAmount = new UserAmount();
                userAmount.setUserOpenid(couponItemDto.getGiveOpenid());
                userAmount.setAmonutAwait(0);
                userAmount.setAmonutLock(0);
                userAmount.setAmonutTotal(0);
                userAmount.setAmonutUsable(0);
                try {
                    amountMapper.add(userAmount);
                } catch (DuplicateKeyException e) {
                    userAmount = amountMapper.get(couponItemDto.getGiveOpenid());
                }
            }
            userAmount.setUserOpenid(null);
            userAmount.setAmonutLock(null);
            userAmount.setAmonutTotal(null);
            userAmount.setAmonutUsable(null);
            // 待入账金额
            int amount = couponItemMapper.getCouponItemById(couponId).getCouponReduce();
            userAmount.setAmonutAwait(amount);
            amountMapper.edit(userAmount);
            // 返利记录
            UserAmountLogs logs = new UserAmountLogs();
            logs.setLogsAmount(amount);
            logs.setLogsDate(DateTimeUtil.addDay(new Date(), 16));
            logs.setLogsState(1);
            logs.setLogsType(2);
            logs.setOrderId(orderId);
            logs.setUserOpenid(couponItemDto.getGiveOpenid());
            amountLogsMapper.add(logs);
        }
        CouponItem couponItem=new CouponItem();
        couponItem.setCouponItemId(couponId);
        couponItem.setCouponUseStatus(2);
        couponItem.setCouponUseDate(new Date());
        return couponItemMapper.updateCouponItemById(couponItem);
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, SQLException.class}, isolation = Isolation.READ_COMMITTED)
    public int enter(UserAmountLogs logs) {
        // 入账提现金额、减少待入账金额
        UserAmount userAmount = amountMapper.get(logs.getUserOpenid());
        assert userAmount != null;

        userAmount.setAmonutLock(null);
        userAmount.setUserOpenid(null);

        userAmount.setAmonutUsable(logs.getLogsAmount());
        userAmount.setAmonutAwait(-logs.getLogsAmount());
        userAmount.setAmonutTotal(logs.getLogsAmount());
        amountMapper.edit(userAmount);
        // 入账记录编辑
        logs.setUserOpenid(null);
        logs.setOrderId(null);
        logs.setLogsAmount(null);

        logs.setLogsRemark("SUCCESS");
        logs.setLogsType(2);
        logs.setLogsDate(new Date());
        return amountLogsMapper.edit(logs);
    }

    @Override
    public UserAmount getAmount(String openid) {
        UserAmount userAmount = amountMapper.get(openid);
        if (userAmount == null) {
            userAmount = new UserAmount();
            userAmount.setUserOpenid(openid);
            userAmount.setAmonutAwait(0);
            userAmount.setAmonutLock(0);
            userAmount.setAmonutTotal(0);
            userAmount.setAmonutUsable(0);
            try {
                amountMapper.add(userAmount);
            } catch (DuplicateKeyException e) {
                userAmount = amountMapper.get(openid);
            }
        }
        return userAmount;
    }

    @Override
    public List<UserAmountLogs> listAmount(UserAmountLogs userAmountLogs) {
        List<UserAmountLogs> list = amountLogsMapper.list(userAmountLogs);
        if (list == null || list.isEmpty()) {
            return list;
        }
        for (UserAmountLogs logs : list) {
            logs.setOrder(orderMapper.get(logs.getOrderId()));
            logs.setMember(memberMapper.getMemberByUserOpenId(logs.getOrder().getSalesOpenid()));
        }
        return list;
    }

    @Override
    public List<UserAtLogs> listAt(UserAtLogs data) {
        return atLogsMapper.list(data);
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class, SQLException.class}, isolation = Isolation.READ_COMMITTED)
    public int addAt(UserAtLogs userAtLogs) {
        // 查询用户余额
        UserAmount userAmount = amountMapper.get(userAtLogs.getUserOpenid());
        if (userAmount.getAmonutUsable() < userAtLogs.getAtAmonut()) {
            return 0;
        }
        if (userAtLogs.getAtAmonut() < 10000) {
            return 0;
        }
        UserAmount edit = new UserAmount();
        edit.setAmonutLock(userAtLogs.getAtAmonut());
        edit.setAmonutUsable(-userAtLogs.getAtAmonut());
        edit.setAmountId(userAmount.getAmountId());
        amountMapper.edit(edit);
        // 添加提现记录
        return atLogsMapper.add(userAtLogs);
    }
}
