package cn.com.ctop.toutiao.modules.report.controller;

import cn.com.ctop.common.module.entity.CtopOauthToken;
import cn.com.ctop.common.module.service.ICtopOauthTokenService;
import cn.com.ctop.common.module.utils.HttpUtils;
import cn.com.ctop.common.module.vo.ByteDanceReportAccountDailyDTOEntity;
import cn.com.ctop.common.module.vo.SheetInfoVo;
import cn.com.ctop.toutiao.modules.report.DTO.ByteDanceReportAccountDailyDTO;
import cn.com.ctop.toutiao.modules.report.DTO.BytedanceInfoDTO;
import cn.com.ctop.toutiao.modules.report.entity.BytedanceReportMaterialRetry;
import cn.com.ctop.toutiao.modules.report.service.IByteDanceVideoReportDailyService;
import cn.com.ctop.toutiao.modules.report.service.IBytedanceAccountReportService;
import cn.com.ctop.toutiao.modules.report.service.IBytedanceReportService;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
@RestController
@RequestMapping("/ctop/report")
public class BytedanceReportController {
    @Autowired
    private IBytedanceReportService bytedanceReportService;
    @Autowired
    private ICtopOauthTokenService tokenService;
    @Autowired
    private IByteDanceVideoReportDailyService byteDanceVideoReportDailyService;
    @Autowired
    private IBytedanceAccountReportService bytedanceAccountReportService;

    @PostMapping("/kuaiShou/accountReport")
    public Result<JSONObject> getKuaiShouAccountReport(@RequestBody JSONObject requestJson) {
        Result<JSONObject> result = new Result<>();
        try {
            JSONObject json = bytedanceReportService.getKuaiShouAccountReport(requestJson);
            result.setResult(json);
            result.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            result.setSuccess(false);
        }
        return result;
    }


    @PostMapping("/kuaiShou/accountDetailReport")
    public Result<List<JSONObject>> getKuaiShouAccountDetailReport(@RequestBody JSONObject requestJson) {
        Result<List<JSONObject>> result = new Result<>();
        try {
            List<JSONObject> kuaiShouAccounDetailtReport = bytedanceReportService.getKuaiShouAccounDetailtReport(requestJson);
            result.setResult(kuaiShouAccounDetailtReport);
            result.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            result.setSuccess(false);
        }
        return result;
    }


    @PostMapping("/kuaiShou/getReportList")
    public Result<List<JSONObject>> getReportList(@RequestBody JSONObject requestJson) {
        Result<List<JSONObject>> result = new Result<>();
        try {
            List<JSONObject> kuaiShouAccounDetailtReport = bytedanceReportService.getReportList(requestJson);
            result.setResult(kuaiShouAccounDetailtReport);
            result.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            result.setSuccess(false);
        }
        return result;

    }

