package org.jeecg.ctop.material.service.impl;


import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.DateUtils;
import org.jeecg.ctop.material.constants.Check;
import org.jeecg.ctop.material.entity.vo.KuaiShouAccountPieVo;
import org.jeecg.ctop.material.entity.vo.KuaiShouOperateAccountVo;
import org.jeecg.ctop.material.entity.vo.KuaiShouOperateProjectVo;
import org.jeecg.ctop.material.entity.vo.KuaiShouOperateVo;
import org.jeecg.ctop.material.mapper.MaterialStareMapper;
import org.jeecg.ctop.material.service.MaterialStareService;
import org.jeecg.ctop.material.utils.FeidNotNullUtils;
import org.jeecg.ctop.material.utils.LinkUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 盯盘接口
 */
@Slf4j
@Service
public class MaterialStareServiceImpl implements MaterialStareService {

    @Resource
    MaterialStareMapper materialStareMapper;




    /**
     *
     * @description:数据总览-快手-运营经理
     *
     * @param mediaType 媒体类型 1-头条 2-快手
     * @param type 查询类型 1-汇总 2-运营个人
     * @param userId
     * @param startTime
     * @param startTime
     * @author: zianY
     * @time: 2022/2/15
     */
    @Override
    public Result kuaiShousumData(String mediaType, String type, String startTime, String endTime, String userId) {
        long stratDate = DateUtils.getDateInteger(startTime);
        long endDate = DateUtils.getDateInteger(endTime);
        //查询当前人员所有下级
        Set<String> operatorUserIds = getAffiliateId(userId);
        //头条
        if (StringUtils.equals(mediaType,"1")){
            return Result.successMsg("暂无头条数据。",null);
        }
        //快手
        if (StringUtils.equals(mediaType,"2")){
            //汇总
            if (StringUtils.equals(type,"1")){
                //查询一天数据时 查询时报
                if (stratDate == endDate){
                    Map resultMap = new HashMap<>();
                    //时报
                    List<Map> todayList = materialStareMapper.getKuaiShouCostHourlyByUserIdList(stratDate, endDate, operatorUserIds);
                    long time = DateUtils.getDateInteger(DateUtils.addDayParse(Long.toString(endDate), -1));
                    List<Map> yesterdayList = materialStareMapper.getKuaiShouCostHourlyByUserIdList(time,time , operatorUserIds);
                    resultMap.put("todayList",todayList);
                    resultMap.put("yesterdayList",yesterdayList);
                    return Result.successMsg("查询-时报-汇总。",resultMap);
                }
                //多天 数据
                // 日报
                List<Map> dailyList = materialStareMapper.getKuaiShouCostDailyByUserIdList(stratDate, endDate, operatorUserIds);
                return Result.successMsg("查询-日报-汇总成功。",dailyList);

            //运营个人
            }else if (StringUtils.equals(type,"2")){
                if (stratDate == endDate){
                    //时报 消耗前5
                    List<JSONObject> userList = materialStareMapper.getKuaiShouCostByTop5HourList(stratDate, endDate, operatorUserIds);
                    List<Map> resultList = new ArrayList<>();
                    for (JSONObject jsonObject : userList) {
                        Map map = new HashMap();
                        Set<String> userSet = new HashSet<String>(){{
                            add(jsonObject.getString("user_id"));
                        }};
                        List<Map> usertopList = materialStareMapper.getKuaiShouCostHourlyByUserIdList(stratDate, endDate, userSet);
                        map.put("userName",jsonObject.getString("userName"));
                        map.put("data",usertopList);
                        resultList.add(map);
                    }
                    return Result.successMsg("查询-时报-运营个人消耗top5成功。",resultList);
                }

                //日报 消耗前5
                List<JSONObject> userList = materialStareMapper.getKuaiShouCostByTop5DailyList(stratDate,endDate, operatorUserIds);
                List<Map> resultList = new ArrayList<>();
                for (JSONObject jsonObject : userList) {
                    Map map = new HashMap();
                    Set<String> userSet = new HashSet<String>(){{
                        add(jsonObject.getString("user_id"));
                    }};
                    List<Map> usertopList = materialStareMapper.getKuaiShouCostDailyByUserIdList(stratDate, endDate, userSet);
                    map.put("userName",jsonObject.getString("userName"));
                    map.put("data",usertopList);
                    resultList.add(map);
                }
                return Result.successMsg("查询-日报-运营个人消耗top5成功。",resultList);
            }
        }
        return null;
    }

