package org.jeecg.modules.ctop.controller;

import cn.com.ctop.common.module.annotation.AutoLog;
import cn.com.ctop.common.module.constant.CtopRoleCodeConstant;
import cn.com.ctop.common.module.entity.Advertiser;
import cn.com.ctop.common.module.entity.Project;
import cn.com.ctop.common.module.entity.UserAllocation;
import cn.com.ctop.common.module.mapper.ProjectMapper;
import cn.com.ctop.common.module.service.IProductService;
import cn.com.ctop.common.module.service.ISysRoleExtService;
import cn.com.ctop.common.module.service.IUserAllocationService;
import cn.com.ctop.common.module.utils.*;
import cn.com.ctop.common.module.vo.SheetInfoVo;
import cn.com.ctop.kuaishou.modules.report.entity.KuaishouInfoDTO;
import cn.com.ctop.kuaishou.modules.report.entity.KuaishouReportDailyAccountDTO;
import cn.com.ctop.kuaishou.modules.report.entity.ProjectAccountDTO;
import cn.com.ctop.kuaishou.modules.report.service.IKuaishouReportDailyAccountService;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.ctop.mapper.ProjectMemberMapper;
import org.jeecg.modules.ctop.service.IAdvertiserService;
import org.jeecg.modules.excelutil.entity.*;
import org.jeecg.modules.system.entity.UserCompany;
import org.jeecg.modules.system.mapper.UserCompanyMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.text.ParseException;
import java.util.*;

/**
 * @Description: 广告主信息表
 * @Author: jeecg-boot
 * @Date: 2019-06-11
 * @Version: V1.0
 */
@Slf4j
@Api(tags = "广告主信息表")
@RestController
@RequestMapping("/ctop/advertiser")
public class AdvertiserController {
    @Autowired
    private IAdvertiserService advertiserService;
    @Autowired
    private UserCompanyMapper userCompanyMapper;
    @Autowired
    private ISysRoleExtService sysRoleService;
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private ProjectMemberMapper projectMemberMapper;
    @Autowired
    private IUserAllocationService userAllocationService;

    /**
     * 查询 公司广告主
     *
     * @param userId
     * @return
     */
    @GetMapping(value = "/getAdvertiserByCompany")
    public Result<List<Advertiser>> getAdvertiserByCompany(String userId) {
        Result<List<Advertiser>> result = new Result<>();
        try {
            String roleCode = sysRoleService.getRoleCodeByUserId(userId);
            QueryWrapper<Advertiser> queryWrapper = new QueryWrapper<>();
            if (!CtopRoleCodeConstant.COMMON_ROLE_CODE_ADMIN.equals(roleCode)) {
                QueryWrapper<UserCompany> userCompanyQueryWrapper = new QueryWrapper<>();
                userCompanyQueryWrapper.eq("user_id", userId);
                userCompanyQueryWrapper.orderByDesc("create_time");
                userCompanyQueryWrapper.last("limit 1");
                UserCompany userCompany = userCompanyMapper.selectOne(userCompanyQueryWrapper);
                queryWrapper.eq("company_id", userCompany.getCompanyId());
            }
            List<Advertiser> list = advertiserService.list(queryWrapper);
            result.setSuccess(true);
            result.setResult(list);
        } catch (Exception e) {
            e.printStackTrace();
            result.setSuccess(false);
        }
        return result;
    }

