package com.sptg.ad.biz.receiver;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.sptg.ad.api.entity.AdPushContent;
import com.sptg.ad.api.entity.AdPushContentImg;
import com.sptg.ad.api.entity.AdPushTask;
import com.sptg.ad.api.entity.AdPushTaskDetails;
import com.sptg.ad.biz.service.AdPushContentImgServiceInterface;
import com.sptg.ad.biz.service.AdPushContentServiceInterface;
import com.sptg.ad.biz.service.AdPushTaskDetailsServiceInterface;
import com.sptg.ad.biz.service.AdPushTaskServiceInterface;
import com.sptg.ad.biz.stream.SyncLeisureAdvertDataDeviceReceiverInterface;
import com.sptg.common.core.beans.PageBean;
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.entity.Device;
import com.sptg.device.api.feigns.DeviceFeign;
import com.sptg.device.api.feigns.MsgPublishFeign;
import com.sptg.permissions.api.dto.RegionAuthorizeDto;
import com.sptg.permissions.api.entity.RegionAuthorize;
import com.sptg.permissions.api.feigns.DeviceAuthorizeFeign;
import com.sptg.permissions.api.feigns.RegionAuthorizeFeign;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.stereotype.Component;

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

/**
 *
 *
 * description:
 */
@Component
@Slf4j
@RequiredArgsConstructor
@SuppressWarnings({"all"})
@EnableBinding(value = { SyncLeisureAdvertDataDeviceReceiverInterface.class})
public class SyncLeisureAdvertDataDeviceReceiver {

    private final DeviceFeign deviceFeign;
    private final DeviceAuthorizeFeign deviceAuthorizeFeign;
    private final AdPushTaskServiceInterface adPushTaskServiceInterface;
    private final AdPushContentServiceInterface adPushContentServiceInterface;
    private final AdPushContentImgServiceInterface adPushContentImgServiceInterface;
    private final AdPushTaskDetailsServiceInterface adPushTaskDetailsServiceInterface;
    private final RegionAuthorizeFeign regionAuthorizeFeign;
    private final MsgPublishFeign msgPublishFeign;

