package com.td.WaDa.game.complayerlog.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.td.WaDa.common.service.CommonServiceImpl;
import com.td.WaDa.game.complayergoods.pojo.ComPlayerGoods;
import com.td.WaDa.game.complayergoods.repository.ComPlayerGoodsRepository;
import com.td.WaDa.game.complayerlog.pojo.ComPlayerLog;
import com.td.WaDa.game.complayerlog.repository.ComPlayerLogRepository;
import com.td.WaDa.game.complayerlog.vo.ComPlayerLogVo;
import com.td.WaDa.util.DoubleUtil;
import com.td.WaDa.util.UUIDUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ComPlayerLogServiceImpl extends CommonServiceImpl<ComPlayerLogVo, ComPlayerLog, Integer> implements ComPlayerLogService {

    @PersistenceContext
    private EntityManager em;
    @Autowired
    private ComPlayerLogRepository comPlayerLogRepository;
    @Autowired
    private ComPlayerGoodsRepository comPlayerGoodsRepository;

    /**
     * 7天没有操作仓库进入断电损耗期，最多持续8天
     * 1.查询5种操作最后一次操作时间
     * - 购买种子
     * - 种植
     * - 收取果实
     * - 偷取果实
     * - 卖出果实
     * 2.计算并执行本次损耗
     *
     * @param userId 用户id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void powerLoss(String userId) {
        // 查询 [种植] [收取果实] [偷取果实] [卖出果实] 最后操作时间
        ComPlayerLog comPlayerLog = comPlayerLogRepository.findFirstByUserIdOrderByCreateTimeDesc(userId).orElse(null);
        // 查询 [购买种子] 最后操作时间，这里查询这张表是因为购买种子不会往 [com_player_log] 表写数据
        ComPlayerGoods comPlayerGoods = comPlayerGoodsRepository.findFirstByUserIdOrderByCreateTimeDesc(userId).orElse(null);
        // 这是个空号.
        if (comPlayerLog == null && comPlayerGoods == null) {
            return;
        }
        // 计算最后操作时间
        Date lastOperationTime = lastOperationTime(comPlayerLog, comPlayerGoods);
        //System.out.println("最后操作时间：" + dateFormat(lastOperationTime));
        // 计算服务器时间与最后操作时间差
        Date serverDate = new Date();
        long dayDiff = DateUtil.betweenDay(serverDate, lastOperationTime, false);
        //System.out.println("与服务器时间相差：" + dayDiff + "天");
        // 7天未操作 并且 最多持续8天.
        if (dayDiff < 7) {
            //System.out.println("未到7天不损耗");
            return;
        }
        dayDiff = dayDiff > 14 ? 14 : dayDiff;
        dayDiff = Math.abs(14 - 8 - dayDiff);
        //System.out.println("实际断电损耗：" + dayDiff + "天");

        List<ComPlayerGoods> fruitList = comPlayerGoodsRepository.findAllByUserId(userId).stream().filter(a -> a.getGoodsType().equals(1)).collect(Collectors.toList());
        if (fruitList.size() == 0) {
            //System.out.println("仓库无果实不损耗");
            return;
        }
        // 批量更新仓库果实量
        List<ComPlayerGoods> playerGoodsList = new ArrayList<>();
        // 写入明细
        List<ComPlayerLog> playerLogList = new ArrayList<>();

        for (ComPlayerGoods goods : fruitList) {
            // 操作仓库
            int goodsBeforeAmount = goods.getAmount();
            double goodsBeforePart = goods.getAmountPart();
            //
            double amount = (goodsBeforeAmount + goodsBeforePart) * (1 - NumberUtil.div(dayDiff, 100));
            goods.setAmount((int) Math.floor(amount));
            goods.setAmountPart(DoubleUtil.sub(amount, Math.floor(amount)));
            goods.setCreateTime(serverDate);
            playerGoodsList.add(goods);

            // 写入明细
            ComPlayerLog playerLog = new ComPlayerLog();
            playerLog.setId(UUIDUtil.getUUID());
            playerLog.setUserId(userId);
            // 操作目标id，比如进入背包的是收获时候操作：水果
            playerLog.setTId(goods.getGoodsIndex());
            playerLog.setTName(goods.getName());
            playerLog.setTPart(0d);
            playerLog.setTAmount(0);
            playerLog.setTType(7);//断电消耗
            playerLog.setBeforeAmount(goodsBeforeAmount);
            playerLog.setBeforePart(goodsBeforePart);
            // 交易后的数据
            playerLog.setAfterAmount(goods.getAmount());
            playerLog.setAfterPart(goods.getAmountPart());
            // 收获时候，会有一个倍数
            playerLog.setLMultiple(0);
            playerLog.setWithered(2); //断电损耗
            // 损失
            playerLog.setTLoss((goodsBeforeAmount + goodsBeforePart) * NumberUtil.div(dayDiff, 100));
            playerLog.setCreateTime(serverDate);
            playerLog.setUpdateTime(serverDate);
            playerLogList.add(playerLog);
        }
        comPlayerGoodsRepository.saveAll(playerGoodsList);
        comPlayerLogRepository.saveAll(playerLogList);

        //System.out.println("损耗完成");
    }

    /**
     * 获取最后一次操作时间
     *
     * @param comPlayerLog   交易日志
     * @param comPlayerGoods 最后购买种子时间
     * @return {@link Date}
     */
    private Date lastOperationTime(ComPlayerLog comPlayerLog, ComPlayerGoods comPlayerGoods) {
        if (comPlayerLog == null) {
            System.out.println("[comPlayerLog]表无记录. 最后操作时间：" + dateFormat(comPlayerGoods.getCreateTime()));
            return comPlayerGoods.getCreateTime();
        }
        if (comPlayerGoods == null) {
            System.out.println("[comPlayerGoods]表无记录. 最后操作时间：" + dateFormat(comPlayerLog.getCreateTime()));
            return comPlayerLog.getCreateTime();
        }

        System.out.println("[comPlayerLog]表最后操作日期：" + dateFormat(comPlayerLog.getCreateTime()));
        System.out.println("[comPlayerGoods]表最后操作日期：" + dateFormat(comPlayerGoods.getCreateTime()));
        if (comPlayerGoods.getCreateTime().before(comPlayerLog.getCreateTime())) {
            return comPlayerLog.getCreateTime();
        } else {
            return comPlayerGoods.getCreateTime();
        }
    }

    /**
     * 日期格式化
     *
     * @param date 日期
     * @return {@link String}
     */
    private String dateFormat(Date date) {
        return DateUtil.format(date, "yyyy-MM-dd HH:mm:ss");
    }
}
