package cn.com.ctop.kuaishou.modules.report.service.impl;

import cn.com.ctop.common.module.utils.CtopAdConstant;
import cn.com.ctop.kuaishou.modules.report.mapper.KuaiShouAccountReportMapper;
import cn.com.ctop.kuaishou.modules.report.service.IKuaiShouAccountReportService;
import cn.com.ctop.kuaishou.modules.utils.LinkUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.jeecg.common.constant.AccountReportConstants;
import org.jeecg.common.constant.SystemDateConstant;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.JsonResourceUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by JQ.bi on 2020.08.23
 */
@Service
public class KuaiShouAccountReportServiceImpl implements IKuaiShouAccountReportService {

    @Autowired
    KuaiShouAccountReportMapper kuaiShouAccountReportMapper;

    private static final BigDecimal zero = BigDecimal.ZERO;

    @Override
    public Map<String, Object> getSumDataBy(String mediaId, BigDecimal discount, JSONArray accounts, String startDate, String endDate) {
        Map<String, Object> result = new HashMap<>();
        JSONObject after;
        JSONObject before;
        if (startDate.equals(endDate)) {
            after = kuaiShouAccountReportMapper.queryTodaySumReportBy(startDate, accounts);
            if (after == null) {
                return result;
            }
            before = kuaiShouAccountReportMapper.queryTodaySumByHour(DateUtils.getAnotherDay(SystemDateConstant.yyyy_MM_dd, startDate, -1), after.getInteger("maxHour"), accounts);
            if (before == null) {
                before = after;
            }
        } else {
            after = kuaiShouAccountReportMapper.querySumByStartEndDate(endDate, startDate, accounts);
            if (after == null) {
                return result;
            }
            before = after;
        }
        result.put("Sum", getSumLink(mediaId, discount, after, before));
        return result;
    }

    @Override
    public List<JSONObject> getChartDataBy(String mediaId, BigDecimal discount, JSONArray accounts, String startDate, String endDate) throws ParseException {
        List<JSONObject> result = new ArrayList<>();
        String filedAll = JsonResourceUtil.joinAllFiled(AccountReportConstants.dicMapKs);
        if (startDate.equals(endDate)) {
            List<JSONObject> after = kuaiShouAccountReportMapper.queryTodayDetailReportBy(filedAll, startDate, accounts);
            List<JSONObject> before = kuaiShouAccountReportMapper.queryTodayDetailReportBy(filedAll, DateUtils.getAnotherDay(SystemDateConstant.yyyy_MM_dd, startDate, -1), accounts);
            if (after.size() == 0) {
                return result;
            }
            if (before.size() == 0) {
                before = nullDataHandle();
            }
            List<JSONObject> afterDis = this.countDiscountCost(mediaId, discount, after);
            List<JSONObject> beforeDis = this.countDiscountCost(mediaId, discount, before);
            result = LinkUtils.getCompareDate(beforeDis, afterDis, "statHour");
        } else {
            List<JSONObject> after;
            //判断是不是日期间隔大于半年
            if (DateUtils.isMoreSixMonth(startDate, endDate)) {
                after = kuaiShouAccountReportMapper.queryDetailGroupMonthByDate(endDate, startDate, accounts);
            } else {
                after = kuaiShouAccountReportMapper.queryDetailByStartEndDate(endDate, startDate, accounts);
            }
            if (after == null) {
                return result;
            }
            result = this.countDiscountCost(mediaId, discount, after);
        }
        return result;
    }

    @Override
    public List<JSONObject> getListDataBy(String mediaId, BigDecimal discount, JSONArray accounts, String startDate, String endDate, int hour, String target, String order) {
        List<JSONObject> result;
        String filedAll = JsonResourceUtil.joinAllFiled(AccountReportConstants.dicMapKs);
        if (startDate.equals(endDate)) {
            if (startDate.equals(DateUtils.date2Str())) {
                result = kuaiShouAccountReportMapper.queryTodaySumByHourGroupAccount(filedAll, startDate, hour, accounts, target, order);
                JSONObject afterSum = kuaiShouAccountReportMapper.querySumByHour(filedAll, startDate, hour, accounts);
                JSONObject beforeSum = kuaiShouAccountReportMapper.querySumByHour(filedAll, DateUtils.getAnotherDay(SystemDateConstant.yyyy_MM_dd, startDate, -1), hour, accounts);
                result.add(afterSum);
                result.add(beforeSum);
                result.add(countTotal(afterSum, beforeSum));
            } else {
                result = kuaiShouAccountReportMapper.querySumByDateGroupAccount(filedAll, endDate, startDate, accounts, target, order);
                JSONObject afterSum = kuaiShouAccountReportMapper.queryAllSumByStartEndDate(filedAll, endDate, startDate, accounts);
                JSONObject beforeSum = kuaiShouAccountReportMapper.queryAllSumByStartEndDate(filedAll, DateUtils.getAnotherDay(SystemDateConstant.yyyy_MM_dd, endDate, -1), DateUtils.getAnotherDay(SystemDateConstant.yyyy_MM_dd, startDate, -1), accounts);
                result.add(afterSum);
                result.add(beforeSum);
                result.add(countTotal(afterSum, beforeSum));
            }
        } else {
            if (accounts.size() > 1) {
                result = kuaiShouAccountReportMapper.querySumByDateGroupAccount(filedAll, endDate, startDate, accounts, target, order);
            } else {
                result = kuaiShouAccountReportMapper.querySumByDateGroupAccountAndDate(filedAll, endDate, startDate, accounts, target, order);
            }
            result.add(kuaiShouAccountReportMapper.queryAllSumByStartEndDate(filedAll, endDate, startDate, accounts));
        }
        return result;
    }