    @GetMapping("/bytedance/bytedanceMaterialReport")
    public Result bytedanceMaterialReport(@RequestParam(name = "startDate") String startDate,
                                          @RequestParam(name = "endDate") String endDate) {
        Result result = new Result<>();
        if (StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)) {
            result.error500("开始时间和结束时间不能为空");
            return result;
        }
        try {
            log.info("头条获取素材报表数据任务执行开始");
            Long starttime = System.currentTimeMillis();
            List<CtopOauthToken> tokens = tokenService.selectToutiaoToken();
            if (null == tokens || tokens.size() <= 0) {
                log.info("头条获取素材报表数据任务执行失败:未获取到可用的token");
                return result;
            }

            final ExecutorService executorService = Executors.newFixedThreadPool(8);
            tokens.forEach(token -> {
                        executorService.submit(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    //间隔天数
                                    Long days = DateUtils.getDiscrepantDays(startDate, endDate);
                                    String start = null;
                                    String end = null;
                                    for (int i = 0; i <= days; i++) {
                                        start = DateUtils.addDay(startDate, i);
                                        end = start;
                                        //获取头条素材报表数据
                                        bytedanceReportService.bytedanceMaterialReport(token, start, end);
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                } finally {
                                }
                            }
                        });
                    }
            );
            ////
            Long endtime = System.currentTimeMillis();
            log.info("头条获取素材报表数据任务执行结束,执行耗时：{}秒", (endtime - starttime) / 1000);
        } catch (Exception e) {
            log.error("头条获取素材报表数据任务执行结失败");
            e.printStackTrace();
            result.setSuccess(false);
        }
        return result;
    }






    /**
     * 头条视频素材报表--此接口仅有视频素材，异步拉取数据
     *
     * @param startDate
     * @param endDate
     * @return
     */
    @GetMapping("/bytedance/bytedanceVideoMaterialReport")
    public Result bytedanceVideoMaterialReport(@RequestParam(name = "startDate") String startDate,
                                               @RequestParam(name = "endDate") String endDate) {
        Result result = new Result<>();
        if (StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)) {
            result.error500("开始时间和结束时间不能为空");
            return result;
        }
        try {
            log.info("头条获取视频素材报表数据任务执行开始");
            Long starttime = System.currentTimeMillis();
            List<CtopOauthToken> tokens = tokenService.selectToutiaoToken();
            if (null == tokens || tokens.size() <= 0) {
                log.info("头条获取素材报表数据任务执行失败:未获取到可用的token");
                return result;
            }

            final ExecutorService executorService = Executors.newFixedThreadPool(8);
            tokens.forEach(token -> {
                executorService.submit(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            //间隔天数
                            Long days = DateUtils.getDiscrepantDays(startDate, endDate);
                            String start = null;
                            String end = null;
                            for (int i = 0; i <= days; i++) {
                                start = DateUtils.addDay(startDate, i);
                                end = start;
                                //获取头条素材报表数据
                                bytedanceReportService.bytedanceVideoMaterialReport(token, start, end);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });
            });
            Long endtime = System.currentTimeMillis();
        } catch (Exception e) {
            log.error("头条获取视频素材报表数据任务执行结失败");
            e.printStackTrace();
            result.setSuccess(false);
        }
        return result;
    }

    /**
     * 头条视频素材报表--此接口仅有视频素材，单个accountId拉取数据
     *
     * @param startDate
     * @param endDate
     * @return
     */
    @GetMapping("/bytedance/bytedanceVideoMaterialReportByAccountId")
    public Result bytedanceVideoMaterialReportByAccountId(@RequestParam(name = "startDate") String startDate,
                                                          @RequestParam(name = "endDate") String endDate,
                                                          @RequestParam(name = "accountId") Long accountId) {
        Result result = new Result<>();
        if (StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate) || accountId == null) {
            result.error500("开始时间，结束时间和账户id不能为空");
            return result;
        }
        try {
            log.info("头条获取单个账户视频素材报表数据任务执行开始");
            Long starttime = System.currentTimeMillis();
            CtopOauthToken token = tokenService.getOauthTokenByAccountId(String.valueOf(accountId));
            if (null == token) {
                log.info("头条获取单个账户视频素材报表数据任务执行失败:未获取到可用的token");
                return result;
            }

            //间隔天数
            Long days = DateUtils.getDiscrepantDays(startDate, endDate);
            String start = null;
            String end = null;
            for (int i = 0; i <= days; i++) {
                start = DateUtils.addDay(startDate, i);
                end = start;
                //获取头条素材报表数据
                bytedanceReportService.bytedanceVideoMaterialReport(token, start, end);
            }

            Long endtime = System.currentTimeMillis();
            log.info("头条获取视频素材报表数据任务执行结束,执行耗时：{}秒", (endtime - starttime) / 1000);
        } catch (Exception e) {
            log.error("头条获取视频素材报表数据任务执行结失败");
            e.printStackTrace();
            result.setSuccess(false);
        }
        return result;
    }

    @ResponseBody
    @RequestMapping("/getBytedanceAccountInfoByProjectId")
    public Result<PageInfo<ByteDanceReportAccountDailyDTO>> getBytedanceAccountInfoByProjectId(@RequestBody BytedanceInfoDTO dto) {
        Result<PageInfo<ByteDanceReportAccountDailyDTO>> result = new Result<>();
        result.setSuccess(true);

        if (dto == null || dto.getStartDate() == null || dto.getEndDate() == null) {
            result.setSuccess(false);
            result.setMessage("参数有误");
            return result;
        }

        if (dto.getPageSize() == 0) {
            dto.setPageSize(20);
        }

        try {
            PageInfo<ByteDanceReportAccountDailyDTO> byteDanceReportAccountDailyDTOList = bytedanceAccountReportService.getBytedanceAccountInfoByProjectId(dto.getStartDate(), dto.getEndDate(), dto.getProjectId(), dto.getPageNum(), dto.getPageSize(), dto.getSort(), dto.getYn());
            result.setResult(byteDanceReportAccountDailyDTOList);
        } catch (Exception e) {
            log.error(e.getMessage());
            result.setSuccess(false);
            result.setMessage("执行出错");
        } finally {
        }

        return result;
    }

    @ResponseBody
    @RequestMapping("/getBytedanceSaleProjectInfo")
    public Result<PageInfo<ByteDanceReportAccountDailyDTO>> getBytedanceSaleProjectInfo(@RequestBody BytedanceInfoDTO dto) {
        Result<PageInfo<ByteDanceReportAccountDailyDTO>> result = new Result<>();
        result.setSuccess(true);

        if (dto == null || dto.getStartDate() == null || dto.getEndDate() == null) {
            //result.setSuccess(false);
            //result.setMessage("参数有误");
            //return result;

            Date getDate = DateUtils.addDay(new Date(), -1);
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String dateString = dateFormat.format(getDate);

            dto = new BytedanceInfoDTO();
            dto.setStartDate(dateString);
            dto.setEndDate(dateString);
        }

        if (dto.getPageSize() == 0) {
            dto.setPageSize(20);
        }

        try {
            PageInfo<ByteDanceReportAccountDailyDTO> byteDanceReportAccountDailyDTOList = bytedanceAccountReportService.getBytedanceSaleProjectInfo(dto.getStartDate(), dto.getEndDate(), dto.getProjectList(), dto.getPageNum(), dto.getPageSize(), dto.getSort(), dto.getYn());
            result.setResult(byteDanceReportAccountDailyDTOList);
        } catch (Exception e) {
            log.error(e.getMessage());
            result.setSuccess(false);
            result.setMessage("执行出错");
        } finally {
        }

        return result;
    }


    /**
     * 导出报表
     *
     * @return
     */
    @PostMapping(value = "/exportBytedanceSaleProjectInfo")
    public void exportXxl(@RequestBody BytedanceInfoDTO dto, HttpServletResponse response) throws IOException {
        List<SheetInfoVo> sheets = new ArrayList<>();
        if (dto == null || dto.getStartDate() == null || dto.getEndDate() == null) {
            Date getDate = DateUtils.addDay(new Date(), -1);
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            String dateString = dateFormat.format(getDate);

            dto = new BytedanceInfoDTO();
            dto.setStartDate(dateString);
            dto.setEndDate(dateString);
        }

        dto.setPageSize(1000000000);
        //查询总的消耗信息
        SheetInfoVo totalSheetVo = bytedanceAccountReportService.getBytedanceSaleProjectInfoSheetVO(dto.getStartDate(), dto.getEndDate(), dto.getProjectList(), dto.getPageNum(), dto.getPageSize(), dto.getSort(), dto.getYn());
        OutputStream outputStream = response.getOutputStream();
        String date = DateUtils.formatDate(new Date());
        HttpUtils.setResponseHeader(response, "头条销售报表" + date + ".xlsx");
        ExcelWriter excelWriter = EasyExcelFactory.getWriter(outputStream);
        Sheet sheet = new Sheet(1, 0, ByteDanceReportAccountDailyDTOEntity.class);
        sheet.setSheetName(totalSheetVo.getSheetName());
        excelWriter.write(totalSheetVo.getDetails(), sheet);
        excelWriter.finish();
        outputStream.flush();
        outputStream.close();
    }

}