    /**
     *
     * @description: 数据总览-快手-运营个人
     *
     * @param mediaType 媒体类型 1-头条 2-快手
     * @param startTime
     * @param endTime
     * @param userId
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/3/3
     */
    @Override
    public Result kuaiShousumDataPersonal(String mediaType,String startTime, String endTime, String userId) {

        long stratDate = DateUtils.getDateInteger(startTime);
        long endDate = DateUtils.getDateInteger(endTime);
        Set<String> userSet = new HashSet<String>(){{
            add(userId);
        }};

        //头条
        if (StringUtils.equals(mediaType,"1")){
            return Result.successMsg("暂无头条数据。",null);
        }
        //快手
        if (StringUtils.equals(mediaType,"2")){
            //查询一天数据时 查询时报
            if (stratDate == endDate){
                Map resultMap = new HashMap<>();
                //时报
                List<Map> todayList = materialStareMapper.getKuaiShouCostHourlyByUserIdList(stratDate, endDate, userSet);
                long time = DateUtils.getDateInteger(DateUtils.addDayParse(Long.toString(endDate), -1));
                List<Map> yesterdayList = materialStareMapper.getKuaiShouCostHourlyByUserIdList(time,time , userSet);
                resultMap.put("todayList",todayList);
                resultMap.put("yesterdayList",yesterdayList);
                return Result.successMsg("查询运营个人-时报-汇总。",resultMap);
            }
            //多天 数据
            // 日报
            List<Map> dailyList = materialStareMapper.getKuaiShouCostDailyByUserIdList(stratDate, endDate, userSet);
            return Result.successMsg("查询运营个人-日报-汇总成功。",dailyList);
        }
        return null;
    }


    /**
     *
     * @description: 快手-运营组数据
     *
     * @param mediaType 媒体类型 1-头条 2-快手
     * @param startTime
     * @param endTime
     * @param userId
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/2/15
     */
    @Override
    public Result kuaiShouOperateDateTotal(String mediaType, String startTime, String endTime, String userId) {
        Map resultMap = new HashMap();
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");
        //查询用户所属公司
        String companyId = materialStareMapper.getUserCompanyByUserId(userId);
        Set<String> operatorUserIds = null;
        try {
            //查询当前人员所有下级
            operatorUserIds= getAffiliateId(userId);

            //有消耗的账户
            operatorUserIds = materialStareMapper.getKuaiShouAllOperators(companyId,DateUtils.getDateInteger(startTime).longValue(),DateUtils.getDateInteger(endTime).longValue(),operatorUserIds);

            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            // ==>> 20220202
            String now = sdf.format(new Date());
            long nowDate = Long.valueOf(now);
            int nowHour = DateUtils.getNowHour();
            //昨天时间
            long time = DateUtils.getDateInteger(DateUtils.addDayParse(now, -1));

            //当天总消耗
            JSONObject jsonObjectNow = materialStareMapper.getKuaiShouTotalCost(nowDate,nowDate,nowHour,operatorUserIds);
            resultMap.put("todayCost",jsonObjectNow.getString("totalCost"));
            //昨天总消耗
            JSONObject jsonObjectYesterday = materialStareMapper.getKuaiShouTotalCost(time,time,nowHour,operatorUserIds);
            //今日同比 = （今天总消耗 - 昨天总消耗 ） / 昨天总消耗
            Double d = (Double.valueOf(jsonObjectNow.getString("totalCost")) - Double.valueOf(jsonObjectYesterday.getString("totalCost"))) / Double.valueOf(jsonObjectYesterday.getString("totalCost"));
            resultMap.put("compare",decimalFormat.format(d));

            //时间段内 总消耗 及 账户数量
            JSONObject totalCost = materialStareMapper.getKuaiShouTotalCostDaily(Long.valueOf(DateUtils.getDateInteger(startTime)),
                    Long.valueOf(DateUtils.getDateInteger(endTime)),
                    operatorUserIds);
            resultMap.put("sectionCost",totalCost.getDoubleValue("totalCost"));
            // 人均账户数量 = 时间段内 账户总数量 / 人数
            Double userAverageAccount = Double.valueOf(totalCost.getString("accountNum")) / operatorUserIds.size();
            // 人均消耗 = 时间段内 总消耗 / 人数
            Double userAveragecost = Double.valueOf(totalCost.getString("totalCost")) / operatorUserIds.size();
            DecimalFormat df = new DecimalFormat("#.000");
            resultMap.put("userAverageAccount",new Double(Math.ceil(userAverageAccount)).intValue());
            resultMap.put("userAveragecost",df.format(userAveragecost));
        }catch (Exception e){
            e.printStackTrace();
        }
        return Result.successMsg("查询成功",resultMap);
    }

    /**
     *
     * @description: 运营个人数据
     *
     * @param mediaType 媒体类型 1-头条 2-快手
     * @param startTime
     * @param endTime
     * @param userId
     * @return: org.jeecg.common.api.vo.Result<com.alibaba.fastjson.JSONObject>
     * @author: zianY
     * @time: 2022/3/3
     */
    @Override
    public Result kuaiShouOperateDateTotalPersonal(String mediaType, String startTime, String endTime, String userId) {
        Map resultMap = new HashMap();
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");

        long stratDate = DateUtils.getDateInteger(startTime);
        long endDate = DateUtils.getDateInteger(endTime);

        try {
            Set<String> userSet = new HashSet<String>(){{
                add(userId);
            }};

            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            // ==>> 20220202
            String now = sdf.format(new Date());
            long nowDate = Long.valueOf(now);
            int nowHour = DateUtils.getNowHour();
            //昨天时间
            long time = DateUtils.getDateInteger(DateUtils.addDayParse(now, -1));

            //当天总消耗
            JSONObject jsonObjectNow = materialStareMapper.getKuaiShouTotalCost(nowDate,nowDate,nowHour,userSet);
            resultMap.put("todayCost",Check.isNull(jsonObjectNow.getString("totalCost")) ? "0" : jsonObjectNow.getString("totalCost"));
            //昨天同时段总消耗
            JSONObject jsonObjectYesterday = materialStareMapper.getKuaiShouTotalCost(time,time,nowHour,userSet);

            //今日同比 = （今天总消耗 - 昨天总消耗 ） / 昨天总消耗
            Double d = new Double("0");
            if (!Check.isNull( jsonObjectNow.getString("totalCost")) && !Check.isNull(jsonObjectYesterday.getString("totalCost"))){
                 d = (Double.valueOf(jsonObjectNow.getString("totalCost"))
                        - Double.valueOf(jsonObjectYesterday.getString("totalCost")))
                        / Double.valueOf(jsonObjectYesterday.getString("totalCost"));
            }
            resultMap.put("todayCompare",decimalFormat.format(d));

            //所选时段消耗
            JSONObject timeNowCost = materialStareMapper.getKuaiShouTotalCostDaily(stratDate,endDate,userSet);
            resultMap.put("timeCost",Check.isNull(timeNowCost.getString("totalCost")) ? "0" : timeNowCost.getString("totalCost"));
            //上阶段时间
            Map<String,String> lastTime = DateUtils.getStartEndTime(startTime,endTime);
            long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
            long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));