    @Override
    public List<JSONObject> getExcelDataBy(String filed, String mediaId, JSONArray accounts, String startDate, String endDate, int hour, String target, String order) {
        List<JSONObject> result;
        if (startDate.equals(endDate)) {
            if (startDate.equals(DateUtils.date2Str())) {
                result = kuaiShouAccountReportMapper.queryTodaySumByHourGroupAccount(filed, startDate, hour, accounts, target, order);
            } else {
                result = kuaiShouAccountReportMapper.querySumByDateGroupAccount(filed, endDate, startDate, accounts, target, order);
            }
        } else {
            result = kuaiShouAccountReportMapper.querySumByDateGroupAccount(filed, endDate, startDate, accounts, target, order);
        }
        return result;
    }

    //计算汇总数据环比
    private Map<String, Object> getSumLink(String mediaId, BigDecimal discount, JSONObject after, JSONObject before) {

        Map<String, Object> result = new HashMap<>();

        JSONObject costLink = new JSONObject();
        JSONObject discountCostLink = new JSONObject();
        JSONObject photoClickLink = new JSONObject();
        JSONObject photoShowLink = new JSONObject();
        JSONObject aClickLink = new JSONObject();

        costLink.put("cost", after.getBigDecimal("cost"));
        costLink.put("CostSumLink", LinkUtils.countLink(after.getBigDecimal("cost"), before.getBigDecimal("cost")));
        if (mediaId.equals(CtopAdConstant.PLATFORM_TYPE_KUAISHOU)) {
            discountCostLink.put("discountCost", after.getBigDecimal("cost").divide(discount, 4, RoundingMode.HALF_UP));
            discountCostLink.put("discountCostLink", LinkUtils.countLink(after.getBigDecimal("cost").divide(discount, 4, RoundingMode.HALF_UP), before.getBigDecimal("cost").divide(discount, 4, RoundingMode.HALF_UP)));
        } else {
            discountCostLink.put("discountCost", after.getBigDecimal("cost").multiply(discount));
            discountCostLink.put("discountCostLink", LinkUtils.countLink(after.getBigDecimal("cost").multiply(discount), before.getBigDecimal("cost").multiply(discount)));
        }
        photoClickLink.put("photoClick", after.getBigDecimal("photoClick"));
        photoClickLink.put("photoClickLink", LinkUtils.countLink(after.getBigDecimal("photoClick"), before.getBigDecimal("photoClick")));
        photoShowLink.put("photoShow", after.getBigDecimal("photoShow"));
        photoShowLink.put("photoShowLink", LinkUtils.countLink(after.getBigDecimal("photoShow"), before.getBigDecimal("photoShow")));
        aClickLink.put("aClick", after.getBigDecimal("aClick"));
        aClickLink.put("aClickLink", LinkUtils.countLink(after.getBigDecimal("aClick"), before.getBigDecimal("aClick")));
        result.put("costLink", costLink);
        result.put("discountCostLink", discountCostLink);
        result.put("photoClickLink", photoClickLink);
        result.put("photoShowLink", photoShowLink);
        result.put("aClickLink", aClickLink);
        return result;
    }

    //计算折后消耗
    private List<JSONObject> countDiscountCost(String mediaId, BigDecimal discount, List<JSONObject> data) {
        if (data.isEmpty()) {
            return data;
        }
        if (mediaId.equals(CtopAdConstant.PLATFORM_TYPE_KUAISHOU)) {
            data.forEach(it -> {
                it.put("discountCost", it.getBigDecimal("cost").divide(discount, 4, RoundingMode.HALF_UP));
            });
        } else {
            data.forEach(it -> {
                it.put("discountCost", it.getBigDecimal("cost").multiply(discount));
            });
        }
        return data;
    }

    //计算总计环比
    private JSONObject countTotal(JSONObject after, JSONObject before) {
        JSONObject jsonObject = new JSONObject();
        after.forEach((k, v) -> {
            //去除没法计算的字段
            if ("accountId".equals(k) || "authName".equals(k) || v.toString().contains("%") || before.getString(k).contains("%")) {
                jsonObject.put(k, "-");
            } else {
                jsonObject.put(k, (LinkUtils.countLink(after.getBigDecimal(k) == null ? zero : after.getBigDecimal(k), before.getBigDecimal(k) == null ? zero : before.getBigDecimal(k))).multiply(BigDecimal.valueOf(100)).setScale(2, RoundingMode.HALF_UP)+"%");
            }
        });
        return jsonObject;
    }

    private List<JSONObject> nullDataHandle() {
        List<JSONObject> objectList = new ArrayList<>();
        JSONObject jsonObject;
        for (int i = 0; i < 24; i++) {
            jsonObject = new JSONObject();
            jsonObject.put("cost", 0);
            jsonObject.put("photoShow", 0);
            jsonObject.put("photoClick", 0);
            jsonObject.put("aClick", 0);
            jsonObject.put("statHour", i);
            objectList.add(jsonObject);
        }
        return objectList;
    }
}