    /**
     * 分页列表查询
     *
     * @param advertiser
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @AutoLog(value = "广告主信息表-分页列表查询")
    @ApiOperation(value = "广告主信息表-分页列表查询", notes = "广告主信息表-分页列表查询")
    @GetMapping(value = "/list")
    public Result<IPage<Advertiser>> queryPageList(Advertiser advertiser,
                                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                   @RequestParam(name = "pageSize", defaultValue = "1000") Integer pageSize,
                                                   HttpServletRequest req) {
        Result<IPage<Advertiser>> result = new Result<>();
        String name = advertiser.getName();
        advertiser.setName(null);
        QueryWrapper<Advertiser> queryWrapper = QueryGenerator.initQueryWrapper(advertiser, req.getParameterMap());
        if (!Check.isNull(name)) {
            queryWrapper.like("name", name);
        }
        Page<Advertiser> page = new Page<>(pageNo, pageSize);
        IPage<Advertiser> pageList = advertiserService.page(page, queryWrapper);
        result.setSuccess(true);
        result.setResult(pageList);
        return result;
    }

    /**
     * 添加
     *
     * @param advertiser
     * @return
     */
    @AutoLog(value = "广告主信息表-添加")
    @ApiOperation(value = "广告主信息表-添加", notes = "广告主信息表-添加")
    @PostMapping(value = "/add")
    public Result<Advertiser> add(@RequestBody Advertiser advertiser) {
        Result<Advertiser> result = new Result<>();
        try {
            String userId = advertiser.getUserId();
            String name = advertiser.getName().trim();
            QueryWrapper<UserCompany> userCompanyQueryWrapper = new QueryWrapper<>();
            userCompanyQueryWrapper.eq("user_id", userId);
            userCompanyQueryWrapper.orderByDesc("create_time");
            userCompanyQueryWrapper.last("limit 1");
            UserCompany userCompany = userCompanyMapper.selectOne(userCompanyQueryWrapper);
            QueryWrapper<Advertiser> advertiserQueryWrapper = new QueryWrapper<>();
            advertiserQueryWrapper.eq("name", name);
            if (!Check.isNull(userCompany)) {
                advertiserQueryWrapper.eq("company_id", userCompany.getCompanyId());
            }
            advertiserQueryWrapper.last("limit 1");
            advertiserQueryWrapper.orderByDesc("create_time");
            Advertiser checkAdvertiser = advertiserService.getOne(advertiserQueryWrapper);
            if (!Check.isNull(checkAdvertiser)) {
                throw new Exception("广告主已存在");
            }
            if (!Check.isNull(userCompany)) {
                advertiser.setCompanyId(userCompany.getCompanyId());
            }
            advertiserService.save(advertiser);
            result.success("添加成功！");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result.error500("添加失败 " + e.getMessage());
        }
        return result;
    }

    /**
     * 编辑
     *
     * @param advertiser
     * @return
     */