            //上阶段消耗
            JSONObject timeLastCost = materialStareMapper.getKuaiShouTotalCostDaily(lastTimeStart,lastTimeEnd,userSet);
            //环比 = （当前总消耗 - 上阶段总消耗 ） / 上阶段总消耗
            Double timeCompare = new Double("0");
            if (!Check.isNull(timeNowCost.getString("totalCost")) && !Check.isNull(timeLastCost.getString("totalCost"))){
                timeCompare = (Double.valueOf(timeNowCost.getString("totalCost")) - Double.valueOf(timeLastCost.getString("totalCost"))) / Double.valueOf(timeLastCost.getString("totalCost"));
            }

            resultMap.put("timeCompare",decimalFormat.format(timeCompare));

            //当前月份的框返 和 激励
            // 当前月份第一天
            long monthFirstDay = Long.valueOf(DateUtils.getFirstDayByMonth());
            //框返 激励
            JSONObject nowMonthCost = materialStareMapper.getKuaiShouAccountCharged(monthFirstDay,nowDate,userSet);



            resultMap.put("directCharged",Check.isNull(nowMonthCost) ? "0" : nowMonthCost.getString("directCharged"));//框返
            resultMap.put("contractCharged",Check.isNull(nowMonthCost) ? "0" : nowMonthCost.getString("contractCharged"));//激励

            //当前月消耗
            JSONObject monthCost = materialStareMapper.getKuaiShouAccountCostMonth(userId, monthFirstDay,nowDate);
            resultMap.put("monthCost",Check.isNull(monthCost) ? "0" : monthCost.getString("cost"));

            //用户
            JSONObject userName = materialStareMapper.getKuaiShouUserByUserId(userId);
            resultMap.put("userName",Check.isNull(userName) ? "-" : userName.getString("userName"));


            //公司 组内排名
            //用户所属公司id
            String companyId = materialStareMapper.getUserCompanyByUserId(userId);
            //组内排名
            List<JSONObject> groupRankList = materialStareMapper.getKuaiShouPersonalGroupRank(monthFirstDay,nowDate,companyId);
            resultMap.put("userRankTotalNum",groupRankList.size());//排名总数
            for (JSONObject group : groupRankList) {
                if (group.getString("user_id").equals(userId)){
                    resultMap.put("userIdRank",group.getString("serialNumber"));//排名
                }
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        return Result.successMsg("查询运营个人数据成功",resultMap);
    }

