package com.td.boss.game.complayerland.service;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.td.boss.common.service.CommonServiceImpl;
import com.td.boss.game.complayerland.pojo.ComPlayerDisaster;
import com.td.boss.game.complayerland.repository.ComPlayerDisasterRepository;
import com.td.boss.game.complayerland.scheduled.ComPlayerDisasterDateUtil;
import com.td.boss.game.complayerland.vo.ComPlayerDisasterVo;
import com.td.boss.util.DappUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class ComPlayerDisasterServiceImpl extends CommonServiceImpl<ComPlayerDisasterVo, ComPlayerDisaster, String> implements ComPlayerDisasterService {

    @Autowired
    private ComPlayerDisasterRepository repository;

    /**
     * 同步“链端接口”上周“收入支出数据”到数据库
     * 本周开始时间为周日到周六，期间获取的不会变化，这周获取的是上周的数据
     *
     * @param userId
     * @return
     */
    @Override
    public ComPlayerDisaster getAndSave(String userId) {
        Date begin = ComPlayerDisasterDateUtil.getBegin();
        Date end = ComPlayerDisasterDateUtil.getEnd();
        log.info("灾难模式周同步数据[{}],begin:{},end:{},now:{}", userId, begin, end, DateUtil.format(new Date(), "yyyy-MM-dd hh:mm:ss"));
        if (exists(userId, begin, end)) {
            log.info("灾难模式周同步数据[{}]已经同步过了", userId);
            return null;
        }
        ComPlayerDisaster data = getData(userId, begin, end);
        return repository.saveAndFlush(data);
    }

    /**
     * 所以 支出对应pay_amount，收入对应swap_amount
     * @param userId
     * @param beginTime
     * @param endTime
     * @return
     */
    private ComPlayerDisaster getData(String userId, Date beginTime, Date endTime) {
        Map response = DappUtil.getCntPayAndSwapAmount(userId);
        log.info("接口返回支付兑换结果：{}", JSONUtil.toJsonStr(response));
        Map<String, Object> cntPayAndSwapAmount = (Map) response.get("data");

        // 总支付cnt
        Double pay_amount = Convert.toDouble(cntPayAndSwapAmount.get("pay_amount"), 0d);
        // 总兑换cnt
        Double swap_amount = Convert.toDouble(cntPayAndSwapAmount.get("swap_amount"), 0d);
        ComPlayerDisaster comPlayerDisaster = new ComPlayerDisaster();
        comPlayerDisaster.setCreateTime(new Date());
        comPlayerDisaster.setUserId(userId);
        comPlayerDisaster.setIncome(swap_amount);
        comPlayerDisaster.setPayment(pay_amount);
        comPlayerDisaster.setLog(JSONUtil.toJsonStr(response));
        comPlayerDisaster.setBeginTime(beginTime);
        comPlayerDisaster.setEndTime(endTime);
        return comPlayerDisaster;
    }

    private boolean exists(String userId, Date begin, Date end) {
        Specification specification = new Specification<ComPlayerDisaster>() {
            @Override
            public Predicate toPredicate(Root<ComPlayerDisaster> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                predicates.add(criteriaBuilder.between(root.get("createTime"), begin, end));
                predicates.add(criteriaBuilder.equal(root.get("userId"), userId));
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        return repository.count(specification) > 0;
    }
}
