package com.sptg.ad.biz.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.sptg.ad.api.dto.AdContentDto;
import com.sptg.ad.api.dto.AdPushTaskDto;
import com.sptg.ad.api.entity.*;
import com.sptg.ad.biz.mapper.AdPushTaskMapper;
import com.sptg.ad.biz.service.*;
import com.sptg.common.core.beans.ResultBean;
import com.sptg.common.core.beans.ResultEnum;
import com.sptg.common.core.constant.OperationConstant;
import com.sptg.common.core.entity.PublishTask;
import com.sptg.common.core.enums.Instruct;
import com.sptg.device.api.feigns.MsgPublishFeign;
import com.sptg.permissions.api.feigns.ConfFeign;
import com.sptg.statistics.api.dto.StatisticsAdPushCountDto;
import com.sptg.statistics.api.entity.StatisticsAdPushCount;
import com.sptg.statistics.api.feigns.StatisticsAdPushCountFeign;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * title: AdPushTaskServiceImpl
 * package: com.sptg.ad.biz.security.impl
 * description: 广告类容-服务层实现类
 *
 *
 *
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AdPushTaskServiceImpl extends ServiceImpl<AdPushTaskMapper, AdPushTask> implements AdPushTaskServiceInterface{

    private final AdPushTaskDetailsServiceInterface adPushTaskDetailsServiceInterface;

    private final AdContentServiceInterface adContentServiceInterface;

    private final AdPushContentImgServiceInterface adPushContentImgServiceInterface;

    private final AdPushDeviceDetailsServiceInterface adPushDeviceDetailsServiceInterface;

    private final AdPushContentServiceInterface adPushContentServiceInterface;

    private final ConfFeign confFeign;

    private final StatisticsAdPushCountFeign statisticsAdPushCountFeign;
    private final MsgPublishFeign msgPublishFeign;

    private final AdMaterialServiceInterface adMaterialServiceInterface;
    @Override
    public Page<AdPushTask> showAdPushTaskList(AdPushTaskDto adPushTaskDto){
        //排序字段 时间降序
        adPushTaskDto.getPage().setOrderByField("t.t_create_date");
        adPushTaskDto.getPage().setAsc(false);
        //构建查询条件
        Wrapper<AdPushTask> wrapper = new EntityWrapper<>();
        //  根据任务类型查询
        if (null != adPushTaskDto.getTaskType()){
            wrapper.eq("t.i_task_type",adPushTaskDto.getTaskType());
        }
//        //根据广告发布内容反查
//        AdPushContent adPushContent = new AdPushContent();
//        adPushContent.setAdTitle(adPushTaskDto.getAdTitle());
//        adPushContent.setAdCode(adPushTaskDto.getAdCode());
//        adPushContent.setAdTypeId(adPushTaskDto.getAdTypeId());
//        adPushContent.setOrgPosition(adPushTaskDto.getOrgPosition());
//        if(StringUtils.isNotBlank(adPushContent.getAdTitle()) || StringUtils.isNotBlank(adPushContent.getAdCode()) || adPushContent.getAdTypeId()!=null){
//            List<Long> taskIds = adPushContentServiceInterface.getTaskIds(adPushContent);
//            if(taskIds!=null && taskIds.size()>0){
//                wrapper.in("t.l_id",taskIds);
//            }else {
//                wrapper.eq("t.l_id","");
//            }
//        }
        if(StringUtils.isNotBlank(adPushTaskDto.getAdTitle())){
            wrapper.like("c.s_ad_title", adPushTaskDto.getAdTitle());
        }
        if(adPushTaskDto.getTaskType()!=null){
            wrapper.eq("t.i_task_type", adPushTaskDto.getTaskType());
        }
        //发布状态{ -1：发布失败，0：待发布，1：发布成功，2：已撤销 }
        if(adPushTaskDto.getPushStatus()!=null){
            if(adPushTaskDto.getPushStatus()==1){
                List<Integer> pushStatus = new ArrayList<>();
                pushStatus.add(adPushTaskDto.getPushStatus());
                pushStatus.add(2);
                wrapper.in("t.i_push_status", pushStatus);
            }else if(adPushTaskDto.getPushStatus()==3){
                //3是临时状态
                wrapper.in("t.i_push_status", "1");
            }else{
                wrapper.eq("t.i_push_status", adPushTaskDto.getPushStatus());
            }
        }
        //查询本级以及下级广告记录
        wrapper.like("t.s_org_position",adPushTaskDto.getOrgPosition());
        Page<AdPushTask> page = adPushTaskDto.getPage();
        page.setRecords(this.baseMapper.showList(wrapper, page));
        return page;
    }

    private final AdTypeServiceInterface adTypeServiceInterface;

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Boolean> addAdPushTask(AdPushTask adPushTask){
        //任务对象
        boolean result = this.insert(adPushTask);
        Long[] adIds = adPushTask.getAdIds();
        String fastDfsServerHost = confFeign.getFileServerHost();
        for(Long adId:adIds){
            //广告内容对象
            AdContent adContent = adContentServiceInterface.findAdContentById(adId);
            if(adContent!=null){
                AdType adType = this.adTypeServiceInterface.selectById(adContent.getAdTypeId());
                AdPushContent adPushContent = new AdPushContent();
                adPushContent.setTaskId(adPushTask.getId());
                adPushContent.setAdTypeName(adType.getName());
                adPushContent.setAdId(adContent.getId());
                adPushContent.setAdTitle(adContent.getAdTitle());
                adPushContent.setAdTypeId(adContent.getAdTypeId());
                adPushContent.setAdCode(adContent.getAdCode());
                AdMaterial adMaterial = adMaterialServiceInterface.selectById(adContent.getAdMaterialId());
                if(adMaterial != null){
                    if(StringUtils.isNotBlank(adMaterial.getMaterialFile())){
                    //全路径
                        adPushContent.setVideoUri(fastDfsServerHost + adMaterial.getMaterialFile());
                        adPushContent.setVideoMd5(adMaterial.getVideoMd5());
                    }
                }
                adPushContent.setImgPlayTime(adPushTask.getImgPlayTime());
                adPushContent.setOrgPosition(adPushTask.getOrgPosition());
                adPushContentServiceInterface.addAdPushContent(adPushContent);
                //有图片
                if(adContent.getHasImg()==1){
                    List<AdContentImg> list = adContent.getAdContentImgs();
                    List<AdPushContentImg> adPushContentImgs = new ArrayList<>(list.size());
                    for(AdContentImg adContentImg : list){
                        AdPushContentImg adPushContentImg = new AdPushContentImg();
                        adPushContentImg.setPushContentId(adPushContent.getId());
                        adPushContentImg.setImgUri(fastDfsServerHost+adContentImg.getImgUri());
                        adPushContentImg.setImgMd5(adContentImg.getImgMd5());
                        adPushContentImg.setSort(adContentImg.getSort());
                        adPushContentImgs.add(adPushContentImg);
                    }
                    if(adPushContentImgs.size()>0){
                        //保存图片
                        adPushContentImgServiceInterface.addAdPushContentImg(adPushContentImgs);
                    }
                }
            }
        }

        if(result){
            Long[] ids = adPushTask.getAdPushTaskDetails();
            if(ids!=null){
                List<AdPushTaskDetails> list = new ArrayList<>();
                for(Long id:ids){
                    AdPushTaskDetails adPushTaskDetails = new AdPushTaskDetails();
                    adPushTaskDetails.setTaskId(adPushTask.getId());
                    adPushTaskDetails.setFkId(id);
                    list.add(adPushTaskDetails);
                }
                //保存任务详情
                adPushTaskDetailsServiceInterface.addAdPushTaskDetails(list);
            }
        }
        return new ResultBean<>(ResultEnum.SUCCESS,result);
    }

    @Override
    public ResultBean<Boolean> cancelAdPushTask(Long id) {
        if(id!=null){
            AdPushTask adPushTask = this.selectById(id);
            //发布状态{ -1：发布失败，0：待发布，1：发布成功，2：已撤销 }
            //校验状态--只有待发布的任务才能撤回
            if(adPushTask.getPushStatus()==0){
                AdPushTask a = new AdPushTask();
                Wrapper<AdPushTask> wrapper = new EntityWrapper<>();
                wrapper.eq("l_id", id);
                //撤销
                a.setPushStatus(OperationConstant.TWO);
                return new ResultBean<>(ResultEnum.SUCCESS, this.update(a,wrapper));
            }
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    @Override
    public AdPushTask findAdPushTaskById(Long id) {
        AdPushTask adPushTask = this.selectById(id);
        if(adPushTask!=null){
            //关联的广告
            List<AdPushContent> adPushContents = adPushContentServiceInterface.getAdPushContents(id);
            adPushTask.setAdPushContents(adPushContents);
            //详情
            List<AdPushTaskDetails> adPushTaskDetails = adPushTaskDetailsServiceInterface.getAdPushTaskDetails(adPushTask.getId());
            adPushTask.setAdPushTaskDetailsList(adPushTaskDetails);
        }
        return adPushTask;
    }

    @Override
    public ResultBean<Boolean> manuallyIssued(Long id) {
        AdPushTask task = this.selectById(id);
        if(task!=null){
            //  发送广告任务
            try {
                //任务体
                List<AdPushContent> adPushContents = adPushContentServiceInterface.getAdPushContents(id);
                for(AdPushContent adPushContent : adPushContents){
                    //获取广告图片
                    List<AdPushContentImg> adPushContentImgs = adPushContentImgServiceInterface.getAdPushContentImgs(adPushContent.getId());
                    adPushContent.setAdPushContentImgs(adPushContentImgs);
                }
                //任务内容
                task.setAdPushContents(adPushContents);
                //获取推送失败记录
                List<AdPushDeviceDetails> adPushDeviceDetails = adPushDeviceDetailsServiceInterface.getListByTaskId(task.getId());
                // 获取设备Id列表
                List<Long> deviceIdList = adPushDeviceDetails.stream().map(AdPushDeviceDetails::getDeviceId).collect(Collectors.toList());

                //  判断是人脸广告还是闲时广告
                Instruct instruct = task.getTaskType() == 1 ? Instruct.add_face_advert_task : Instruct.add_leisure_advert_task;
                // 构建发布内容体
                PublishTask publishTask =  new PublishTask(task.getId(),instruct,task,deviceIdList);
                //  任务类型：{ 1：广告，2：策略，3：公告 }
                publishTask.setTaskType(1);
                Map<String,String> map = new HashMap<>();
                this.msgPublishFeign.publishTask(publishTask,map);

                //记录统计广告发布数量  等到推送完成才能累计到系统中
                StatisticsAdPushCountDto statisticsAdPushCountDto=new StatisticsAdPushCountDto();
                statisticsAdPushCountDto.setAdPushTaskId(task.getId());
                //查询是否已经添加记录
                StatisticsAdPushCount statisticsAdPushCount = statisticsAdPushCountFeign.getStatisticsAdPushCountByTaskId(statisticsAdPushCountDto);
                if(statisticsAdPushCount==null){
                    //推送状态
                    statisticsAdPushCountDto.setPushState(OperationConstant.ZERO);
                    statisticsAdPushCountDto.setCount(task.getContentCount());
                    statisticsAdPushCountDto.setCreateDate(new Date());
                    statisticsAdPushCountDto.setRootOrgId(task.getRootOrgId());
                    statisticsAdPushCountDto.setOrgPosition(task.getOrgPosition());
                    statisticsAdPushCountFeign.addAdPushCount(statisticsAdPushCountDto);
                }
            }catch (Exception e){
                //发布失败
                return new ResultBean<>(ResultEnum.SUCCESS,false);
            }
        }
        return new ResultBean<>(ResultEnum.SUCCESS,true);
    }
    @Override
    public ResultBean<Boolean> adIssued(Long deviceId) {
        AdContentDto adContentDto = new AdContentDto();
        adContentDto.setAdTitle("实施测试广告");
        adContentDto.setOrgPosition("0/1/");
        ResultBean<AdContent> resultBean = this.adContentServiceInterface.getList(adContentDto);
        List<AdContent> list = resultBean.getList();
        if(list!=null && list.size()>0){
            String fastDfsServerHost = confFeign.getFileServerHost();
            AdContent adContent = list.get(0);
            AdPushContent adPushContent = new AdPushContent();
            adPushContent.setTaskId(0L);
            adPushContent.setAdId(adContent.getId());
            adPushContent.setAdTitle(adContent.getAdTitle());
            adPushContent.setAdTypeId(adContent.getAdTypeId());
            adPushContent.setAdCode(adContent.getAdCode());
            //全路径
            adPushContent.setVideoUri(fastDfsServerHost+adContent.getVideoUri());
            adPushContent.setVideoMd5(adContent.getVideoMd5());
            adPushContent.setOrgPosition(adContent.getOrgPosition());
            //构建任务
            AdPushTask task = new AdPushTask();
            //创建一个不存在的任务id
            task.setId(0L);
            task.setContentCount(1);
            task.setBeginDate(new Date());
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.HOUR, +3);
            task.setEndDate(calendar.getTime());
            task.setPushType(3);
            //构建发送的任务体
            List<AdPushContent> adPushContents = new ArrayList<>();
            adPushContents.add(adPushContent);
            task.setAdPushContents(adPushContents);
            //发送的设备
            List<Long> deviceIdList = new ArrayList<>();
            deviceIdList.add(deviceId);

            // 构建发布内容体
            PublishTask publishTask =  new PublishTask(task.getId(),Instruct.add_face_advert_task,task,deviceIdList);
            //  任务类型：{ 1：广告，2：策略，3：公告 }
            publishTask.setTaskType(1);
            Map<String,String> map = new HashMap<>();
            this.msgPublishFeign.publishTask(publishTask,map);

            return new ResultBean<>(ResultEnum.SUCCESS,true);
        }else{
            log.warn("下发实施广告失败，没有查询到实施测试广告内容");
            return new ResultBean<>(ResultEnum.SUCCESS,false);
        }
    }

    @Override
    public void updateOrgPosition(String oldPosition, String newPosition) {
        this.baseMapper.updateOrgPosition(oldPosition,newPosition);
    }

    @Override
    public ResultBean<Boolean> updateAdPushTask(AdPushTask adPushTask) {
        return new ResultBean<>(ResultEnum.SUCCESS, this.updateById(adPushTask));
    }

    @Override
    public int getValidAdPushCountDevice(Long deviceId) {
        Integer adCount = this.baseMapper.getValidAdPushCountDevice(deviceId);
        return adCount==null?0:adCount.intValue();
    }
}