    /**
     *
     * @description: 运营数据详情
     *
     * @param pageNum
     * @param pageSize
     * @param startTime
     * @param endTime
     * @param userId
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/2/16
     */
    @Override
    public Result getKuaiShouOperateInfo(Integer pageNum, int pageSize, String startTime, String endTime, String userId) {
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");

        try {
        //查询当前人员所有下级
        Set<String> operatorUserIds = getAffiliateId(userId);
        //2022-02-15 ==>> 20220215
        long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
        long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));
        //上阶段时间
        Map<String,String> lastTime = DateUtils.getStartEndTime(startTime,endTime);
        long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
        long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));

        PageHelper.startPage(pageNum,pageSize);
        //查询运营数据
        List<KuaiShouOperateVo> listOperate = materialStareMapper.getKuaiShouOperateInfo(startDate,entDate,operatorUserIds);
        for (KuaiShouOperateVo operate : listOperate) {

            //查询 有效 上新计划 上新组
            JSONObject newEffect = materialStareMapper.getKuaiShouAccountBaseByUserId(operate.getUserId(),null,null,startDate,entDate);
            operate.setNewEffectNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newEffectNum"));//有效
            operate.setNewCampaignNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newCampaignNum"));//计划
            operate.setNewUnitNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newUnitNum"));//组

            Set<String> userSet = new HashSet<String>(){{
                add(operate.getUserId());
            }};
            List<KuaiShouOperateVo> userOperate = materialStareMapper.getKuaiShouOperateInfo(lastTimeStart,lastTimeEnd,userSet);
            String rate = "0";
            if (!Check.isNull(userOperate)){
                //环比
                Double rateDoulbe = (operate.getTotalCost() - userOperate.get(0).getTotalCost()) / userOperate.get(0).getTotalCost();
                rate = decimalFormat.format(rateDoulbe);
            }
            operate.setRate(rate);
        }
        PageInfo<KuaiShouOperateVo> pageInfo = new PageInfo<>(listOperate);
        return Result.successMsg("运营数据查询成功。",pageInfo);
       }catch (Exception e){
           e.printStackTrace();
       }
        return Result.errorMsg("哎呀,查询失败了。");
    }

    @Override
    public Result exportKuaiShouOperateInfo(String startTime, String endTime, String userId, HttpServletResponse response) {
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");
        try {
        //查询当前人员所有下级
        Set<String> operatorUserIds = getAffiliateId(userId);
        //2022-02-15 ==>> 20220215
        long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
        long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));
        //上阶段时间
        Map<String,String> lastTime = DateUtils.getStartEndTime(startTime,endTime);
        long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
        long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));

        //查询运营数据
        List<KuaiShouOperateVo> listOperate = materialStareMapper.getKuaiShouOperateInfo(startDate,entDate,operatorUserIds);
        for (KuaiShouOperateVo operate : listOperate) {

            //查询 有效 上新计划 上新组
            JSONObject newEffect = materialStareMapper.getKuaiShouAccountBaseByUserId(operate.getUserId(),null,null,startDate,entDate);
            operate.setNewEffectNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newEffectNum"));//有效
            operate.setNewCampaignNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newCampaignNum"));//计划
            operate.setNewUnitNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newUnitNum"));//组

            Set<String> userSet = new HashSet<String>(){{
                add(operate.getUserId());
            }};
            List<KuaiShouOperateVo> userOperate = materialStareMapper.getKuaiShouOperateInfo(lastTimeStart,lastTimeEnd,userSet);
            String rate = "0";
            if (!Check.isNull(userOperate)){
                //环比 = （当前 - 上阶段 ） / 上阶段
                Double rateDouble = (operate.getTotalCost() - userOperate.get(0).getTotalCost() ) / userOperate.get(0).getTotalCost();
                rate = decimalFormat.format(rateDouble);
            }
            operate.setRate(rate);
        }
       Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("运营数据详情", "运营数据"), KuaiShouOperateVo.class, listOperate);
       response.setCharacterEncoding("UTF-8");
       response.setHeader("content-Type", "application/vnd.ms-excel");
       response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("运营数据详情.xlsx", "UTF-8"));
       workbook.write(response.getOutputStream());
       return null;
       }catch (Exception e){
           e.printStackTrace();
       }
        return Result.errorMsg("哎呀,查询失败了。");
    }


    /**
     *
     * @description: 运营数据-项目列表
     *
     * @param pageNum
     * @param pageSize
     * @param startTime
     * @param endTime
     * @param userId
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/2/17
     */
    @Override
    public Result getKuaiShouOperateProjectInfo(Integer pageNum, int pageSize, String startTime, String endTime, String userId) {
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");
        try {
            //查询当前人员所有下级
            Set<String> operatorUserIds = getAffiliateId(userId);
            //2022-02-15 ==>> 20220215
            long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
            long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));

            //计算环比 时间值 上阶段时间 以及 两个日期之间的 间隔天数
            Map<String,String> lastTime = DateUtils.getStartEndTime(startTime,endTime);
            long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
            long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));
            Integer daysBetween = Integer.valueOf(lastTime.get("daysBetween"))+1;

            //计算同比 时间值 只支持7天
            long startEqually = new Long("0");
            long endEqually = new Long("0");
            if (daysBetween <= 7) {
                startEqually = DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(DateUtils.getDateInteger(startTime)), -7));
                endEqually = DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(DateUtils.getDateInteger(endTime)), -7));
            }

            PageHelper.startPage(pageNum,pageSize);
            //查询运营数据-项目维度
            List<KuaiShouOperateProjectVo> listOperate = materialStareMapper.getKuaiShouOperateProjectInfo(startDate,entDate,null,operatorUserIds);
            for (KuaiShouOperateProjectVo projectInfo : listOperate) {

                //查询 有效 上新视频 爆款视频
                JSONObject newEffect = materialStareMapper.getKuaiShouAccountBaseByUserId(null,projectInfo.getProjectId(),null,startDate,entDate);
                projectInfo.setNewEffectNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newEffectNum"));//有效
                projectInfo.setNewVideoNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newVideoNum"));//上新
                projectInfo.setNewHotNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newHotNum"));//爆款


                String projectId = projectInfo.getProjectId();
                List<KuaiShouOperateProjectVo> projectYearOnYearInfo = materialStareMapper.getKuaiShouOperateProjectInfo(lastTimeStart,lastTimeEnd,projectId,operatorUserIds);
                //环比 = （当前 - 上阶段 ） / 上阶段
                String yearOnYear = "0";
                if (!Check.isNull(projectYearOnYearInfo)){
                    Double yearOnYearD = (projectInfo.getTotalCost() - projectYearOnYearInfo.get(0).getTotalCost()) / projectYearOnYearInfo.get(0).getTotalCost();
                    yearOnYear = decimalFormat.format(yearOnYearD);
                }
                projectInfo.setYearOnYear(yearOnYear);

                //同比 日期超过 7 天 则不显示
                String equallyRate = "-";
                if (daysBetween <= 7){
                    List<KuaiShouOperateProjectVo> projectEquallyInfo = materialStareMapper.getKuaiShouOperateProjectInfo(startEqually,endEqually,projectId,operatorUserIds);
                    if (!Check.isNull(projectEquallyInfo)){
                        Double equallyRateD = (projectInfo.getTotalCost() - projectEquallyInfo.get(0).getTotalCost()) / projectEquallyInfo.get(0).getTotalCost();
                        equallyRate = decimalFormat.format(equallyRateD);
                    }
                }
                projectInfo.setEquallyRate(equallyRate);

            }

            PageInfo<KuaiShouOperateProjectVo> pageInfo = new PageInfo<>(listOperate);
            return Result.successMsg("运营项目列表数据查询成功。",pageInfo);
        }catch (Exception e){
            e.printStackTrace();
        }
        return Result.errorMsg("哎呀,查询失败了。");
    }



    /**
     *
     * @description: 运营数据-账户列表
     *
     * @param pageNum
     * @param pageSize
     * @param startTime
     * @param endTime
     * @param userId
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/2/18
     */
    @Override
    public Result getKuaiShouOperateAccountInfo(Integer pageNum, int pageSize, String startTime, String endTime,String projectId, String userId) {
        DecimalFormat decimalFormat = new DecimalFormat("0.00%");
        try {
            //查询当前人员所有下级
            Set<String> operatorUserIds = getAffiliateId(userId);
            //2022-02-15 ==>> 20220215
            long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
            long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));

            //计算环比 时间值 上阶段时间 以及 两个日期之间的 间隔天数
            Map<String,String> lastTime = DateUtils.getStartEndTime(startTime,endTime);
            long lastTimeStart = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeStart")));
            long lastTimeEnd = Long.valueOf(DateUtils.getDateInteger(lastTime.get("lastTimeEnd")));
            Integer daysBetween = Integer.valueOf(lastTime.get("daysBetween"))+1;

            //计算同比 时间值 只支持7天
            long startEqually = new Long("0");
            long endEqually = new Long("0");
            if (daysBetween <= 7) {
                startEqually = DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(DateUtils.getDateInteger(startTime)), -7));
                endEqually = DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(DateUtils.getDateInteger(endTime)), -7));
            }

            PageHelper.startPage(pageNum,pageSize);
            //查询运营数据-账户 维度
            List<KuaiShouOperateAccountVo> listOperate = materialStareMapper.getKuaiShouOperateAccountInfo(startDate,entDate,projectId,null,operatorUserIds);
            for (KuaiShouOperateAccountVo accountInfo : listOperate) {

                //查询 有效 上新视频 爆款视频
                JSONObject newEffect = materialStareMapper.getKuaiShouAccountBaseByUserId(null,null,String.valueOf(accountInfo.getAccountId()),startDate,entDate);
                accountInfo.setNewEffectNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newEffectNum"));//有效
                accountInfo.setNewVideoNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newVideoNum"));//上新
                accountInfo.setNewHotNum(Check.isNull(newEffect) ? 0 : newEffect.getInteger("newHotNum"));//爆款

                long accountId = accountInfo.getAccountId();
                List<KuaiShouOperateAccountVo> accountYearOnYearInfo = materialStareMapper.getKuaiShouOperateAccountInfo(lastTimeStart,lastTimeEnd,projectId,accountId,operatorUserIds);
                //环比 = （当前 - 上阶段 ） / 上阶段
                String yearOnYear = "0";
                if (!Check.isNull(accountYearOnYearInfo)){
                    Double yearOnYearD = (accountInfo.getTotalCost() - accountYearOnYearInfo.get(0).getTotalCost()) / accountYearOnYearInfo.get(0).getTotalCost();
                    yearOnYear = decimalFormat.format(yearOnYearD);
                }
                accountInfo.setYearOnYear(yearOnYear);

                //同比 日期超过 7 天 则不显示
                String equallyRate = "-";
                if (daysBetween <= 7){
                    List<KuaiShouOperateAccountVo> accountEquallyInfo = materialStareMapper.getKuaiShouOperateAccountInfo(startEqually,endEqually,projectId,accountId,operatorUserIds);
                    if (!Check.isNull(accountEquallyInfo)){
                        Double equallyRateD = (accountInfo.getTotalCost() - accountEquallyInfo.get(0).getTotalCost()) / accountEquallyInfo.get(0).getTotalCost();
                        equallyRate = decimalFormat.format(equallyRateD);
                    }
                }
                accountInfo.setEquallyRate(equallyRate);
            }

            PageInfo<KuaiShouOperateAccountVo> pageInfo = new PageInfo<>(listOperate);
            return Result.successMsg("运营账户列表数据查询成功。",pageInfo);
        }catch (Exception e){
            e.printStackTrace();
        }
        return Result.errorMsg("哎呀,查询失败了。");
    }


    /**
     *
     * @description: 查询账户余额 以及 账户状态 和 消耗
     *
     * @param accountId
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/2/21
     */
    @Override
    public Result getKuaiShouAccountInfo(long accountId) {
        Map resultMap = new HashMap();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        // ==>> 20220202
        String now = sdf.format(new Date());
        long nowDate = Long.valueOf(now);
        //当前月份第一天
        long monthFirstDay = Long.valueOf(DateUtils.getFirstDayByMonth());
        //账户余额
        JSONObject balance = materialStareMapper.getKuaiShouAccountBalance(accountId);
        resultMap.put("balance",Check.isNull(balance) ? "0" : balance.getString("balance"));
        //账户今日消耗 以及状态
        JSONObject totalCost = materialStareMapper.getKuaiShouAccountTotalCost(accountId, nowDate);

        resultMap.put("accountId",Check.isNull(totalCost) ? "-" : totalCost.getString("accountId"));
        resultMap.put("accountName",Check.isNull(totalCost) ? "0" : totalCost.getString("accountName"));

        resultMap.put("totalCost",Check.isNull(totalCost) ? "0" : totalCost.getString("todayCost"));
        //0-开 1-关
        resultMap.put("state", Check.isNull(totalCost) ? "1" : totalCost.getString("accountStatus"));

        return Result.successMsg("账户查询成功",resultMap);
    }


    /**
     *
     * @description: 账户 折线图 查询时间为当天查询时报；查询时间为多天 查询日报
     *
     * @param accountId
     * @param startTime
     * @param endTime
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/2/21
     */
    @Override
    public Result getKuaiShouAccountInfoBrokenLine(long accountId, String startTime, String endTime,String type) {

        List<JSONObject> resultList = new ArrayList<>();
        try {
            //2022-02-15 ==>> 20220215
            long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
            long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));

            //两个日期之间的 间隔天数
            Map<String,String> lastTime = DateUtils.getStartEndTime(startTime,endTime);
            Integer daysBetween = Integer.valueOf(lastTime.get("daysBetween"));

            if (daysBetween == 0){
                //昨天
                long yesterday = DateUtils.getDateInteger(DateUtils.addDayParse(String.valueOf(entDate), -1));
                resultList = materialStareMapper.getKuaiShouAccountInfoBrokenLineHour(type,accountId,startDate,yesterday);
                return Result.successMsg("账户时报报折线图查询成功",resultList);
            }
            resultList = materialStareMapper.getKuaiShouAccountInfoBrokenLineDaily(type,accountId,startDate,entDate);

            return Result.successMsg("账户日报折线图查询成功",resultList);

        }catch (Exception e){
            e.printStackTrace();
        }
        return Result.errorMsg("账户折线图查询异常");
    }


    /**
     *
     * @description: 快手 账户 素材上新-有效-爆款
     *
     * @param accountId
     * @param searchType searchType：查询类型  0-全部 1-上新 2-有效 3-爆款
     * @param startTime
     * @param endTime
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/2/21
     */
    @Override
    public Result getKuaiShouAccountMaterialNewAndEffectAndFaddish(long accountId, String searchType, String startTime, String endTime,Integer pageNum,Integer pageSize) {
        //2022-02-15 ==>> 20220215
        long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
        long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));
        PageHelper.startPage(pageNum,pageSize);
        List<JSONObject> resultList = materialStareMapper.getKuaiShouAccountMaterialNewAndEffectAndFaddish(accountId,searchType,startDate,entDate);
        PageInfo<JSONObject> pageInfo = new PageInfo<>(resultList);
        return Result.successMsg("查询账户素材信息成功。",pageInfo);
    }

    /**
     *
     * @description: 查询账户饼图数据信息
     *
     * @param accountId
     * @param startTime
     * @param endTime
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     * @time: 2022/2/22
     */
    @Override
    public Result getKuaiShouAccountPieChar(long accountId, String startTime, String endTime,String type) {
        Map resultMap = new HashMap();
        //2022-02-15 ==>> 20220215
        long startDate = Long.valueOf(DateUtils.getDateInteger(startTime));
        long entDate = Long.valueOf(DateUtils.getDateInteger(endTime));
        //版位
        List<KuaiShouAccountPieVo> sceneList = materialStareMapper.getKuaiShouAccountPieScene(accountId,startDate,entDate,type);
        //年龄
        List<KuaiShouAccountPieVo> ageList = materialStareMapper.getKuaiShouAccountPieAge(accountId,startDate,entDate,type);
        //性别
        List<KuaiShouAccountPieVo> genderList = materialStareMapper.getKuaiShouAccountPieGender(accountId,startDate,entDate,type);
        resultMap.put("scene",sceneList);
        resultMap.put("age",ageList);
        resultMap.put("gender",genderList);
        return Result.successMsg("查询饼图数据成功。",resultMap);
    }

    @Override
    public Result kuaiShouRealTimeUnitDateInfo(long accountId, Integer pageNum, Integer pageSize) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        // ==>> 20220202
        String now = sdf.format(new Date());
        long nowDate = Long.valueOf(now);

        PageHelper.startPage(pageNum,pageSize);
        List<JSONObject> ListUnit = materialStareMapper.kuaiShouRealTimeUnitDateInfo(accountId,nowDate);
        for (JSONObject unitVo : ListUnit) {

            //优化目标
           Integer conver = Check.isNull(unitVo.getInteger("ocpx_action_type")) ? 0 : unitVo.getInteger("ocpx_action_type");

            //优化目标： 激活，  付费，  行为，  表单提交，  注册，  唤起应用，  关键行为
            //对应转化数 激活数，付费数，行为数，表单提交数，注册数，唤起应用次数，关键行为数
            //优化目标id 来源---ctop_kuaishou_ocpx_action_type_config
            unitVo.put("converNum",0);//默认
            //激活
            if (conver == 180) {
                unitVo.put("converNum",unitVo.getInteger("activation"));
            }
            //付费
            if (conver == 190) {
                unitVo.put("converNum",unitVo.getInteger("eventPay"));
            }
            //行为
            if (conver == 2) {
                unitVo.put("converNum",unitVo.getInteger("bClick"));
            }
            //表单提交
            if (conver == 53) {
                unitVo.put("converNum",unitVo.getInteger("formCount"));
            }
            //注册
            if (conver == 396) {
                unitVo.put("converNum",unitVo.getInteger("eventRegister"));
            }
            //唤起应用
            if (conver == 324) {
                unitVo.put("converNum",unitVo.getInteger("eventAppInvoked"));
            }
            //关键行为
            if (conver == 773) {
                unitVo.put("converNum",unitVo.getInteger("keyAction"));
            }

            //转化成本 = 花费 / 转化数
            double converCost = unitVo.getInteger("converNum") == 0 ? 0 : unitVo.getDouble("charge") / unitVo.getInteger("converNum");
            unitVo.put("converCost",converCost);


            //操作建议

            //消耗
            Double charge = unitVo.getDoubleValue("charge");

            //出价 单位:厘
            long bid = new Long("1000");
            //2：CPC
            if (unitVo.getInteger("bidType") == 2){
                bid = unitVo.getLong("bid");
            //10：OCPM
            }else if(unitVo.getInteger("bidType") == 10){
                bid = unitVo.getLong("cpaBid");
            }
            Double price = new Double(bid/1000).doubleValue();

            //转化数量
            Integer converNum = unitVo.getInteger("converNum");

            unitVo.put("operationAgree","暂无");
            unitVo.put("operationContent","暂无");
            unitVo.put("operationAgreeInfo","暂无");

            //1. 转化成本大于出价×120%，消耗大于500元：
            if ((converCost > price * 1.2) && (charge > 500)) {
                unitVo.put("operationAgree","高成本 | 有消耗");
                unitVo.put("operationContent","建议限制预算");
                unitVo.put("operationAgreeInfo","当前广告组转化成本偏高且消耗大于500，建议限制预算;");
            }
            //2.  转化成本大于出价×120%，转化数大于10小于等于50：
            if (converCost > price * 1.2 && LinkUtil.isInTheInterval(String.valueOf(converNum), "(10,50)")) {

                unitVo.put("operationAgree","高成本 | 有转化");
                unitVo.put("operationContent","建议限制预算");
                unitVo.put("operationAgreeInfo","当前广告组成本大于出价×120%且转化数介于10-50之间;");
            }
            //3. 转化成本大于出价×120%，转化数大于50
            if (converCost > price * 1.2 && LinkUtil.isInTheInterval(String.valueOf(converNum), "(50,∞)")) {
                unitVo.put("operationAgree","高成本 | 有转化");
                unitVo.put("operationContent","建议降低出价");
                unitVo.put("operationAgreeInfo","当前转化成本大于出价×120%，转化数大于50，建议降低出价;");
            }
            //4.  转化成本小于等于出价×120%，转化数大于10小于等于50
            if (converCost <= price * 1.2 && LinkUtil.isInTheInterval(String.valueOf(converNum), "(10,50]")) {
                unitVo.put("operationAgree","成本合理 | 有转化");
                unitVo.put("operationContent","建议复制推广组或放开预算");
                unitVo.put("operationAgreeInfo","当前转化成本小于等于出价×120%，转化数大于10小于等于50，建议复制推广组或放开预算;");
            }
            //5.  消耗大于0小于等于100，转化数大于0小于等于10：
            if (LinkUtil.isInTheInterval(String.valueOf(charge), "(0,100]") && LinkUtil.isInTheInterval(String.valueOf(converNum), "(0,10]")) {
                unitVo.put("operationAgree","消耗少 | 转化少");
                unitVo.put("operationContent","建议启用加速探索");
                unitVo.put("operationAgreeInfo","当前广告组消耗大于0小于等于100，转化数大于0小于等于10，建议加速探索;");
            }
            //6.  消耗大于等于500，转化数等于0：
            if (charge >= 500 && converNum == 0) {
                unitVo.put("operationAgree","有消耗 | 无转化");
                unitVo.put("operationContent","建议暂停广告组");
                unitVo.put("operationAgreeInfo","当前广告组消耗大于等于500且转化数等于0，建议暂停推广组;");
            }
            //7.   消耗大于100小于等于500
            if (LinkUtil.isInTheInterval(String.valueOf(charge), "(100,500]")) {
                unitVo.put("operationAgree","有一定消耗");
                unitVo.put("operationContent","建议继续观察");
                unitVo.put("operationAgreeInfo","当前广告组消耗大于100小于等于500，建议继续观察;");
            }
        }



        PageInfo<JSONObject> pageInfo = new PageInfo<>(ListUnit);
        return Result.successMsg("查询快手组当天实时数据成功。",pageInfo);

    }


