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

import cn.com.ctop.common.module.entity.UserAllocation;
import cn.com.ctop.common.module.mapper.SysRoleExtMapper;
import cn.com.ctop.common.module.mapper.UserAllocationMapper;
import cn.com.ctop.common.module.utils.Check;
import cn.com.ctop.kuaishou.modules.report.mapper.MaterialReportMapper;
import cn.com.ctop.kuaishou.modules.report.service.IMaterialReportService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * @author yumeng
 * 2019年11月12日10:04:00
 */
@Slf4j
@Service
public class MaterialReportServiceImpl implements IMaterialReportService {
    @Autowired
    private MaterialReportMapper materialReportMapper;

    @Autowired
    private UserAllocationMapper userAllocationMapper;
    @Autowired
    private SysRoleExtMapper sysRoleExtMapper;


    /**
     * 获取快手大盘数据报表
     *
     * @param json
     * @return
     */

    @Override
    public List<JSONObject> getKuaiShouMaterialMarket(JSONObject json) {
        long startTime = System.currentTimeMillis();
        List<JSONObject> marketJsonList = new ArrayList<>();
        try {
            if (Check.isNull(json)) {
                return marketJsonList;
            }
            String userId = json.getString("userId");
            if (Check.isNull(userId)) {
                return marketJsonList;
            }
            String roleCode = sysRoleExtMapper.getRoleCodeByUserId(userId);
            String nowDate = DateUtils.getNowDate("yyyy-MM-dd");
            String anotherDay = DateUtils.getAnotherDay("yyyy-MM-dd", nowDate, -1);
            Integer type = json.getInteger("type");
            Map<String, Object> paramsMap = new HashMap<>();
            if ("operator".equals(roleCode)) {
                paramsMap.put("userId", userId);
            }
            if (type == 1) {
                // 今天分时数据
                Integer maxHour = materialReportMapper.selectMaxHourByDate(nowDate);
                if (Check.isNull(maxHour) || maxHour == 0) {
                    return marketJsonList;
                }
                Integer statHour = maxHour - 1;
                paramsMap.put("startDate", nowDate);
                paramsMap.put("statHour", statHour);
                marketJsonList = materialReportMapper.selectByMap(paramsMap);

            } else if (type == 2) {
                paramsMap.put("startDate", anotherDay);
                marketJsonList = materialReportMapper.selectByMap(paramsMap);

            } else if (type == 3) {
                String endDate = DateUtils.getAnotherDay("yyyy-MM-dd", anotherDay, -6);
                paramsMap.put("startDate", anotherDay);
                paramsMap.put("endDate", endDate);
                marketJsonList = materialReportMapper.selectDailyByMap(paramsMap);
            } else if (type == 4) {
                String endDate = DateUtils.getAnotherDay("yyyy-MM-dd", anotherDay, -14);
                paramsMap.put("startDate", anotherDay);
                paramsMap.put("endDate", endDate);
                marketJsonList = materialReportMapper.selectDailyByMap(paramsMap);
            } else if (type == 5) {
                String endDate = DateUtils.getMonthBefore("yyyy-MM-dd", anotherDay, -1);
                paramsMap.put("startDate", anotherDay);
                paramsMap.put("endDate", endDate);
                marketJsonList = materialReportMapper.selectDailyByMap(paramsMap);
            } else if (type == 6) {
                String endDate = DateUtils.getMonthBefore("yyyy-MM-dd", anotherDay, -3);
                paramsMap.put("startDate", anotherDay);
                paramsMap.put("endDate", endDate);
                marketJsonList = materialReportMapper.selectDailyByMap(paramsMap);

            } else if (type == 7) {
                String endDate = DateUtils.getMonthBefore("yyyy-MM-dd", anotherDay, -6);
                paramsMap.put("startDate", anotherDay);
                paramsMap.put("endDate", endDate);
                marketJsonList = materialReportMapper.selectDailyByMap(paramsMap);

            } else if (type == 8) {
                marketJsonList = materialReportMapper.selectDailyByMap(paramsMap);

            } else if (type == 9) {
                String startDate = json.getString("startDate");
                String endDate = json.getString("endDate");
                paramsMap.put("startDate", startDate);
                paramsMap.put("endDate", endDate);
                marketJsonList = materialReportMapper.selectDailyByMap(paramsMap);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        log.info("素材数据请求所用时长------------->: {} ms", System.currentTimeMillis() - startTime);
        return marketJsonList;
    }

    /**
     * 获取 环比
     *
     * @param json
     * @return
     */
    @Override
    public JSONObject getKuaiShouChainRatio(JSONObject json) {
        JSONObject returnJson = new JSONObject();
        long startTime = System.currentTimeMillis();
        try {
            if (Check.isNull(json)) {
                return null;
            }
            String signature = json.getString("signature");
            if (Check.isNull(signature)) {
                return null;
            }
            Integer type = json.getInteger("type");
            String accountId = json.getString("accountId");
            String nowDate = DateUtils.getNowDate("yyyy-MM-dd");
            String anotherDay = DateUtils.getAnotherDay("yyyy-MM-dd", nowDate, -1);
            Map<String, Object> paramsMap = new HashMap<>();
            paramsMap.put("signature", signature);
            if (!Check.isNull(accountId)) {
                paramsMap.put("accountId", accountId);
            }
            String beContrastDate = "";
            String contrastStartDate = "";
            String beContrastStartDate = "";
            String beContrastEndDate = "";
            JSONObject contrastJson = new JSONObject();
            JSONObject beContrastJson = new JSONObject();
            if (type == 1) {
                Integer maxHour = materialReportMapper.selectMaxHourByDate(nowDate);
                Integer statHour = maxHour - 1;
                paramsMap.put("statDate", nowDate);
                paramsMap.put("statHour", statHour);

                contrastJson = materialReportMapper.selectChainRatioByMap(paramsMap);
                if (!Check.isNull(contrastJson)) {
                    paramsMap.put("statDate", anotherDay);
                    beContrastJson = materialReportMapper.selectChainRatioByMap(paramsMap);
                }

            } else if (type == 2) {
                // 昨天数据
                paramsMap.put("statDate", anotherDay);
                contrastJson = materialReportMapper.selectDailyChainRatioByMap(paramsMap);
                if (!Check.isNull(contrastJson)) {
                    beContrastDate = DateUtils.getAnotherDay("yyyy-MM-dd", anotherDay, -1);
                    paramsMap.put("statDate", beContrastDate);
                    beContrastJson = materialReportMapper.selectDailyChainRatioByMap(paramsMap);
                }

            } else if (type == 3) {
                // 近一周数据
                contrastStartDate = DateUtils.getAnotherDay("yyyy-MM-dd", anotherDay, -6);
                paramsMap.put("startDate", contrastStartDate);
                paramsMap.put("endDate", anotherDay);
                contrastJson = materialReportMapper.selectDailyChainRatioByMap(paramsMap);
                if (!Check.isNull(contrastJson)) {
                    beContrastEndDate = DateUtils.getAnotherDay("yyyy-MM-dd", contrastStartDate, -1);
                    beContrastStartDate = DateUtils.getAnotherDay("yyyy-MM-dd", beContrastEndDate, -6);
                    paramsMap.put("endDate", beContrastEndDate);
                    paramsMap.put("startDate", beContrastStartDate);
                    beContrastJson = materialReportMapper.selectDailyChainRatioByMap(paramsMap);
                }
            } else if (type == 4) {
                contrastStartDate = DateUtils.getAnotherDay("yyyy-MM-dd", anotherDay, -14);
                paramsMap.put("startDate", contrastStartDate);
                paramsMap.put("endDate", anotherDay);
                contrastJson = materialReportMapper.selectDailyChainRatioByMap(paramsMap);
                if (!Check.isNull(contrastJson)) {
                    beContrastEndDate = DateUtils.getAnotherDay("yyyy-MM-dd", contrastStartDate, -1);
                    beContrastStartDate = DateUtils.getAnotherDay("yyyy-MM-dd", beContrastEndDate, -14);
                    paramsMap.put("endDate", beContrastEndDate);
                    paramsMap.put("startDate", beContrastStartDate);
                    beContrastJson = materialReportMapper.selectDailyChainRatioByMap(paramsMap);
                }
            } else if (type == 5) {
                contrastStartDate = DateUtils.getMonthBefore("yyyy-MM-dd", anotherDay, -1);
                paramsMap.put("startDate", contrastStartDate);
                paramsMap.put("endDate", anotherDay);
                contrastJson = materialReportMapper.selectDailyChainRatioByMap(paramsMap);
                if (!Check.isNull(contrastJson)) {
                    beContrastEndDate = DateUtils.getAnotherDay("yyyy-MM-dd", contrastStartDate, -1);
                    beContrastStartDate = DateUtils.getMonthBefore("yyyy-MM-dd", beContrastEndDate, -1);
                    paramsMap.put("endDate", beContrastEndDate);
                    paramsMap.put("startDate", beContrastStartDate);
                    beContrastJson = materialReportMapper.selectDailyChainRatioByMap(paramsMap);
                }
            } else if (type == 6) {
                contrastStartDate = DateUtils.getMonthBefore("yyyy-MM-dd", anotherDay, -3);
                paramsMap.put("startDate", contrastStartDate);
                paramsMap.put("endDate", anotherDay);
                contrastJson = materialReportMapper.selectDailyChainRatioByMap(paramsMap);
                if (!Check.isNull(contrastJson)) {
                    beContrastEndDate = DateUtils.getAnotherDay("yyyy-MM-dd", contrastStartDate, -1);
                    beContrastStartDate = DateUtils.getMonthBefore("yyyy-MM-dd", beContrastEndDate, -3);
                    paramsMap.put("endDate", beContrastEndDate);
                    paramsMap.put("startDate", beContrastStartDate);
                    beContrastJson = materialReportMapper.selectDailyChainRatioByMap(paramsMap);
                }
            }

            if (!Check.isNull(contrastJson) && !Check.isNull(beContrastJson)) {
                if (type == 1) {
                    contrastJson.put("statDate", nowDate);
                    beContrastJson.put("statDate", anotherDay);
                } else if (type == 2) {
                    contrastJson.put("statDate", anotherDay);
                    beContrastJson.put("statDate", beContrastDate);
                } else {
                    contrastJson.put("startDate", contrastStartDate);
                    contrastJson.put("endDate", anotherDay);
                    beContrastJson.put("startDate", beContrastStartDate);
                    beContrastJson.put("endDate", beContrastEndDate);
                }
                returnJson.put("contrast", contrastJson);
                returnJson.put("beContrast", beContrastJson);
                JSONObject chainRatioJson = new JSONObject();
                BigDecimal contrastCost = contrastJson.getBigDecimal("cost");
                BigDecimal beContrastCost = beContrastJson.getBigDecimal("cost");
                if (!Check.isNull(contrastCost) && !Check.isNull(beContrastCost)) {
                    if (beContrastCost.compareTo(new BigDecimal(0)) != 0) {
                        BigDecimal costProportion = (contrastCost.subtract(beContrastCost)).divide(beContrastCost, 2, RoundingMode.HALF_UP);
                        chainRatioJson.put("costProportion", costProportion);
                    } else {
                        chainRatioJson.put("costProportion", 0);
                    }
                } else {
                    chainRatioJson.put("costProportion", 0);
                }
                Long contrastPhotoShow = contrastJson.getLong("photoShow");
                Long beContrastPhotoShow = beContrastJson.getLong("photoShow");
                if (!Check.isNull(contrastPhotoShow) && !Check.isNull(beContrastPhotoShow)) {
                    if (beContrastPhotoShow != 0L) {
                        double showProportion = (contrastPhotoShow.doubleValue() - beContrastPhotoShow.doubleValue()) / beContrastPhotoShow.doubleValue();
                        chainRatioJson.put("showProportion", showProportion);
                    } else {
                        chainRatioJson.put("showProportion", 0);
                    }
                } else {
                    chainRatioJson.put("showProportion", 0);
                }
                Long contrastPhotoClick = contrastJson.getLong("photoClick");
                Long beContrastPhotoClick = beContrastJson.getLong("photoClick");
                if (!Check.isNull(contrastPhotoClick) && !Check.isNull(beContrastPhotoClick)) {
                    if (beContrastPhotoClick != 0L) {
                        double photoClickProportion = (contrastPhotoClick.doubleValue() - beContrastPhotoClick.doubleValue()) / beContrastPhotoClick.doubleValue();
                        chainRatioJson.put("photoClickProportion", photoClickProportion);
                    } else {
                        chainRatioJson.put("photoClickProportion", 0);
                    }
                } else {
                    chainRatioJson.put("photoClickProportion", 0);
                }

                Long contrastAClick = contrastJson.getLong("aclick");
                Long beContrastAClick = beContrastJson.getLong("aclick");
                if (!Check.isNull(contrastAClick) && !Check.isNull(beContrastAClick)) {
                    if (beContrastAClick != 0L) {
                        double aClickProportion = (contrastAClick.doubleValue() - beContrastAClick.doubleValue()) / beContrastAClick.doubleValue();
                        chainRatioJson.put("aClickProportion", aClickProportion);
                    } else {
                        chainRatioJson.put("aClickProportion", 0);
                    }
                } else {
                    chainRatioJson.put("aClickProportion", 0);
                }

                Long contrastBClick = contrastJson.getLong("bclick");
                Long beContrastBClick = beContrastJson.getLong("bclick");
                if (!Check.isNull(contrastBClick) && !Check.isNull(beContrastBClick)) {
                    if (beContrastBClick != 0L) {
                        double bClickProportion = (contrastBClick.doubleValue() - beContrastBClick.doubleValue()) / beContrastBClick.doubleValue();
                        chainRatioJson.put("bClickProportion", bClickProportion);
                    } else {
                        chainRatioJson.put("bClickProportion", 0);
                    }
                } else {
                    chainRatioJson.put("bClickProportion", 0);
                }


                BigDecimal contrastPhotoClickCost = contrastJson.getBigDecimal("photoClickCost");
                BigDecimal beContrastPhotoClickCost = beContrastJson.getBigDecimal("photoClickCost");
                if (!Check.isNull(contrastPhotoClickCost) && !Check.isNull(beContrastPhotoClickCost)) {
                    if (beContrastPhotoClickCost.compareTo(new BigDecimal(0)) != 0) {
                        BigDecimal photoClickCostProportion = (contrastPhotoClickCost.subtract(beContrastPhotoClickCost)).divide(beContrastPhotoClickCost, 2, RoundingMode.HALF_UP);
                        chainRatioJson.put("photoClickCostProportion", photoClickCostProportion);
                    } else {
                        chainRatioJson.put("photoClickCostProportion", 0);
                    }
                } else {
                    chainRatioJson.put("photoClickCostProportion", 0);
                }
                BigDecimal contrastPhotoClickRatio = contrastJson.getBigDecimal("photoClickRatio");
                BigDecimal beContrastPhotoClickRatio = beContrastJson.getBigDecimal("photoClickRatio");
                if (!Check.isNull(contrastPhotoClickRatio) && !Check.isNull(beContrastPhotoClickRatio)) {
                    if (beContrastPhotoClickRatio.compareTo(new BigDecimal(0)) != 0) {
                        BigDecimal photoClickRatioProportion = (contrastPhotoClickRatio.subtract(beContrastPhotoClickRatio)).divide(beContrastPhotoClickRatio, 2, RoundingMode.HALF_UP);
                        chainRatioJson.put("photoClickRatioProportion", photoClickRatioProportion);
                    } else {
                        chainRatioJson.put("photoClickRatioProportion", 0);
                    }
                } else {
                    chainRatioJson.put("photoClickRatioProportion", 0);
                }
                BigDecimal contrastActionCost = contrastJson.getBigDecimal("actionCost");
                BigDecimal beContrastActionCost = beContrastJson.getBigDecimal("actionCost");
                if (!Check.isNull(contrastActionCost) && !Check.isNull(beContrastActionCost)) {
                    if (beContrastActionCost.compareTo(new BigDecimal(0)) != 0) {
                        BigDecimal actionCostProportion = (contrastActionCost.subtract(beContrastActionCost)).divide(beContrastActionCost, 2, RoundingMode.HALF_UP);
                        chainRatioJson.put("actionCostProportion", actionCostProportion);
                    } else {
                        chainRatioJson.put("actionCostProportion", 0);
                    }
                } else {
                    chainRatioJson.put("actionCostProportion", 0);
                }
                // 封面点击率
                BigDecimal contrastActionRatio = contrastJson.getBigDecimal("actionRatio");
                BigDecimal beContrastActionRatio = beContrastJson.getBigDecimal("actionRatio");
                if (!Check.isNull(contrastActionRatio) && !Check.isNull(beContrastActionRatio)) {
                    if (beContrastActionRatio.compareTo(new BigDecimal(0)) != 0) {
                        BigDecimal actionRatioProportion = (contrastActionRatio.subtract(beContrastActionRatio)).divide(beContrastActionRatio, 2, RoundingMode.HALF_UP);
                        chainRatioJson.put("actionRatioProportion", actionRatioProportion);
                    } else {
                        chainRatioJson.put("actionRatioProportion", 0);
                    }
                } else {
                    chainRatioJson.put("actionRatioProportion", 0);
                }
                // 千次花费
                BigDecimal contrastImpression1kCost = contrastJson.getBigDecimal("impression1kCost");
                BigDecimal beContrastImpression1kCost = beContrastJson.getBigDecimal("impression1kCost");
                if (!Check.isNull(contrastImpression1kCost) && !Check.isNull(beContrastImpression1kCost)) {
                    if (beContrastImpression1kCost.compareTo(new BigDecimal(0)) != 0) {
                        BigDecimal impression1kCostProportion = (contrastImpression1kCost.subtract(beContrastImpression1kCost)).divide(beContrastImpression1kCost, 2, RoundingMode.HALF_UP);
                        chainRatioJson.put("impression1kCostProportion", impression1kCostProportion);
                    } else {
                        chainRatioJson.put("impression1kCostProportion", 0);
                    }
                } else {
                    chainRatioJson.put("impression1kCostProportion", 0);
                }
                // 转化书
                Long contrastConversions = contrastJson.getLong("conversions");
                Long beContrastConversions = beContrastJson.getLong("conversions");
                if (!Check.isNull(contrastConversions) && !Check.isNull(beContrastConversions)) {
                    if (beContrastConversions != 0L) {
                        double conversionsProportion = (contrastConversions.doubleValue() - beContrastConversions.doubleValue()) / beContrastConversions.doubleValue();
                        chainRatioJson.put("conversionsProportion", conversionsProportion);
                    } else {
                        chainRatioJson.put("conversionsProportion", 0);
                    }
                } else {
                    chainRatioJson.put("conversionsProportion", 0);
                }
                // 转化单价
                BigDecimal contrastConversionPrice = contrastJson.getBigDecimal("conversionPrice");
                BigDecimal beContrastConversionPrice = beContrastJson.getBigDecimal("conversionPrice");
                if (!Check.isNull(contrastConversionPrice) && !Check.isNull(beContrastConversionPrice)) {
                    if (beContrastConversionPrice.compareTo(new BigDecimal(0)) != 0) {
                        BigDecimal conversionPriceProportion = (contrastConversionPrice.subtract(beContrastConversionPrice)).divide(beContrastConversionPrice, 2, RoundingMode.HALF_UP);
                        chainRatioJson.put("conversionPriceProportion", conversionPriceProportion);
                    } else {
                        chainRatioJson.put("conversionPriceProportion", 0);
                    }
                } else {
                    chainRatioJson.put("conversionPriceProportion", 0);
                }
                returnJson.put("chainRatio", chainRatioJson);
            }

            log.info("素材数据获取环比请求所用时长------------->: {} ms", System.currentTimeMillis() - startTime);
            return returnJson;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return returnJson;
    }


    /**
     * 查询 所有绑定账号
     *
     * @param userId
     * @return
     */
    @Override
    public List<UserAllocation> selectAccountIds(String userId) {
        String roleCode = sysRoleExtMapper.getRoleCodeByUserId(userId);
        QueryWrapper<UserAllocation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("media_id", 2);
        if ("operator".equals(roleCode)) {
            queryWrapper.eq("userId", userId);
        }
        queryWrapper.isNotNull("account_id");
        queryWrapper.groupBy("account_id");
        queryWrapper.orderByAsc("advertiser_name");

        List<UserAllocation> userAllocations = userAllocationMapper.selectList(queryWrapper);
        return userAllocations;
    }

    /**
     * 根据账号 查询素材报表
     *
     * @param json
     * @return
     */
    @Override
    public List<JSONObject> selectReportByAccountIds(JSONObject json) {
        long startTime = System.currentTimeMillis();
        List<JSONObject> marketJsonList = new ArrayList<>();
        try {
            if (Check.isNull(json)) {
                return marketJsonList;
            }
            JSONArray accountIds = json.getJSONArray("accountIds");
            if (Check.isNull(accountIds)) {
                return marketJsonList;
            }
            String nowDate = DateUtils.getNowDate("yyyy-MM-dd");
            String anotherDay = DateUtils.getAnotherDay("yyyy-MM-dd", nowDate, -1);
            Integer type = json.getInteger("type");

            Map<String, Object> paramsMap = new HashMap<>();
            paramsMap.put("accountIds", accountIds);
            if (type == 1) {
                // 今天分时数据
                Integer maxHour = materialReportMapper.selectMaxHourByDate(nowDate);
                if (Check.isNull(maxHour) || maxHour == 0) {
                    return marketJsonList;
                }
                Integer statHour = maxHour - 1;
                paramsMap.put("statHour", statHour);
                paramsMap.put("statDate", nowDate);
                marketJsonList = materialReportMapper.selectHourMaterialList(paramsMap);
            } else if (type == 2) {
                paramsMap.put("startDate", anotherDay);
                paramsMap.put("endDate", anotherDay);
                marketJsonList = materialReportMapper.selectDayMaterialList(paramsMap);
            } else if (type == 3) {
                String startDate = DateUtils.getAnotherDay("yyyy-MM-dd", anotherDay, -6);
                paramsMap.put("startDate", startDate);
                paramsMap.put("endDate", anotherDay);
                marketJsonList = materialReportMapper.selectDayMaterialList(paramsMap);
            } else if (type == 4) {
                String startDate = DateUtils.getAnotherDay("yyyy-MM-dd", anotherDay, -14);
                paramsMap.put("startDate", startDate);
                paramsMap.put("endDate", anotherDay);
                marketJsonList = materialReportMapper.selectDayMaterialList(paramsMap);
            } else if (type == 5) {
                String startDate = DateUtils.getMonthBefore("yyyy-MM-dd", anotherDay, -1);
                paramsMap.put("startDate", startDate);
                paramsMap.put("endDate", anotherDay);
                marketJsonList = materialReportMapper.selectDayMaterialList(paramsMap);
            } else if (type == 6) {
                String startDate = DateUtils.getMonthBefore("yyyy-MM-dd", anotherDay, -3);
                paramsMap.put("startDate", startDate);
                paramsMap.put("endDate", anotherDay);
                marketJsonList = materialReportMapper.selectDayMaterialList(paramsMap);
            } else if (type == 7) {
                String startDate = DateUtils.getMonthBefore("yyyy-MM-dd", anotherDay, -6);
                paramsMap.put("startDate", startDate);
                paramsMap.put("endDate", anotherDay);
                marketJsonList = materialReportMapper.selectDayMaterialList(paramsMap);
            } else if (type == 9) {
                String startDate = json.getString("startDate");
                String endDate = json.getString("endDate");
                paramsMap.put("startDate", startDate);
                paramsMap.put("endDate", endDate);
                marketJsonList = materialReportMapper.selectDayMaterialList(paramsMap);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info("账户维度素材数据请求所用时长------------->: {} ms", System.currentTimeMillis() - startTime);
        return marketJsonList;
    }
}