    @StreamListener(value = SyncLeisureAdvertDataDeviceReceiverInterface.INPUT)
    public void input(String serialNumber){
        if (null == serialNumber){
            return;
        }
        //  获取设备授权的机构列表
        List<String> orgPositionList = this.deviceAuthorizeFeign.getDeviceAuthorizeOrgList(serialNumber);
        if (null == orgPositionList || orgPositionList.size() <= 0){
            return;
        }
        //  获取设备信息
        Device device = this.deviceFeign.getEntityBySerialNumber(serialNumber);
        if (null  == device){
            return;
        }
        //  分页获取广告任务列表
        int pageNum = 1;
        int pageSize = 100;
        Page<AdPushTask> page = new Page<>();
        page.setSize(pageSize);
        /*
            构建查询条件：
                1.查询授权机构下发的所有广告记录
                2.过滤已过期数据
                3.只查询发布成功的数据
                4.过滤针对单台设备发布的数据
                5.只查询闲时广告
         */
        Wrapper<AdPushTask> wrapper = new EntityWrapper<>();
//        wrapper.in("s_org_position",orgPositionList);
        wrapper.gt("t_end_date",new Date());
        wrapper.eq("i_push_status",1);
        wrapper.notIn("i_push_type",3);
        wrapper.eq("i_task_type",2);
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < orgPositionList.size(); i++){
            sb.append("INSTR(\'" + orgPositionList.get(i) +" \', s_org_position" + ")");
//            wrapper.where("INSTR(\'" + orgPositionList.get(i) +" \', s_org_position" + ")");
            if(i < orgPositionList.size() - 1){
//                wrapper.or();
                sb.append(" or ");
            }
        }
        if(sb.length() > 0){
            String sql = "(" + sb.toString() + ")";
            wrapper.where(sql);
        }
        while (true){
            page.setCurrent(pageNum);
            Page<AdPushTask> resultPage = this.adPushTaskServiceInterface.selectPage(page, wrapper);
            if (resultPage.getRecords().size() > 0){
                //  推送任务
                resultPage.getRecords().forEach(task -> this.pushTask(task,device));
            }
            if (resultPage.getRecords().size() < pageSize){
                //  结束循环
                break;
            }
            ++ pageNum;
        }
    }

    private void pushTask(AdPushTask task, Device device){
        //  获取发布范围,并判断是否需要推送到设备
        List<AdPushTaskDetails> detailsList = this.adPushTaskDetailsServiceInterface.getAdPushTaskDetails(task.getId());
        List<Long> fkIdList = detailsList.stream().map(AdPushTaskDetails::getFkId).collect(Collectors.toList());
        List<Long> deviceIdList;
        switch (task.getPushType()){
            //  小区发布
            case 1:
                if (!fkIdList.contains(device.getXqId())){
                    return;
                }
                deviceIdList = this.getDeviceIdByXqs(fkIdList);
                break;
            //  单元发布
            case 2:
                if (!fkIdList.contains(device.getUnitId())){
                    return;
                }
                deviceIdList = this.getDeviceIdByUnits(fkIdList);
                break;
            //  区域发布
            case 4:
                long province = Long.parseLong(device.getRegionProvince());
                long city = Long.parseLong(device.getRegionCity());
                long area = Long.parseLong(device.getRegionArea());
                if (!fkIdList.contains(province) && !fkIdList.contains(city) && !fkIdList.contains(area)){
                    return;
                }
                deviceIdList = this.getDeviceIdByRegions(fkIdList,task.getOrgPosition());
                break;
            default: return;
        }
        //  获取广告内容列表
        List<AdPushContent> contentList = this.adPushContentServiceInterface.getAdPushContents(task.getId());
        contentList.forEach(content -> {
            //  获取广告图片
            List<AdPushContentImg> imgList = this.adPushContentImgServiceInterface.getAdPushContentImgs(content.getId());
            content.setAdPushContentImgs(imgList);
        });
        task.setAdPushContents(contentList);

        PublishTask publishTask = new PublishTask(task.getId(), Instruct.add_leisure_advert_task,task,deviceIdList);
        publishTask.setTaskType(OperationConstant.ONE);
        Map<String,String> map = new HashMap<>();
        this.msgPublishFeign.publishTask(publishTask,map);
    }


    private List<Long> getDeviceIdByRegions(List<Long> fkIdList,String position){
        List<Long> xqIdList = new ArrayList<>();
        PageBean<RegionAuthorize, RegionAuthorizeDto> pageBean = new PageBean<>();
        pageBean.setSize(100);
        RegionAuthorizeDto dto = new RegionAuthorizeDto();
        dto.setUserOrgPosition(position);
        dto.setAreaIdList(fkIdList);
        pageBean.setDto(dto);
        int pageNo = 0;
        while (true){
            ++ pageNo;
            pageBean.setCurrent(pageNo);
            //  得到授权小区列表
            Page<RegionAuthorize> page = this.regionAuthorizeFeign.pagingQuery(pageBean);
            if (page.getRecords().size() == 0){
                break;
            }
            page.getRecords().forEach(authorize -> xqIdList.add(authorize.getXqId()));
        }
        return this.getDeviceIdByXqs(xqIdList);
    }

    private List<Long> getDeviceIdByXqs(List<Long> fkIdList){
        List<Long> deviceIdList = new ArrayList<>();
        fkIdList.forEach(xqId -> {
            List<Device> deviceList = this.deviceFeign.getListByXqId(xqId);
            deviceList.forEach(device -> deviceIdList.add(device.getId()));
        });
        return deviceIdList;
    }

    private List<Long> getDeviceIdByUnits(List<Long> fkIdList){
        List<Device> deviceList = this.deviceFeign.getListByUnitIds(fkIdList);
        return deviceList.stream().map(Device::getId).collect(Collectors.toList());
    }

}