//===========================================查询下级员工========================

    public Result getCompanyAllSubordinateByUserId(String userId){
        Set<String> operatorUserIds = getAffiliateId(userId);
        return Result.successMsg("查询该用户所有下级userId",operatorUserIds);
    }





    /**
     * 查询当前人员  所属公司 返回自己和下属id
     */
    public Set<String> getAffiliateId(String userId) {

        //查询用户所属公司
        String companyId = materialStareMapper.getUserCompanyByUserId(userId);
        //查询用户角色
        String roleCode = materialStareMapper.getRoleCodeByUserId(userId);
        //管理员查询公司下所有用户
       /* if ("admin".equals(roleCode)) {
            return materialStareMapper.getCompanyAllUserId(companyId);
        }*/

        Set<String> result;
        //查询当前用户是否存在下级
        Set<String> subordinate = materialStareMapper.getAffiliateId(userId,companyId);
        if (subordinate.isEmpty()) {
            if ("admin".equals(roleCode)) {
                return materialStareMapper.getCompanyAllUserId(companyId);
            }
            subordinate.add(userId);
            return subordinate;
        } else {
            result = querySubordinate(subordinate, subordinate,companyId);
            result.add(userId);
        }
        return result;
    }

    //递归查询
    private Set<String> querySubordinate(Set<String> leaderIds, Set<String> result,String companyId) {
        if (leaderIds.isEmpty()) {
            return result;
        }
        Set<String> temp = materialStareMapper.querySubordinateRecursive(companyId,leaderIds);
        result.addAll(temp);
        querySubordinate(temp, result,companyId);
        return result;
    }
