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


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.DateUtils;
import org.jeecg.ctop.material.constants.*;
import org.jeecg.ctop.material.mapper.MaterialReportOverViewV3Mapper;
import org.jeecg.ctop.material.service.IMaterialReportOverViewV2Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MaterialReportOverViewV2ServiceImpl implements IMaterialReportOverViewV2Service {

    @Autowired
    private MaterialReportOverViewV3Mapper materialReportOverViewV3Mapper;

    /*@Autowired
    private ISysRoleService roleService;*/

    @Override
    public Set<String> recursiveQuerySubordinate(String userId) {
        Set<String> result;
        //查询当前用户是否存在下级
        Set<String> subordinate = materialReportOverViewV3Mapper.recursiveQuerySubordinateByLeader(userId);
        if (subordinate.isEmpty()) {
            subordinate.add(userId);
            return subordinate;
        } else {
            result = querySubordinate(subordinate, subordinate);
            result.add(userId);
        }
        return result;
    }

    /**
     * 查询快手/头条 设计组信息
     */
    @Override
    public List<JSONObject> getDesignTeamList(String userId, int mediaId) {
        String roleCode = materialReportOverViewV3Mapper.getRoleCodeByUserId(userId);
        List<JSONObject> designTeamList = new ArrayList<>();
        if ("admin".equals(roleCode)) {
            //管理员查询全部部门
            designTeamList = materialReportOverViewV3Mapper.getDesignTeamALLList();
        } else {
            designTeamList = materialReportOverViewV3Mapper.getDesignTeamList(userId);
        }

        if (designTeamList != null && !designTeamList.isEmpty()) {
            //判断是否默认选中
            for (JSONObject jsonObject : designTeamList) {
                String leaderId = jsonObject.getString("leaderId");
                if (leaderId != null && leaderId.equals(userId)) {
                    jsonObject.put("default", true);
                } else {
                    jsonObject.put("default", false);
                }
            }
        }
        return designTeamList;
    }

    @Override
    public Set<JSONObject> queryProjectBy(Set<String> userIds, int mediaId) {
        JSONArray mediaIds = new JSONArray();
        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
            mediaIds.add(1);
            mediaIds.add(3);
        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
            mediaIds.add(2);
            mediaIds.add(4);
        }
        return materialReportOverViewV3Mapper.queryProjectBy(userIds, mediaIds);
    }

    @Override
    public JSONArray queryProjectIdBy(Set<String> userIds, int mediaId) {
        JSONArray mediaIds = new JSONArray();
        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
            mediaIds.add(1);
            mediaIds.add(3);
        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
            mediaIds.add(2);
            mediaIds.add(4);
        }
        return materialReportOverViewV3Mapper.queryProjectIdBy(userIds, mediaIds);
    }

    @Override
    public Map<String, Object> getTotalModule(int mediaId, String startDate, String endDate, JSONArray projects, String dimension, String leaderId, String designerId, String userId) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String nowData = sdf.format(new Date());
        startDate = startDate.replace("-", "");
        endDate = endDate.replace("-", "");
        Map<String, Object> result = new HashMap<>();
        if (projects != null && projects.isEmpty()) {
            projects = getProjectsByCurrentUser(mediaId);
        }
        //根据userID查询公司id
        String companyId = materialReportOverViewV3Mapper.getCompanyId(userId);
        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
            //总消耗
            BigDecimal cost = materialReportOverViewV3Mapper.queryBytedanceCost(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
            //上阶段消耗
            BigDecimal lastCost = materialReportOverViewV3Mapper.queryBytedanceCost(Long.parseLong(DateUtils.addDayParse(startDate, -DateUtils.dateDiffParse(startDate, endDate) - 1)), Long.parseLong(DateUtils.addDayParse(startDate, -1)), projects, dimension, leaderId, designerId, companyId);
            result.put("costTotal", cost);
            //同比 （本阶段截止昨天消耗-上一个阶段截止和昨天对应日期的消耗）/上一个阶段截止和昨天对应日期的消耗 X 100%
            result.put("yearOnYearCompare", countLink(cost, lastCost));
            //昨日消耗
            BigDecimal yesterdayCost = materialReportOverViewV3Mapper.queryBytedanceCost(Long.parseLong(DateUtils.addDayParse(nowData, -1)), Long.parseLong(DateUtils.addDayParse(nowData, -1)), projects, dimension, leaderId, designerId, companyId);
            //前天消耗
            BigDecimal beforeYesterdayCost = materialReportOverViewV3Mapper.queryBytedanceCost(Long.parseLong(DateUtils.addDayParse(nowData, -2)), Long.parseLong(DateUtils.addDayParse(nowData, -2)), projects, dimension, leaderId, designerId, companyId);
            result.put("yesterdayCost", yesterdayCost);
            //环比 （昨日消耗-前日消耗）/前日消耗 X 100%
            result.put("chainCompare", countLink(yesterdayCost, beforeYesterdayCost));

        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
            //总消耗
            BigDecimal cost = materialReportOverViewV3Mapper.queryKuaishouCost(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
            //上阶段
            BigDecimal lastCost = materialReportOverViewV3Mapper.queryKuaishouCost(Long.parseLong(DateUtils.addDayParse(startDate, -DateUtils.dateDiffParse(startDate, endDate) - 1)), Long.parseLong(DateUtils.addDayParse(startDate, -1)), projects, dimension, leaderId, designerId, companyId);
            result.put("costTotal", cost);
            //同比 （本阶段截止昨天消耗-上一个阶段截止和昨天对应日期的消耗）/上一个阶段截止和昨天对应日期的消耗 X 100%
            result.put("yearOnYearCompare", countLink(cost, lastCost));
            //昨日消耗
            BigDecimal yesterdayCost = materialReportOverViewV3Mapper.queryKuaishouCost(Long.parseLong(DateUtils.addDayParse(nowData, -1)), Long.parseLong(DateUtils.addDayParse(nowData, -1)), projects, dimension, leaderId, designerId, companyId);
            //前天消耗
            BigDecimal beforeYesterdayCost = materialReportOverViewV3Mapper.queryKuaishouCost(Long.parseLong(DateUtils.addDayParse(nowData, -2)), Long.parseLong(DateUtils.addDayParse(nowData, -2)), projects, dimension, leaderId, designerId, companyId);
            result.put("yesterdayCost", yesterdayCost);
            //日环比 （昨日消耗-前日消耗）/前日消耗 X 100%
            result.put("chainCompare", countLink(yesterdayCost, beforeYesterdayCost));
        }
        return result;
    }


    @Override
    public Map<String, Object> sumDataVideoNewEffective(int mediaId, String startDate, String endDate, JSONArray projects, String dimension, String leaderId, String designerId, String userId) {
        Map<String, Object> result = new HashMap<>();
        if (projects != null && projects.isEmpty()) {
            projects = getProjectsByCurrentUser(mediaId);
        }
        //根据userID查询公司id
        String companyId = materialReportOverViewV3Mapper.getCompanyId(userId);
        startDate = startDate.replace("-", "");
        endDate = endDate.replace("-", "");


        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
            //视频上新
            List<Map<String, String>> videoList = materialReportOverViewV3Mapper.queryMaterialCountList(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
            //总数
            long videoTotal = videoList.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
            result.put("videoList", videoList);
            result.put("videoTotal", videoTotal);
            //素材使用率 = 有消耗的素材 / 总数 * 100%
            long videoCost = materialReportOverViewV3Mapper.queryMaterialCostList(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
            result.put("useCompare", Check.isNull(videoCost) ? 0 : new BigDecimal(videoCost).divide(new BigDecimal(videoTotal), 4, RoundingMode.HALF_UP));
            //有效视频
            List<Map<String, String>> effectiveList = materialReportOverViewV3Mapper.selectEffectiveMaterialVideoBytedance(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), projects, dimension, leaderId, designerId, companyId);
            //总数
            long effectiveTotal = effectiveList.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
            result.put("effectiveList", effectiveList);
            result.put("effectiveTotal", effectiveTotal);
            //素材有效率 = 有效视频数量 / 视频总数 X 100%
            result.put("effectiveCompare", Check.isNull(videoCost) ? 0 : new BigDecimal(effectiveTotal).divide(new BigDecimal(videoTotal), 4, RoundingMode.HALF_UP));

        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {

            //视频上新
            List<Map<String, String>> videoList = materialReportOverViewV3Mapper.queryMaterialCountListKs(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
            //总数
            long videoTotal = videoList.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
            result.put("videoList", videoList);
            result.put("videoTotal", videoTotal);
            //素材使用率 = 有消耗的素材 / 总数 * 100%
            long videoCost = materialReportOverViewV3Mapper.queryMaterialCostListKs(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), projects, dimension, leaderId, designerId, companyId);
            result.put("useCompare", Check.isNull(videoCost) ? 0 : new BigDecimal(videoCost).divide(new BigDecimal(videoTotal), 4, RoundingMode.HALF_UP));
            //有效视频
            List<Map<String, String>> effectiveList = materialReportOverViewV3Mapper.selectEffectiveMaterialVideoKs(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), projects, dimension, leaderId, designerId, companyId);
            //总数
            long effectiveTotal = effectiveList.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
            result.put("effectiveList", effectiveList);
            result.put("effectiveTotal", effectiveTotal);
            //素材有效率 = 有效视频数量 / 视频总数 X 100%
            result.put("effectiveCompare", Check.isNull(videoTotal) ? 0 : new BigDecimal(effectiveTotal).divide(new BigDecimal(videoTotal), 4, RoundingMode.HALF_UP));

        }
        return result;
    }

    //爆款视频
    @Override
    public Map<String, Object> sumDataVideoHot(int mediaId, String startDate, String endDate, JSONArray projects, String dimension, String leaderId, String designerId, String userId, int type) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String nowData = sdf.format(new Date());
        Map<String, Object> result = new HashMap<>();
        if (projects != null && projects.isEmpty()) {
            projects = getProjectsByCurrentUser(mediaId);
        }
        //根据userID查询公司id
        String companyId = materialReportOverViewV3Mapper.getCompanyId(userId);
        startDate = startDate.replace("-", "");
        endDate = endDate.replace("-", "");
        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
            //爆款视频
            List<Map<String, String>> hotList = materialReportOverViewV3Mapper.selectHotMaterialVideoBytedance(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId, type);
            //总数
            long hotTotal = hotList.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
            result.put("hotList", hotList);
            result.put("hotTotal", hotTotal);
           /* //上阶段
            List<Map<String, String>> lastHostList = materialReportOverViewV3Mapper.selectHotMaterialVideoBytedance(Long.parseLong(DateUtils.addDayParse(startDate, -DateUtils.dateDiffParse(startDate, endDate) - 1)), Long.parseLong(DateUtils.addDayParse(startDate, -1)), projects, dimension, leaderId, designerId, companyId, type);
            long lastHotTotal = lastHostList.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
            //同比 （本阶段截止昨天的爆款视频数量-上一个阶段截止和昨天对应日期的爆款视频数量）/上一个阶段截止和昨天对应日期的爆款视频数量X 100%
            result.put("hotYearOnYearCompare", countLink(new BigDecimal(hotTotal), new BigDecimal(lastHotTotal)));
            //昨日消耗
            List<Map<String, String>> yesterdayHost = materialReportOverViewV3Mapper.selectHotMaterialVideoBytedance(Long.parseLong(DateUtils.addDayParse(nowData, -1)), Long.parseLong(DateUtils.addDayParse(nowData, -1)), projects, dimension, leaderId, designerId, companyId, type);
            //前天消耗
            List<Map<String, String>> beforeYesterdayHost = materialReportOverViewV3Mapper.selectHotMaterialVideoBytedance(Long.parseLong(DateUtils.addDayParse(nowData, -2)), Long.parseLong(DateUtils.addDayParse(nowData, -2)), projects, dimension, leaderId, designerId, companyId, type);
            long yesterday = yesterdayHost.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
            long before = beforeYesterdayHost.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
            //日环比 （昨日-前日）/前日消耗 X 100%
            result.put("hostCompare", countLink(new BigDecimal(yesterday), new BigDecimal(before)));*/

        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
            //爆款视频
            List<Map<String, String>> hotList = materialReportOverViewV3Mapper.selectHotMaterialVideoKs(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId, type);
            //总数
            long hotTotal = hotList.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
            result.put("hotList", hotList);
            result.put("hotTotal", hotTotal);
         /*   //上阶段
            List<Map<String, String>> lastHostList = materialReportOverViewV3Mapper.selectHotMaterialVideoKs(Long.parseLong(DateUtils.addDayParse(startDate, -DateUtils.dateDiffParse(startDate, endDate) - 1)), Long.parseLong(DateUtils.addDayParse(startDate, -1)), projects, dimension, leaderId, designerId, companyId, type);
            long lastHotTotal = lastHostList.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
            //同比 （本阶段截止昨天的爆款视频数量-上一个阶段截止和昨天对应日期的爆款视频数量）/上一个阶段截止和昨天对应日期的爆款视频数量X 100%
            result.put("hotYearOnYearCompare", countLink(new BigDecimal(hotTotal), new BigDecimal(lastHotTotal)));
            //昨日消耗
            List<Map<String, String>> yesterdayHost = materialReportOverViewV3Mapper.selectHotMaterialVideoKs(Long.parseLong(DateUtils.addDayParse(nowData, -1)), Long.parseLong(DateUtils.addDayParse(nowData, -1)), projects, dimension, leaderId, designerId, companyId, type);
            //前天消耗
            List<Map<String, String>> beforeYesterdayHost = materialReportOverViewV3Mapper.selectHotMaterialVideoKs(Long.parseLong(DateUtils.addDayParse(nowData, -2)), Long.parseLong(DateUtils.addDayParse(nowData, -2)), projects, dimension, leaderId, designerId, companyId, type);
            long yesterday = yesterdayHost.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
            long before = beforeYesterdayHost.stream().collect(Collectors.summarizingInt(s -> Integer.valueOf(String.valueOf(s.get("count"))))).getSum();
            //日环比 （昨日-前日）/前日消耗 X 100%
            result.put("hostCompare", countLink(new BigDecimal(yesterday), new BigDecimal(before)));*/
        }
        return result;
    }


    @Override
    public List<JSONObject> getTotalChat(int mediaId, String startDate, String endDate, JSONArray projects, String dimension, String leaderId, String designerId, String userId) {
        List<JSONObject> result = new ArrayList<>();
        if (projects != null && projects.isEmpty()) {
            projects = getProjectsByCurrentUser(mediaId);
        }
        //根据userID查询公司id
        String companyId = materialReportOverViewV3Mapper.getCompanyId(userId);
        startDate = startDate.replace("-", "");
        endDate = endDate.replace("-", "");
        try {
            if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
                if (DateUtils.isMoreSixMonthParse(startDate, endDate)) {
                    result = materialReportOverViewV3Mapper.queryBytedanceChatGroupMonth(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
                } else {
                    result = materialReportOverViewV3Mapper.queryBytedanceChat(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
                }
            } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
                if (DateUtils.isMoreSixMonthParse(startDate, endDate)) {
                    result = materialReportOverViewV3Mapper.queryKuaishouChatGroupMonth(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
                } else {
                    result = materialReportOverViewV3Mapper.queryKuaishouChat(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
                }
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }

    @Override
    public JSONObject getTagProportion(int mediaId, String startDate, String endDate, int tagId) {
        return null;
    }

    @Override
    public List<JSONObject> getTopMaterialList(int mediaId, String startDate, String endDate, JSONArray projects, String dimension, String leaderId, String designerId, String userId, Integer channelType) {
        List<JSONObject> result = new ArrayList<>();
        //根据userID查询公司id
        String companyId = materialReportOverViewV3Mapper.getCompanyId(userId);
        startDate = startDate.replace("-", "");
        endDate = endDate.replace("-", "");
        if (projects != null && projects.isEmpty()) {
            projects = getProjectsByCurrentUser(mediaId);
        }

        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
            result = materialReportOverViewV3Mapper.queryBytedanceTopMaterial(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);

        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
            result = materialReportOverViewV3Mapper.queryKuaishouTopMaterial(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId, channelType);
        }
        return result;
    }

    @Override
    public PageInfo<JSONObject> getTopMaterialList(Integer mediaId, String startDate, String endDate, JSONArray projects, String userId, String md5, String dimension, String leaderId, String designerId, Integer materialQuality, Integer materialType, Integer innovative, String target, String order, Integer pageNo, Integer pageSize) {
        PageInfo<JSONObject> result = new PageInfo<>();
        if (projects != null && projects.isEmpty()) {
            projects = getProjectsByCurrentUser(mediaId);
        }
        //根据userID查询公司id
        String companyId = materialReportOverViewV3Mapper.getCompanyId(userId);
        startDate = startDate.replace("-", "");
        endDate = endDate.replace("-", "");
        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
            String filedAll = JsonResourceUtil.joinAllFiled(AccountReportConstants.getDicMapByVideoNew());
            PageHelper.startPage(pageNo, pageSize);
            List<JSONObject> list = materialReportOverViewV3Mapper.queryBytedanceMaterialReport(filedAll, Long.parseLong(startDate), Long.parseLong(endDate), projects, md5, dimension, leaderId, designerId, materialQuality, materialType, innovative, target, order, companyId);
            result = new PageInfo(list);
        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
            String filedAll = JsonResourceUtil.joinAllFiled(AccountReportConstants.getKuaishouVideoReportMapNew());
            PageHelper.startPage(pageNo, pageSize);
            List<JSONObject> list = materialReportOverViewV3Mapper.queryKuaishouMaterialReport(filedAll, Long.parseLong(startDate), Long.parseLong(endDate), projects, md5, dimension, leaderId, designerId, materialQuality, materialType, innovative, target, order, companyId);
            result = new PageInfo(list);
        }
        return result;
    }

    @Override
    public void exportBytedanceExcel(JSONObject requestBody, HttpServletRequest request, HttpServletResponse response) {
        JSONArray projects = requestBody.getJSONArray("projects");
        if (projects != null && projects.isEmpty()) {
            projects = getProjectsByCurrentUser(requestBody.getInteger("mediaId"));
        }
        JSONArray columns = requestBody.getJSONArray("columns");
        if (columns.isEmpty()) {
            //默认消耗必查
            columns.add("cost");
        }

        String filed = JsonResourceUtil.joinAllFiled(AccountReportConstants.getDicMapByVideoNew());
        List<String> titles = new ArrayList<>(JsonResourceUtil.joinTitle(AccountReportConstants.getDicMapByVideo(), columns));

        titles.add(0, "唯一标识");
        titles.add(1, "视频");
        titles.add(2, "视频名称");
        titles.add(3, "项目名称");
        columns.add(0, "signature");
        columns.add(1, "url");
        columns.add(2, "materialName");
        columns.add(3, "projectName");
        String companyId = materialReportOverViewV3Mapper.getCompanyId(requestBody.getString("userId"));
        List<JSONObject> excelData = materialReportOverViewV3Mapper.queryBytedanceMaterialReport(filed,
                Long.parseLong(requestBody.getString("startDate").replace("-", "")),
                Long.parseLong(requestBody.getString("endDate").replace("-", "")),
                projects,
                requestBody.getString("md5"),
                requestBody.getString("dimension"),
                requestBody.getString("leaderId"),
                requestBody.getString("designerId"),
                requestBody.getInteger("materialQuality"),
                requestBody.getInteger("materialType"),
                requestBody.getInteger("innovative"),
                requestBody.getString("target") == null ? "cost" : requestBody.getString("target"),
                requestBody.getString("order") == null ? "desc" : requestBody.getString("order"), companyId);

        if (null != excelData && excelData.isEmpty()) {
            return;
        }
        List<List<Object>> excelList = new ArrayList<>();
        excelData.forEach(data -> {
            List<Object> temp = new ArrayList<>();
            columns.forEach(k -> {
                temp.add(data.get(k.toString()));
            });
            excelList.add(temp);
        });
        try {
            String[] headers = titles.toArray(new String[titles.size()]);
            OutputStream os = response.getOutputStream();
            ExportExcelUtils eeu = new ExportExcelUtils();
            XSSFWorkbook workbook = new XSSFWorkbook();
            eeu.exportExcel(workbook, 0, "头条视频报表", headers, excelList);
            HttpUtils.setResponseHeader(response, "头条视频报表.xlsx");
            workbook.write(os);
            os.flush();
            os.close();
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }

    @Override
    public void exportKuaishouExcel(JSONObject requestBody, HttpServletRequest request, HttpServletResponse response) {
        JSONArray projects = requestBody.getJSONArray("projects");
        if (projects != null && projects.isEmpty()) {
            projects = getProjectsByCurrentUser(requestBody.getInteger("mediaId"));
        }
        JSONArray columns2 = new JSONArray();
        columns2.add(0, "signature");
        columns2.add(1, "url");
        columns2.add(2, "projectName");
        columns2.add(3, "materialName");
        JSONArray columns = requestBody.getJSONArray("columns");
        for (int i = 0; i < columns.size(); i++) {
            columns2.add(columns2.size(), columns.getString(i));
        }
        List<String> titles = getfileIds(AccountReportConstants.getKuaishouVideoReportDict(), columns2);
        String filedAll = JsonResourceUtil.joinAllFiled(AccountReportConstants.getKuaishouVideoReportMapNew());
        String companyId = materialReportOverViewV3Mapper.getCompanyId(requestBody.getString("userId"));
        List<JSONObject> excelData = materialReportOverViewV3Mapper.queryKuaishouMaterialReport(filedAll,
                Long.parseLong(requestBody.getString("startDate").replace("-", "")),
                Long.parseLong(requestBody.getString("endDate").replace("-", "")),
                projects,
                requestBody.getString("md5"),
                requestBody.getString("dimension"),
                requestBody.getString("leaderId"),
                requestBody.getString("designerId"),
                requestBody.getInteger("materialQuality"),
                requestBody.getInteger("materialType"),
                requestBody.getInteger("innovative"),
                requestBody.getString("target") == null ? "cost" : requestBody.getString("target"),
                requestBody.getString("order") == null ? "desc" : requestBody.getString("order"), companyId);
        if (null != excelData && excelData.isEmpty()) {
            return;
        }
        List<List<Object>> excelList = new ArrayList<>();
        for (int i = 0; i < excelData.size(); i++) {
            List<Object> temp = new ArrayList<>();
            JSONObject jsonObject = excelData.get(i);
            for (int j = 0; j < columns2.size(); j++) {
                String key = columns2.getString(j);
                String value = jsonObject.getString(key);
                temp.add(value);
            }
            excelList.add(temp);
        }

        try {
            String[] strings = titles.toArray(new String[]{});
            OutputStream os = response.getOutputStream();
            ExportExcelUtils eeu = new ExportExcelUtils();
            XSSFWorkbook workbook = new XSSFWorkbook();
            eeu.exportExcel(workbook, 0, "快手素材报表", strings, excelList);
            HttpUtils.setResponseHeader(response, "快手素材.xlsx");
            workbook.write(os);
            os.flush();
            os.close();
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }

    @Override
    public PageInfo getTopDesignList(Integer mediaId, String startDate, String endDate, String userId, Integer type, int pageNumber, int pageSize) {

        startDate = startDate.replace("-", "");
        endDate = endDate.replace("-", "");
        List<JSONObject> result = new ArrayList<>();
        int total = 0;
        int page = pageNumber;
        //根据userID查询公司id
        String companyId = materialReportOverViewV3Mapper.getCompanyId(userId);
        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
            total =materialReportOverViewV3Mapper.queryBytedanceTopDesign(Long.parseLong(startDate), Long.parseLong(endDate), type, companyId).size();
            PageHelper.startPage(pageNumber, pageSize, false);
            // 查询头条设计排行
            result = materialReportOverViewV3Mapper.queryBytedanceTopDesign(Long.parseLong(startDate), Long.parseLong(endDate), type, companyId);

        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
            total =materialReportOverViewV3Mapper.queryKuaishouTopDesign(Long.parseLong(startDate), Long.parseLong(endDate), type, companyId).size();
            PageHelper.startPage(pageNumber, pageSize, false);
            //查询快手设计排行版
            result = materialReportOverViewV3Mapper.queryKuaishouTopDesign(Long.parseLong(startDate), Long.parseLong(endDate), type, companyId);

        }
        int number = (page - 1) * 10 + 1;
        for (JSONObject jsonObject : result) {
            jsonObject.put("number", number);
            number++;
        }
        PageInfo info = new PageInfo(result);
        info.setTotal(total);
        return info;
    }

    @Override
    public JSONObject getMaterialDetailInfo(int mediaId, String md5) {
        JSONObject result = new JSONObject();
        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
            result = materialReportOverViewV3Mapper.queryBytedanceVideoDetail(md5);
        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
            result = materialReportOverViewV3Mapper.queryKuaishouVideoDetail(md5);

        }
        return result;
    }

    @Override
    public Map<String, Object> materialDetailAnalyse(int mediaId, String md5) {
        Map<String, Object> result = new HashMap<>();
        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
            Long projectId = materialReportOverViewV3Mapper.queryBytedanceProjectIdByMd5(md5);
            result.put("cost", materialReportOverViewV3Mapper.queryBytedanceCostByMd5(md5, projectId));
            result.put("click", materialReportOverViewV3Mapper.queryBytedanceClickByMd5(md5, projectId));
            result.put("materialShow", materialReportOverViewV3Mapper.queryBytedanceMaterialShowByMd5(md5, projectId));
            result.put("play100Rate", materialReportOverViewV3Mapper.queryBytedancePlay100RateByMd5(md5, projectId));
            result.put("likeMaterial", materialReportOverViewV3Mapper.queryBytedanceLikeMaterialByMd5(md5, projectId));
            result.put("commentMaterial", materialReportOverViewV3Mapper.queryBytedanceCommentMaterialByMd5(md5, projectId));
            result.put("shareMaterial", materialReportOverViewV3Mapper.queryBytedanceShareMaterialByMd5(md5, projectId));
            result.put("follow", materialReportOverViewV3Mapper.queryBytedanceFollowByMd5(md5, projectId));
        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
            Long projectId = materialReportOverViewV3Mapper.queryKuaishouProjectIdByMd5(md5);
            result.put("charge", materialReportOverViewV3Mapper.queryKuaishouChargeByMd5(md5, projectId));
            result.put("photoShow", materialReportOverViewV3Mapper.queryKuaishouPhotoShowByMd5(md5, projectId));
            result.put("photoClick", materialReportOverViewV3Mapper.queryKuaishouPhotoClickByMd5(md5, projectId));
            result.put("aclick", materialReportOverViewV3Mapper.queryKuaishouAClickByMd5(md5, projectId));
            result.put("bclick", materialReportOverViewV3Mapper.queryKuaishouBClickByMd5(md5, projectId));
            result.put("activation", materialReportOverViewV3Mapper.queryKuaishouActivationByMd5(md5, projectId));
            result.put("play3sRate", materialReportOverViewV3Mapper.queryKuaishouPlay3sRateByMd5(md5, projectId));
        }
        return result;
    }

    @Override
    public List<JSONObject> getMaterialDetailChat(int mediaId, String md5) {
        List<JSONObject> result = new ArrayList<>();
        List<JSONObject> data = new ArrayList<>();
        List<String> monthBetween = new ArrayList<>();
        Map<String, JSONObject> map = new HashMap<>();
        try {
            if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
                result = materialReportOverViewV3Mapper.queryBytedanceVideoChat(md5);
            } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
                result = materialReportOverViewV3Mapper.queryKuaishouVideoChat(md5);
            }
            //获取最小日期和最大日期 计算中间无数据日期 填充0
            if (result != null && result.size() > 0) {
                JSONObject first = result.get(0);
                JSONObject last = result.get(result.size() - 1);
                String startDate = first.get("statDate") == null ? null : (String) first.get("statDate");
                String endDate = last.get("statDate") == null ? null : (String) last.get("statDate");
                if (startDate != null && endDate != null) {
                    monthBetween = getMonthBetween(startDate, endDate);
                    log.info(":{}", monthBetween.size());
                }
                for (JSONObject jsonObject : result) {
                    String date = jsonObject.get("statDate") == null ? null : (String) jsonObject.get("statDate");
                    if (date != null) {
                        map.put(date, jsonObject);
                    }
                }
                for (String date : monthBetween) {
                    if (map.get(date) != null) {
                        data.add(map.get(date));
                    } else {
                        JSONObject dataMap = new JSONObject();
                        dataMap.put("statDate", date);
                        dataMap.put("cost", 0);
                        dataMap.put("aclick", 0);
                        dataMap.put("activation", 0);
                        data.add(dataMap);
                    }
                }
            }


        } catch (Exception e) {
            log.info("查询数据错误:{}", e.toString());
        }
        return data;
    }

    private static List<String> getMonthBetween(String minDate, String maxDate) throws ParseException {
        ArrayList<String> result = new ArrayList<String>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");//格式化为年月

        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();

        min.setTime(sdf.parse(minDate));
        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

        max.setTime(sdf.parse(maxDate));
        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

        Calendar curr = min;
        while (curr.before(max)) {
            result.add(sdf.format(curr.getTime()));
            curr.add(Calendar.MONTH, 1);
        }

        return result;
    }

    /**
     * 查询人群分析数据列表
     *
     * @param
     * @return
     */
    @Override
    public Result populationAnalysisList(String signature) {
        Result result = new Result<>();
        Map resultMap = new HashMap();
        try {
            List<Map> list = materialReportOverViewV3Mapper.populationAnalysisList(signature);
            //查询点击率
            String actionRatio = materialReportOverViewV3Mapper.getActualProb(signature, "action_ratio");
            //查询转化率
            String convertRatio = materialReportOverViewV3Mapper.getActualProb(signature, "convert_ratio");
            resultMap.put("dataList", list);
            resultMap.put("actionRatio", actionRatio);
            resultMap.put("convertRatio", convertRatio);
            result.setSuccess(true);
            result.setResult(resultMap);
        } catch (Exception e) {
            log.info("查询错误:{}", e.toString());
            result.error500("查询错误");
        }
        return result;
    }

    /**
     * 查询人群分析数据图
     *
     * @param
     * @return
     */
    @Override
    public Result populationAnalysisChart(String signature) {
        Result result = new Result<>();
        try {
            List<Map> list = materialReportOverViewV3Mapper.populationAnalysisChart(signature);
            result.setResult(list);
        } catch (Exception e) {
            log.info("查询错误:{}", e.toString());
            result.error500("查询错误");
        }
        return result;
    }

    /**
     * 最优定向组合
     *
     * @param
     * @return
     */
    @Override
    public Result optimalCombination(String signature) {
        Result result = new Result<>();
        Map<String, String> map = new HashMap();
        try {
            //最优转化率组合
            Map<String, String> convertRatio = materialReportOverViewV3Mapper.optimalCombination(signature, "convert_ratio");
            //最优点击率组合
            Map<String, String> actionRatio = materialReportOverViewV3Mapper.optimalCombination(signature, "action_ratio");
            if (convertRatio != null) {
                map.put("convertRatio", convertRatio.get("gender") + "/" + convertRatio.get("age"));
            } else {
                map.put("convertRatio", null);
            }
            if (actionRatio != null) {
                map.put("actionRatio", actionRatio.get("gender") + "/" + actionRatio.get("age"));
            } else {
                map.put("actionRatio", null);
            }

            result.setResult(map);
        } catch (Exception e) {
            log.info("查询错误:{}", e.toString());
            result.error500("查询错误");
        }
        return result;
    }

    /**
     * 相似素材
     *
     * @param
     * @return
     */
    @Override
    public Result similarMaterial(String signature) {
        Result result = new Result<>();
        List<Map> resultMap = new ArrayList<>();
        Map<String, String> map = materialReportOverViewV3Mapper.getSimilarMaterialList(signature);
        if (map != null) {
            String signature1 = map.get("s1");
            String signature2 = map.get("s2");
            String signature3 = map.get("s3");
            String signature4 = map.get("s4");
            String signature5 = map.get("s5");
            if (signature1 != null && !signature1.equals("")) {
                Map info = materialReportOverViewV3Mapper.similarMaterialInfo(signature1);
                if (info.get("signature") != null && !info.get("signature").equals("")) {
                    resultMap.add(info);
                }
            }
            if (signature2 != null && !signature2.equals("")) {
                Map info = materialReportOverViewV3Mapper.similarMaterialInfo(signature2);
                if (info.get("signature") != null && !info.get("signature").equals("")) {
                    resultMap.add(info);
                }
            }
            if (signature3 != null && !signature3.equals("")) {
                Map info = materialReportOverViewV3Mapper.similarMaterialInfo(signature3);
                if (info.get("signature") != null && !info.get("signature").equals("")) {
                    resultMap.add(info);
                }
            }
            if (signature4 != null && !signature4.equals("")) {
                Map info = materialReportOverViewV3Mapper.similarMaterialInfo(signature4);
                if (info.get("signature") != null && !info.get("signature").equals("")) {
                    resultMap.add(info);
                }
            }
            if (signature5 != null && !signature5.equals("")) {
                Map info = materialReportOverViewV3Mapper.similarMaterialInfo(signature5);
                if (info.get("signature") != null && !info.get("signature").equals("")) {
                    resultMap.add(info);
                }
            }
        }
        result.setResult(resultMap);
        return result;
    }

    /**
     * 设计组维度:组内人均消耗等指标
     * mediaId 类型 1-头条 2-快手
     */
    @Override
    public Map<String, Object> getDesignerAvgData(Integer mediaId, String startDate, String endDate, String userId, String leaderId) {
        //根据userID查询公司id
        String companyId = materialReportOverViewV3Mapper.getCompanyId(userId);
        Map<String, Object> result = new HashMap<>();
        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
            //头条
            //组内人均消耗
            BigDecimal sumCost = materialReportOverViewV3Mapper.getBytedanceDesignTeamAvgCost(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), leaderId, companyId);
            //组人效
            BigDecimal groupWork = materialReportOverViewV3Mapper.getBytedanceDesignTeamGroupWork(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), leaderId, companyId);
            //创新视频数
            int innovativeVideoCount = materialReportOverViewV3Mapper.getBytedanceDesignTeaminnovativeVideoCount(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), leaderId, companyId);
            //素材平均消耗
            BigDecimal avgCost = materialReportOverViewV3Mapper.getBytedanceMaterialCost(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), leaderId, companyId);

            result.put("avgCost", sumCost);
            result.put("peopleWork", groupWork);
            result.put("innovativeVideoCount", innovativeVideoCount);
            result.put("avgMaterialCost", avgCost);
        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
            //快手
            //组内人均消耗
            BigDecimal sumCost = materialReportOverViewV3Mapper.getKuaishouDesignTeamAvgCost(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), leaderId, companyId);
            //组人效
            BigDecimal groupWork = materialReportOverViewV3Mapper.getKuaishouDesignTeamGroupWork(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), leaderId, companyId);
            //创新视频数
            int innovativeVideoCount = materialReportOverViewV3Mapper.getKuaishouDesignTeaminnovativeVideoCount(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), leaderId, companyId);
            //创新视频消耗
            BigDecimal innovativeVideoCost = materialReportOverViewV3Mapper.getKuaishouDesignTeaminnovativeVideoCost(Long.parseLong(startDate.replace("-", "")), Long.parseLong(endDate.replace("-", "")), leaderId, companyId);
            result.put("avgCost", sumCost);
            result.put("peopleWork", groupWork);
            result.put("innovativeVideoCount", innovativeVideoCount);
            result.put("innovativeVideoCost", innovativeVideoCost);
        }
        return result;
    }

    /**
     * 标签占比
     */
    @Override
    public JSONObject labelRatio(Integer mediaId, String startDate, String endDate, JSONArray projects, String dimension, String leaderId, String designerId, String userId, int type) {
        //根据userID查询公司id
        String companyId = materialReportOverViewV3Mapper.getCompanyId(userId);
        Map<String, Object> result = new HashMap<>();
        JSONObject object = new JSONObject();
        if (projects != null && projects.isEmpty()) {
            projects = getProjectsByCurrentUser(mediaId);
        }
        startDate = startDate.replace("-", "");
        endDate = endDate.replace("-", "");
        if (mediaId == CtopAdConstant.PLATFORM_TYPE_BYTEDANCE_INT) {
            //头条
            if (type == 0) {
                //素材数
                //获取真人 制作 其他 数量
                object = materialReportOverViewV3Mapper.getBytedanceMaterialCountByLable(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);

            } else if (type == 1) {
                //消耗
                //获取真人 制作 其他 数量
                object = materialReportOverViewV3Mapper.getBytedanceMaterialCountByCost(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
            }

        } else if (mediaId == CtopAdConstant.PLATFORM_TYPE_KUAISHOU_INT) {
            //快手
            if (type == 0) {
                //素材数
                //获取真人 制作 其他 数量
                object = materialReportOverViewV3Mapper.getKuaishouMaterialCountByLable(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
            } else if (type == 1) {
                //消耗
                //获取真人 制作 其他 数量
                object = materialReportOverViewV3Mapper.getKuaishouMaterialCountByCost(Long.parseLong(startDate), Long.parseLong(endDate), projects, dimension, leaderId, designerId, companyId);
            }
        }

        return object;
    }

    /**
     * 判断是否有设计组权限
     *
     * @param
     * @return
     */
    @Override
    public Result getRole(String userId) {
        Map map = new HashMap();
        Result result = new Result<>();
        String roleCode = materialReportOverViewV3Mapper.getRoleCodeByUserId(userId);
        map.put("role", roleCode);
        if ("admin".equals(roleCode) || "designTeamLeader".equals(roleCode)) {
            map.put("permissions", true);
        } else {
            map.put("permissions", false);
        }
        result.setResult(map);
        return result;
    }


    //递归查询
    private Set<String> querySubordinate(Set<String> leaderIds, Set<String> result) {
        if (leaderIds.isEmpty()) {
            return result;
        }
        Set<String> temp = materialReportOverViewV3Mapper.recursiveQuerySubordinateByLeaders(leaderIds);
        result.addAll(temp);
        querySubordinate(temp, result);
        return result;
    }

    //当项目为空的时候，根据当前登录人查询可查看的所有项目集合
    private JSONArray getProjectsByCurrentUser(int mediaId) {
        //String currentUser = ((LoginUser) SecurityUtils.getSubject().getPrincipal()).getId();
        String currentUser = "e9ca23d68d884d4ebb19d07889727dae";
        //TODO 为了解决管理员等角色初始化查全部项目查询效率慢的问题判断角色，待优化
        String roleCode = materialReportOverViewV3Mapper.getRoleCodeByUserId(currentUser);
        if ("admin".equals(roleCode)) {
            return null;
        }
        return Check.isNull(queryProjectIdBy(recursiveQuerySubordinate(currentUser), mediaId)) ? null : queryProjectIdBy(recursiveQuerySubordinate(currentUser), mediaId);
    }

    private List<String> getfileIds(Map<String, Map<String, Object>> kuaishouVideoReportMap, JSONArray columns) {
        List<String> titles = new ArrayList<>();
        for (int i = 0; i < columns.size(); i++) {
            String string = columns.getString(i);
            Map<String, Object> stringObjectMap = kuaishouVideoReportMap.get(string);
            if (Check.isNull(stringObjectMap)) {
                titles.add("-");
                continue;
            }
            Object comment = stringObjectMap.get("comment");
            titles.add(String.valueOf(comment));

        }
        return titles;
    }

    //环比计算
    private BigDecimal countLink(BigDecimal numA, BigDecimal numB) {
        BigDecimal link = new BigDecimal("0");
        if (Check.isNull(numA) || Check.isNull(numB)) {
            return link;
        }
        if (numB.compareTo(BigDecimal.ZERO) != 0) {
            link = (numA.subtract(numB)).divide(numB, 4, RoundingMode.HALF_UP);
        }
        return link;
    }


    /**
     * 同比 (当前 - 上阶段 ） / 上阶段
     *
     * @param current 当前阶段数值
     * @param last    上阶段数值
     * @return
     */
    private BigDecimal yearOnYearCompare(BigDecimal current, BigDecimal last) {
        BigDecimal yearOnYear = new BigDecimal("0");
        if (last.compareTo(BigDecimal.ZERO) != 0) {
            // (当前 - 上阶段 ） / 上阶段
            yearOnYear = (current.subtract(last)).divide(last, 20, BigDecimal.ROUND_HALF_UP);
        }
        return yearOnYear;
    }


}