    @AutoLog(value = "广告主信息表-编辑")
    @ApiOperation(value = "广告主信息表-编辑", notes = "广告主信息表-编辑")
    @PutMapping(value = "/edit")
    public Result<Advertiser> edit(@RequestBody Advertiser advertiser) {
        Result<Advertiser> result = new Result<>();
        Advertiser advertiserEntity = advertiserService.getById(advertiser.getId());
        if (advertiserEntity == null) {
            result.error500("未找到对应实体");
        } else {
            boolean ok = advertiserService.updateById(advertiser);
            if (ok) {
                result.success("修改成功!");
            }
        }

        return result;
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @Autowired
    private IProductService productService;

    @AutoLog(value = "广告主信息表-通过id删除")
    @ApiOperation(value = "广告主信息表-通过id删除", notes = "广告主信息表-通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<Advertiser> delete(@RequestParam(name = "id", required = true) String id) {
        Result<Advertiser> result = new Result<>();
        Advertiser advertiser = advertiserService.getById(id);
        if (advertiser == null) {
            result.error500("未找到对应实体");
        } else {
            QueryWrapper<Project> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("advertiser_id", id);
            List<Project> projects = projectMapper.selectList(queryWrapper);
            if (!Check.isNull(projects)) {
                for (Project project : projects) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("project_id", project.getId());
                    projectMemberMapper.deleteByMap(map);
                    userAllocationService.removeByMap(map);
                }

            }
            Map<String, Object> productDeleteMap = new HashMap<>();
            productDeleteMap.put("advertiser_id", id);
            productService.removeByMap(productDeleteMap);

            projectMapper.delete(queryWrapper);
            boolean ok = advertiserService.removeById(id);
            if (ok) {
                result.success("删除成功!");
            }
        }

        return result;
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "广告主信息表-批量删除")
    @ApiOperation(value = "广告主信息表-批量删除", notes = "广告主信息表-批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<Advertiser> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        Result<Advertiser> result = new Result<>();
        if (ids == null || "".equals(ids.trim())) {
            result.error500("参数不识别！");
        } else {
            this.advertiserService.removeByIds(Arrays.asList(ids.split(StringUtils.COMMA)));
            result.success("删除成功!");
        }
        return result;
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @AutoLog(value = "广告主信息表-通过id查询")
    @ApiOperation(value = "广告主信息表-通过id查询", notes = "广告主信息表-通过id查询")
    @GetMapping(value = "/queryById")
    public Result<Advertiser> queryById(@RequestParam(name = "id", required = true) String id) {
        Result<Advertiser> result = new Result<>();
        Advertiser advertiser = advertiserService.getById(id);
        if (advertiser == null) {
            result.error500("未找到对应实体");
        } else {
            result.setResult(advertiser);
            result.setSuccess(true);
        }
        return result;
    }

    /**
     * 导出伊对报表
     *
     * @return
     */
    @RequestMapping(value = "/ydWeekReportList")
    public Map<String, Object> ydReportList(HttpServletRequest request, HttpServletResponse response, @RequestBody JSONObject data) throws ParseException {
        Map<String, Object> result = new HashMap<>();
        Long projectId = data.getLong("projectId");
        String startDate = data.getString("startDate");
        String endDate = data.getString("endDate");
        List<SheetInfoVo> vos = advertiserService.getYdStatisticInfo(projectId, startDate, endDate);
        result.put("data", vos);
        ResultMapUtils.setResultMap(result, StatusCode.COMMON_SUCCESS);
        return result;
    }

    /**
     * 导出报表
     *
     * @return
     */
    @RequestMapping(value = "/exportYdDailyReport")
    @ResponseBody
    public void exportYdWeek(HttpServletRequest request, HttpServletResponse response, @RequestBody JSONObject data) throws Exception {
        Long projectId = data.getLong("projectId");
        String startDate = data.getString("startDate");
        String endDate = data.getString("endDate");
        List<SheetInfoVo> vos = advertiserService.getYdStatisticInfo(projectId, startDate, endDate);
        OutputStream outputStream = response.getOutputStream();
        HttpUtils.setResponseHeader(response, "伊对" + startDate + "至" + endDate + "周报.xls");
        ExcelWriter excelWriter = EasyExcelFactory.getWriter(outputStream);
        for (int i = 0; i < vos.size(); i++) {
            Sheet sheet = new Sheet(i + 1, 0, KuaishouXxlEntity.class);
            sheet.setSheetName(vos.get(i).getSheetName());
            excelWriter.write(vos.get(i).getDetails(), sheet);
        }
        excelWriter.finish();
        outputStream.flush();
        outputStream.close();
    }

    /**
     * 导出消消乐报表
     *
     * @return
     */
    @RequestMapping(value = "/xxlDailyReportList")
    @ResponseBody
    public Map<String, Object> xxlReportList(HttpServletRequest request, HttpServletResponse response, @RequestBody JSONObject data) {
        Map<String, Object> result = new HashMap<>();
        List<SheetInfoVo> sheets = new ArrayList<>();
        //查询总的消耗信息
        Long projectId = data.getLong("projectId");
        String systemType = data.getString("systemType");
        if (null == systemType || "".equals(systemType.trim())) {
            systemType = null;
        }
        SheetInfoVo totalSheetVo = advertiserService.getXxlStatisticInfo(projectId, systemType, null, "汇总表");
        sheets.add(totalSheetVo);
        if (null == systemType) {
            List<SheetInfoVo> vos = advertiserService.getSystemTypeXxlStatisticInfo(projectId);
            if (null != vos && !vos.isEmpty()) {
                for (SheetInfoVo vo : vos) {
                    sheets.add(vo);
                }
            }
        }
        List<UserAllocation> allocations = userAllocationService.getByParams(projectId, systemType, null);
        if (null != allocations && !allocations.isEmpty()) {
            for (UserAllocation allocation : allocations) {
                SheetInfoVo vo = advertiserService.getXxlStatisticInfo(projectId, systemType, allocation.getAccountId(), allocation.getAuthName());
                sheets.add(vo);
            }
        }
        result.put("data", sheets);
        ResultMapUtils.setResultMap(result, StatusCode.COMMON_SUCCESS);
        return result;
    }

    /**
     * 导出报表
     *
     * @return
     */
    @RequestMapping(value = "/exportXxlDailyReport")
    @ResponseBody
    public void exportXxl(HttpServletRequest request,
                          HttpServletResponse response,
                          Long projectId,
                          String systemType) throws IOException {
        List<SheetInfoVo> sheets = new ArrayList<>();
        if (null == systemType || "".equals(systemType.trim())) {
            systemType = null;
        }
        //查询总的消耗信息
        SheetInfoVo totalSheetVo = advertiserService.getXxlStatisticInfo(projectId, systemType, null, "汇总表");
        sheets.add(totalSheetVo);
        if (null == systemType) {
            List<SheetInfoVo> vos = advertiserService.getSystemTypeXxlStatisticInfo(projectId);
            if (null != vos && !vos.isEmpty()) {
                for (SheetInfoVo vo : vos) {
                    sheets.add(vo);
                }
            }
        }
        List<UserAllocation> allocations = userAllocationService.getByParams(projectId, systemType, null);
        if (null != allocations && !allocations.isEmpty()) {
            for (UserAllocation allocation : allocations) {
                SheetInfoVo vo = advertiserService.getXxlStatisticInfo(projectId, systemType, allocation.getAccountId(), allocation.getAuthName());
                sheets.add(vo);
            }
        }
        OutputStream outputStream = response.getOutputStream();
        String date = DateUtils.formatDate(new Date());
        HttpUtils.setResponseHeader(response, "爱上消消消日报" + date + ".xlsx");
        ExcelWriter excelWriter = EasyExcelFactory.getWriter(outputStream);
        for (int i = 0; i < sheets.size(); i++) {
            Sheet sheet = new Sheet(i + 1, 0, KuaishouXxlEntity.class);
            sheet.setSheetName(sheets.get(i).getSheetName());
            excelWriter.write(sheets.get(i).getDetails(), sheet);
        }
        excelWriter.finish();
        outputStream.flush();
        outputStream.close();
    }

    @Autowired
    private IKuaishouReportDailyAccountService accountService;

    @RequestMapping("/exportKuaishouProjectInfo")
    public void getKuaishouProjectInfo(@RequestBody KuaishouInfoDTO dto,
                                       HttpServletRequest request,
                                       HttpServletResponse response) throws IOException {
        Result<PageInfo<ProjectAccountDTO>> result = new Result<>();
        result.setSuccess(true);

        if (dto.getPageSize() == 0) {
            dto.setPageSize(100000);
        }
        OutputStream outputStream = response.getOutputStream();
        String date = DateUtils.formatDate(new Date());
        HttpUtils.setResponseHeader(response, "快手效果报表" + date + ".xlsx");
        ExcelWriter excelWriter = EasyExcelFactory.getWriter(outputStream);
        String type = dto.getType();
        if (null != type && "project".equals(type.trim())) {
            SheetInfoVo projectSheetVo = this.getProjectSheetVo(dto, "项目报表");
            Sheet sheet = new Sheet(1, 0, EffecfReportProjectEntity.class);
            sheet.setSheetName(projectSheetVo.getSheetName());
            excelWriter.write(projectSheetVo.getDetails(), sheet);
        }
        if (null != type && "account".equals(type.trim())) {
            SheetInfoVo accountSheetVo = this.getAccountSheetVo(dto, "账户报表");
            Sheet sheet = new Sheet(1, 0, EffecfReportAccountEntity.class);
            sheet.setSheetName(accountSheetVo.getSheetName());
            excelWriter.write(accountSheetVo.getDetails(), sheet);
        }

        if (null != type && "campaign".equals(type.trim())) {
            SheetInfoVo planSheetVo = this.getPlanSheetVo(dto, "广告计划报表");
            Sheet sheet = new Sheet(1, 0, EffecfReportPlanEntity.class);
            sheet.setSheetName(planSheetVo.getSheetName());
            excelWriter.write(planSheetVo.getDetails(), sheet);
        }

        if (null != type && "group".equals(type.trim())) {
            SheetInfoVo campaignSheetVo = this.getGroupSheetVo(dto, "广告组报表");
            Sheet sheet = new Sheet(1, 0, EffecfReportGroupEntity.class);
            sheet.setSheetName(campaignSheetVo.getSheetName());
            excelWriter.write(campaignSheetVo.getDetails(), sheet);
        }

        if (null != type && "creative".equals(type.trim())) {
            SheetInfoVo creativeSheetVo = this.getCreativeSheetVo(dto, "广告创意");
            Sheet sheet = new Sheet(1, 0, EffecfReportCreativeEntity.class);
            sheet.setSheetName(creativeSheetVo.getSheetName());
            excelWriter.write(creativeSheetVo.getDetails(), sheet);
        }

        excelWriter.finish();
        outputStream.flush();
        outputStream.close();
    }

    private SheetInfoVo getCreativeSheetVo(KuaishouInfoDTO dto, String sheetName) {
        SheetInfoVo vo = new SheetInfoVo<EffecfReportProjectEntity>();
        vo.setSheetName(sheetName);
        PageInfo<KuaishouReportDailyAccountDTO> kuaishouCampaignInfoList = accountService.getKuaishouCreativeInfoByUnitId(dto.getProjectList(), dto.getUnitId(), dto.getStartDate(), dto.getEndDate(), dto.getPageSize(), dto.getPageNum(), dto.getYn());
        List<KuaishouReportDailyAccountDTO> dtos = kuaishouCampaignInfoList.getList();
        if (null != dtos && !dtos.isEmpty()) {
            List<EffecfReportCreativeEntity> details = new ArrayList<>();
            for (KuaishouReportDailyAccountDTO dto1 : dtos) {
                EffecfReportCreativeEntity entity = new EffecfReportCreativeEntity();
                BeanUtils.copyProperties(dto1, entity);
                details.add(entity);
            }
            vo.setDetails(details);
        }
        return vo;
    }

    private SheetInfoVo getGroupSheetVo(KuaishouInfoDTO dto, String sheetName) {
        SheetInfoVo vo = new SheetInfoVo<EffecfReportProjectEntity>();
        vo.setSheetName(sheetName);
        PageInfo<KuaishouReportDailyAccountDTO> kuaishouCampaignInfoList = accountService.getKuaishouUnitInfoByCampaignId(dto.getProjectList(), dto.getCampaignId(), dto.getStartDate(), dto.getEndDate(), dto.getPageSize(), dto.getPageNum(), dto.getYn());
        List<KuaishouReportDailyAccountDTO> dtos = kuaishouCampaignInfoList.getList();
        if (null != dtos && !dtos.isEmpty()) {
            List<EffecfReportGroupEntity> details = new ArrayList<>();
            for (KuaishouReportDailyAccountDTO dto1 : dtos) {
                EffecfReportGroupEntity entity = new EffecfReportGroupEntity();
                BeanUtils.copyProperties(dto1, entity);
                details.add(entity);
            }
            vo.setDetails(details);
        }
        return vo;
    }

    private SheetInfoVo getPlanSheetVo(KuaishouInfoDTO dto, String sheetName) {
        SheetInfoVo vo = new SheetInfoVo<EffecfReportProjectEntity>();
        vo.setSheetName(sheetName);
        PageInfo<KuaishouReportDailyAccountDTO> kuaishouCampaignInfoList = accountService.getKuaishouCampaignInfoByAccountId(dto.getProjectList(), dto.getAccountId(), dto.getStartDate(), dto.getEndDate(), dto.getPageSize(), dto.getPageNum(), dto.getYn());
        List<KuaishouReportDailyAccountDTO> dtos = kuaishouCampaignInfoList.getList();
        if (null != dtos && !dtos.isEmpty()) {
            List<EffecfReportPlanEntity> details = new ArrayList<>();
            for (KuaishouReportDailyAccountDTO dto1 : dtos) {
                EffecfReportPlanEntity entity = new EffecfReportPlanEntity();
                BeanUtils.copyProperties(dto1, entity);
                details.add(entity);
            }
            vo.setDetails(details);
        }
        return vo;
    }

    private SheetInfoVo getAccountSheetVo(KuaishouInfoDTO dto, String sheetName) {
        SheetInfoVo vo = new SheetInfoVo<EffecfReportProjectEntity>();
        vo.setSheetName(sheetName);
        PageInfo<KuaishouReportDailyAccountDTO> kuaishouReportDailyAccountDTOList = accountService.getKuaishouAccountInfoByProjectId(dto.getProjectId(), dto.getProjectList(), dto.getStartDate(), dto.getEndDate(), dto.getPageSize(), dto.getPageNum(), dto.getYn());
        List<KuaishouReportDailyAccountDTO> dtos = kuaishouReportDailyAccountDTOList.getList();
        if (null != dtos && !dtos.isEmpty()) {
            List<EffecfReportAccountEntity> details = new ArrayList<>();
            for (KuaishouReportDailyAccountDTO dto1 : dtos) {
                EffecfReportAccountEntity entity = new EffecfReportAccountEntity();
                BeanUtils.copyProperties(dto1, entity);
                details.add(entity);
            }
            vo.setDetails(details);
        }
        return vo;
    }

    private SheetInfoVo getProjectSheetVo(KuaishouInfoDTO dto, String sheetName) {
        SheetInfoVo vo = new SheetInfoVo<EffecfReportProjectEntity>();
        vo.setSheetName(sheetName);
        PageInfo<ProjectAccountDTO> projectAccountDTOList = accountService.getKuaishouProjectInfo(dto.getStartDate(), dto.getEndDate(), dto.getProjectList(), dto.getPageSize(), dto.getPageNum(), "", dto.getYn());
        List<ProjectAccountDTO> dtos = projectAccountDTOList.getList();
        if (null != dtos && !dtos.isEmpty()) {
            List<EffecfReportProjectEntity> details = new ArrayList<>();
            for (ProjectAccountDTO dto1 : dtos) {
                EffecfReportProjectEntity entity = new EffecfReportProjectEntity();
                BeanUtils.copyProperties(dto1, entity);
                details.add(entity);
            }
            vo.setDetails(details);
        }
        return vo;
    }
}