//===========================================查询下级员工========================



    //=========================查询下级的项目以及账户===============================================
    @Override
    public Result<List<JSONObject>> participateListByMediaIdAllSubordinate(JSONObject requestJson) {
        Result<List<JSONObject>> result = new Result<>();

        try {
            String userId = requestJson.getString("userId");
            if (Check.isNull(userId)) {
                throw new Exception("请选择userId");
            }

            //获取所有下级
            Set<String> userIds = getAffiliateId(userId);

            List<Integer> mediaIds = new ArrayList<>();
            String type = requestJson.getString("type");
            if (!Check.isNull(type)) {
                if ("kuaishou".equals(type)) {
                    mediaIds.add(2);
                    mediaIds.add(4);
                } else if ("bytedance".equals(type)) {
                    mediaIds.add(1);
                    mediaIds.add(3);
                }
            }
            //查询用户角色
            String roleCode = materialStareMapper.getRoleCodeByUserId(userId);
            //角色为 管理员 || 销售 || 媒介 查询全部
            if ("admin".equals(roleCode) || roleCode.contains("sale") || "meidaManager".equals(roleCode)) {
                userIds = null;
            }
            //查询项目信息以及广告主
            List<JSONObject> projectList = getProjectByUserIdAndMediaIdsSubordinate(userIds, mediaIds);
            List<JSONObject> haveList = new ArrayList<>();
            if (!Check.isNull(projectList)) {
                //项目id 查询账户人员信息
                Map<Long, List<JSONObject>> accountMap = getAccountListByProjectListSubordinate(userIds,projectList);
                for (int i = 0; i < projectList.size(); i++) {
                    JSONObject project = projectList.get(i);
                    if (!Check.isNull(project)) {
                        List<JSONObject> accountList = accountMap.get(project.getLong("projectId"));
                        if (!Check.isNull(accountList)) {
                            project.put("accountList", accountList);
                            haveList.add(project);
                        }
                    }
                }
            }
            result.setSuccess(true);
            result.setResult(haveList);
        } catch (Exception e) {
            e.printStackTrace();
            result.setSuccess(false);
            result.setMessage(e.getMessage());
        }
        return result;
    }

    public List<JSONObject> getProjectByUserIdAndMediaIdsSubordinate(Set<String> userIds, List<Integer> mediaIds) {
        return materialStareMapper.getProjectByUserIdAndMediaIdsSubordinate(userIds, mediaIds);
    }

    @Override
    public Map<Long, List<JSONObject>> getAccountListByProjectListSubordinate(Set<String> userIds,List<JSONObject> projectList) {
        Map<Long, List<JSONObject>> map = new HashMap<>();
        List list = new ArrayList();
        for (int i = 0; i < projectList.size(); i++) {
            JSONObject jsonObject = projectList.get(i);
            if (!Check.isNull(jsonObject)) {
                list.add(jsonObject.getLong("projectId"));
                map.put(jsonObject.getLong("projectId"), new ArrayList<>());
            }
        }
        List<JSONObject> jsonList = materialStareMapper.getAccountListByProjectListSubordinate(userIds,list);
        for (int i = 0; i < jsonList.size(); i++) {
            JSONObject jsonObject = jsonList.get(i);
            if (!Check.isNull(jsonObject)) {
                Long projectId = jsonObject.getLong("projectId");
                List<JSONObject> jsonObjects = map.get(projectId);
                jsonObjects.add(jsonObject);
            }
        }
        return map;
    }
    //=========================查询下级的项目以及账户===============================================



}
