package com.sptg.gateway.controller.ad;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.baomidou.mybatisplus.plugins.Page;
import com.sptg.ad.api.constant.AdSecurityToken;
import com.sptg.ad.api.dto.AdPushTaskDto;
import com.sptg.ad.api.entity.AdPushContent;
import com.sptg.ad.api.entity.AdPushTask;
import com.sptg.ad.api.entity.AdPushTaskDetails;
import com.sptg.ad.api.entity.AdPushThresholdValue;
import com.sptg.ad.api.feigns.AdPushTaskFeign;
import com.sptg.common.core.beans.ResultBean;
import com.sptg.common.core.constant.OperationConstant;
import com.sptg.common.core.constant.SysLogConstant;
import com.sptg.common.core.util.WebUtils;
import com.sptg.common.security.annotation.Security;
import com.sptg.common.security.enums.DataFormatEnum;
import com.sptg.common.security.service.SecurityServiceInterface;
import com.sptg.device.api.entity.Device;
import com.sptg.device.api.feigns.DeviceFeign;
import com.sptg.estate.api.entity.Residential;
import com.sptg.estate.api.entity.Unit;
import com.sptg.estate.api.feigns.ResidentialFeign;
import com.sptg.estate.api.feigns.UnitFeign;
import com.sptg.permissions.api.entity.Account;
import com.sptg.permissions.api.entity.Area;
import com.sptg.permissions.api.feigns.AreaFeign;
import com.sptg.permissions.api.feigns.ConfFeign;
import com.sptg.statistics.api.constant.SysLogMenuConstant;
import com.sptg.statistics.api.entity.SysOperationLog;
import com.sptg.statistics.api.feigns.SysOperationLogFeign;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * title: AdPushTaskController
 * package: com.sptg.gateway.controller.ad
 * description: 广告发布-控制器
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping(value = "/ad/push")
public class AdPushTaskController {

    private final ConfFeign confFeign;
    private final SecurityServiceInterface<Account> securityServiceInterface;
    private final AdPushTaskFeign adPushTaskFeign;
    private final ResidentialFeign residentialFeign;
    private final UnitFeign unitFeign;
    private final DeviceFeign deviceFeign;
    private final AreaFeign areaFeign;
    private final SysOperationLogFeign sysOperationLogFeign;
    /**
     * 功能描述:广告发布页面
     */
    @GetMapping("/task/index")
    @Security(token = {"ad:push:task:manage","ad:push:leisure:task:manage"},format = DataFormatEnum.VIEW)
    public ModelAndView index(){
        ModelAndView modelAndView = new ModelAndView("ad/ad-push-task-manage");
        modelAndView.addObject("fastDfsServer", this.confFeign.getFileServerHost());
        return modelAndView;
    }

    /**
     * @return 闲时广告发布页面
     */
    @GetMapping(value = "/task/leisure/index")
    @Security(token = "ad:push:leisure:task:manage",format = DataFormatEnum.VIEW)
    public ModelAndView leisureTaskManage(){
        ModelAndView modelAndView = new ModelAndView("ad/ad-leisure-task-manage");
        modelAndView.addObject("fastDfsServer", this.confFeign.getFileServerHost());
        return modelAndView;
    }

    /**
     * @return 线下广告发布页面
     */
    @GetMapping(value = "/task/offline/index")
    @Security(token = "ad:push:task:offline:manage",format = DataFormatEnum.VIEW)
    public ModelAndView offlineTaskManage(){
        ModelAndView modelAndView = new ModelAndView("ad-offline-push-manage");
        modelAndView.addObject("fastDfsServer", this.confFeign.getFileServerHost());
        return modelAndView;
    }

    /**
     * 功能描述:广告任务发布监控页面
     */
    @GetMapping("/monitoring/index")
    @Security(token = AdSecurityToken.AD_PUSH_MONITORING,format = DataFormatEnum.VIEW)
    public ModelAndView monitoringIndex(){
        ModelAndView modelAndView = new ModelAndView("ad/ad-push-monitoring");
        modelAndView.addObject("fastDfsServer", this.confFeign.getFileServerHost());
        return modelAndView;
    }

    /**
     * 功能描述:广告任务发布记录页面
     */
    @GetMapping("/record/index")
    @Security(token = AdSecurityToken.AD_PUSH_RECORD,format = DataFormatEnum.VIEW)
    public ModelAndView recordIndex(){
        ModelAndView modelAndView = new ModelAndView("ad/ad-push-record");
        modelAndView.addObject("fastDfsServer", this.confFeign.getFileServerHost());
        return modelAndView;
    }

    /**
     * 查询广告类容列表(分页)
     * @param adPushTaskDto 查询条件参数
     * @param page 分页参数
     */
    @PostMapping(value = "/task/showAdPushTaskList")
    @Security(token = {"ad:push:task:manage","ad:push:leisure:task:manage"},format = DataFormatEnum.JSON)
    public ResultBean<Page<AdPushTask>> showAdPushTaskList(AdPushTaskDto adPushTaskDto, Page<AdPushTask> page){
        //获取当前登陆用户
        Account onLineUser = this.securityServiceInterface.getOnLineUser();
        adPushTaskDto.setOrgPosition(onLineUser.getOrgPosition());
        adPushTaskDto.setPage(page);
        ResultBean<Page<AdPushTask>> pageResultBean = this.adPushTaskFeign.showAdPushTaskList(adPushTaskDto);
        Page<AdPushTask> pageResult = pageResultBean.getData();
        List<AdPushTask> records = pageResult.getRecords();
        if(records!=null&&!records.isEmpty()){
            for(AdPushTask adPushTask:records){
                //  获取关联的外键Id列表
                Long taskId = adPushTask.getId();
                List<AdPushTaskDetails> adPushTaskDetailList = this.adPushTaskFeign.getAdPushTaskDetailsByTaskId(taskId);
                List<Long> fkIdList =null;
                if(adPushTaskDetailList!=null&&!adPushTaskDetailList.isEmpty()){
                   fkIdList = adPushTaskDetailList.stream().map(AdPushTaskDetails::getFkId).collect(Collectors.toList());
                }
                List<String> list = null;
                if (fkIdList.size() > OperationConstant.ZERO) {
                    switch (adPushTask.getPushType()) {
                        case OperationConstant.THREE:
                            //  按设备发布
                            List<Device> deviceList = this.deviceFeign.getListByIds(fkIdList);
                            list = deviceList.stream().map(Device::getName).collect(Collectors.toList());
                            break;
                        case OperationConstant.TWO:
                            //  按单元发布
                            List<Unit> unitList = this.unitFeign.getListByIdList(fkIdList);
                            list = unitList.stream().map(Unit::getName).collect(Collectors.toList());
                            break;
                        case OperationConstant.ONE:
                            //  按小区发布
                            List<Residential> orgList = this.residentialFeign.getByOrgIdList(fkIdList);
                            list = orgList.stream().map(Residential::getName).collect(Collectors.toList());
                            break;
                        default:
                            //  按区域发布
                            List<Area> areaList = this.areaFeign.getListByIds(fkIdList);
                            list = areaList.stream().map(Area::getName).collect(Collectors.toList());
                            break;
                    }
                    //发布范围
                    adPushTask.setAdPushRangeNames(list);
                    //发布内容
                    List<AdPushContent> abPushContentList = this.adPushTaskFeign.getAdPushContentsByTaskId(taskId);
                    List<String> contentNameList = abPushContentList.stream().map(AdPushContent::getAdTitle).collect(Collectors.toList());
                    adPushTask.setAdPushContentNames(contentNameList);
                }
            }
        }
        return pageResultBean;
    }

    /**
     * 功能描述:关联广告弹窗页面 iframe
     */
    @GetMapping("/task/relevance/view")
    public ModelAndView showTaskRelevance(Integer onlineOrOffline){
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("ad/ad-push-task-relevance");
        modelAndView.addObject("onlineOrOffline",onlineOrOffline);
        return modelAndView;
    }


    /**
     * 功能描述:发布任务详情 iframe
     */
    @GetMapping("/task/detail/view")
    @Security(token = {"ad:push:task:detail","ad:push:leisure:task:detail", "ad:push:record:detail"},format = DataFormatEnum.VIEW)
    public ModelAndView showTaskDetail(Long id){
        ModelAndView modelAndView = new ModelAndView();
        AdPushTask adPushTask = new AdPushTask();
        //详情
        if(id!=null){
            AdPushTask detail = this.adPushTaskFeign.findAdPushTaskById(id);
            if(detail!=null){
                adPushTask = detail;
                List<AdPushTaskDetails> adPushTaskDetailsList = adPushTask.getAdPushTaskDetailsList();
                if(adPushTaskDetailsList!=null){
                    List<Long> fkId = new ArrayList<>(adPushTaskDetailsList.size());
                    for (AdPushTaskDetails adPushTaskDetails:adPushTaskDetailsList){
                        fkId.add(adPushTaskDetails.getFkId());
                    }
                    List objects = null;
                    //发布类型{ 1 ：按小区发布，2：按单元发布，3：按设备发布，4：按区域发布}
                    Integer pushType = adPushTask.getPushType();
                    if(pushType==1){
                        objects = residentialFeign.getByOrgIdList(fkId);
                    }else if(pushType==2){
                        objects = unitFeign.getListByIdList(fkId);
                    }else if(pushType==3){
                        objects =deviceFeign.getListByIds(fkId);
                    }else if(pushType==4){
                        objects = areaFeign.getListByIds(fkId);
                    }
                    modelAndView.addObject("objects",objects);
                }
            }
            modelAndView.addObject("adPushTask",adPushTask);
            modelAndView.setViewName("ad/ad-push-task-detail");
        }
        return modelAndView;
    }

    /**
     * 功能描述:显示新增/编辑页面 iframe
     * @return ModelAndView
     */
    @GetMapping("/task/add/view")
    @Security(token = {"ad:push:task:insert","ad:push:leisure:task:insert"},format = DataFormatEnum.VIEW)
    public ModelAndView showTaskAddContent(){
        return new ModelAndView("ad/ad-push-task-add");
    }

    /**
     * @return 闲时广告发布页面
     */
    @GetMapping("/task/add/leisure/view")
    @Security(token = {"ad:push:task:insert","ad:push:leisure:task:insert"},format = DataFormatEnum.VIEW)
    public ModelAndView leisureTaskPushView(){
        return new ModelAndView("ad/ad-leisure-task-add");
    }

    /**
    * @return 线下广告发布页面
     */
    @GetMapping("/task/add/offline/view")
    @Security(token = {"ad:push:offline:insert"},format = DataFormatEnum.VIEW)
    public ModelAndView offlineTaskPushView(){
        return new ModelAndView("ad-offline-push-add");
    }
    /**
     * 功能描述:新增/编辑广告类容
     * @param task  任务详情
     */
    @PostMapping (value = "/task/add")
    @Security(token = {"ad:push:task:insert","ad:push:leisure:task:insert","ad:push:offline:insert"},format = DataFormatEnum.JSON)
    public @ResponseBody ResultBean<Boolean> addAdPushTask(AdPushTask task){
        Assert.notNull(task.getTaskType(),"任务类型不能为空");
        //  默认启用阈值配置
        if (null == task.getEnableThreshold()){
            task.setEnableThreshold(1);
        }
        //获取当前登录用户
        Account onLineUser = this.securityServiceInterface.getOnLineUser();
        task.setCreateAccountId(onLineUser.getId());
        task.setCreateAccountName(onLineUser.getLoginName());
        task.setOrgId(onLineUser.getOrgId());
        task.setCreateDate(new Date());
        task.setRootOrgId(onLineUser.getRootOrgId());
        //发布状态{ -1：发布失败，0：待发布，1：发布成功，2：已撤销
        task.setPushStatus(OperationConstant.ZERO);
        task.setOrgPosition(onLineUser.getOrgPosition());
        // 发布总次数--初始化站位
        task.setPushCount((long) 0);
        //发布成功次数--初始化站位
        task.setPushSuccess((long) 0);
        //广告预计发布时间
        Calendar calendar = Calendar.getInstance();
        //  日期加一天
//        calendar.add(Calendar.DATE, 1);
//        // 将分秒,毫秒域清零,时设置到凌晨2点
//        calendar.set(Calendar.HOUR_OF_DAY, 2);
//        calendar.set(Calendar.MINUTE, 0);
//        calendar.set(Calendar.SECOND, 0);
//        calendar.set(Calendar.MILLISECOND, 0);
        //广告任务的预计发布时间--第二天凌晨2:00
        task.setEstimatePushDate(calendar.getTime());
        ResultBean<Boolean>  resultBean=this.adPushTaskFeign.addAdPushTask(task);
        if(resultBean.getData()!=null && resultBean.getData()){
            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.AD_PUSH_TASK_MANAGE, SysLogConstant.ADD_EVENT,
                    WebUtils.getIp(),task,onLineUser,task);
            sysOperationLogFeign.info(sysOperationLog);
            /*-------------------------------------------------------------------------------------------------------------------*/
        }
        return resultBean;
    }

    /**
     * 功能描述:任务撤销
     * @param id 任务id
     * @return
     */
    @GetMapping(value = "/task/cancel/{id}")
    @Security(token = {"ad:push:task:cancel","ad:push:leisure:task:cancel"},format = DataFormatEnum.JSON)
    public ResultBean<Boolean> cancelAdPushTask(@PathVariable(value = "id")Long id){
        AdPushTask oldObj = this.adPushTaskFeign.findAdPushTaskById(id);
        ResultBean<Boolean>  resultBean=this.adPushTaskFeign.cancelAdPushTask(id);
        if(resultBean.getData()!=null && resultBean.getData()){
            //获取当前登录用户
            Account onLineUser = this.securityServiceInterface.getOnLineUser();
            AdPushTask adPushTask=new AdPushTask();
            adPushTask.setId(id);
            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.AD_PUSH_TASK_MANAGE, SysLogConstant.ALTER_EVENT,
                    WebUtils.getIp(),"任务撤销",adPushTask,onLineUser,oldObj);
            sysOperationLogFeign.info(sysOperationLog);
            /*-------------------------------------------------------------------------------------------------------------------*/
        }
        return resultBean;
    }
    /**
     * 功能描述:手动下发任务
     * @param
     * @return
     */
    @GetMapping(value = "/manually/issued/{id}")
    @Security(token = AdSecurityToken.AD_PUSH_MANUALLY_ISSUED,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> manuallyIssued(@PathVariable(value = "id")Long id){
        ResultBean<Boolean> resultBean = this.adPushTaskFeign.manuallyIssued(id);
        AdPushTask oldObj = this.adPushTaskFeign.findAdPushTaskById(id);
        if(resultBean.getData()!=null && resultBean.getData()){
            //获取当前登录用户
            Account onLineUser = this.securityServiceInterface.getOnLineUser();
            AdPushTask adPushTask=new AdPushTask();
            adPushTask.setId(id);
            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.AD_PUSH_TASK_MANAGE, SysLogConstant.ALTER_EVENT,
                    WebUtils.getIp(),"手动下发",adPushTask,onLineUser,oldObj);
            sysOperationLogFeign.info(sysOperationLog);
            /*-------------------------------------------------------------------------------------------------------------------*/
        }
        return resultBean;
    }

    /**
     * 功能描述:阈值设置
     * @return ModelAndView
     */
    @GetMapping("/task/thresholdSet/view")
    @Security(token = {"ad:push:task:insert","ad:push:leisure:task:insert"},format = DataFormatEnum.VIEW)
    public ModelAndView showAdPushThresholdSet(){
        //获取当前登录用户
        Account onLineUser = this.securityServiceInterface.getOnLineUser();
        AdPushThresholdValue whereThresholdValue=new AdPushThresholdValue();
        whereThresholdValue.setType(OperationConstant.ZERO);
        whereThresholdValue.setOrgPosition(onLineUser.getOrgPosition());
        AdPushThresholdValue adPushThresholdValue=adPushTaskFeign.getAdPushThresholdValue(whereThresholdValue);
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("ad/ad-push-threshold-set");
        modelAndView.addObject("bean",adPushThresholdValue);
        return modelAndView;
    }

    /**
     * 功能描述:闲时广告保存阈值设置
     * @return ResultBean<Boolean>
     */
    @PostMapping(value = "/task/thresholdSet/save")
    @Security(token = AdSecurityToken.AD_PUSH_MANUALLY_ISSUED,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> saveThresholdSet(Integer count){
        AdPushThresholdValue adPushThresholdValue=new AdPushThresholdValue();
        adPushThresholdValue.setCount(count);
        //获取当前登录用户
        Account onLineUser = this.securityServiceInterface.getOnLineUser();
        //闲时广告设置
        adPushThresholdValue.setType(OperationConstant.ZERO);
        adPushThresholdValue.setRootOrgId(onLineUser.getRootOrgId());
        adPushThresholdValue.setOrgPosition(onLineUser.getOrgPosition());
        return this.adPushTaskFeign.savePushThresholdValue(adPushThresholdValue);
    }

//    /**
//     * 功能描述:查询出阈值设备
//     * @param adPushTaskDto 任务信息
//     * @return ResultBean<Page<Device>>
//     */
//    @PostMapping("/task/threshold/devices")
//    @Security(token = AdSecurityToken.AD_PUSH_MANUALLY_ISSUED,format = DataFormatEnum.JSON)
//    public ResultBean<List> thresholdDevices(AdPushTaskDto adPushTaskDto,String taskDeviceToken){
//        // 获取关联外键Id列表
//        Long[] fkIdList = adPushTaskDto.getAdPushTaskDetails();
//        // 构建发布内容体
//        PushTaskDto dto = new PushTaskDto();
//        dto.setPushType(adPushTaskDto.getPushType());
//        dto.setFkIdList(Arrays.asList(fkIdList));
//        List<Device> taskDevices =null;
//        List<Map<String,Object>> thresholdList=new ArrayList<>();
//        //缓存
//        ValueOperations<String, List<Device>> operations = redisTemplate.opsForValue();
//        taskDevices=operations.get(taskDeviceToken);
//        if(null==taskDevices){
//            taskDevices = pushTaskFeign.getTaskDevices(dto);
//            operations.set(taskDeviceToken,taskDevices,60*5, TimeUnit.SECONDS);
//        }
//        //获取人脸广告阈值
//        Account onLineUser = this.securityServiceInterface.getOnLineUser();
//        AdPushThresholdValue whereThresholdValue=new AdPushThresholdValue();
//        whereThresholdValue.setType(OperationConstant.ZERO);
//        whereThresholdValue.setOrgPosition(onLineUser.getOrgPosition());
//        AdPushThresholdValue adPushThresholdValue=adPushTaskFeign.getAdPushThresholdValue(whereThresholdValue);
//        Integer thresholdValue = adPushThresholdValue.getCount();
//        if(thresholdValue!=null&&thresholdValue>0){
//            taskDevices.forEach(device->{
//                Long deviceId=device.getId();
//                int validAdPushCount = adPushTaskFeign.getValidAdPushCountDevice(deviceId);
//                //超过阈值
//                if(validAdPushCount>=thresholdValue){
//                    //设备名称
//                    Map<String,Object> deviceMap=new HashMap<>(10);
//                    deviceMap.put("id",device.getId());
//                    deviceMap.put("name",device.getName());
//                    deviceMap.put("installPath",device.getInstallPath());
//                    deviceMap.put("count",validAdPushCount);
//                    thresholdList.add(deviceMap);
//                }
//            });
//        }
//        return new ResultBean<List>(ResultEnum.SUCCESS,thresholdList);
//    }
//
//    /**
//     * 功能描述:判断是否有阈值设备
//     * @param adPushTaskDto 任务信息
//     * @param taskDeviceToken
//     * @return ResultBean<Boolean>
//     */
//    @PostMapping("/task/threshold/isOver")
//    @Security(token = AdSecurityToken.AD_PUSH_MANUALLY_ISSUED,format = DataFormatEnum.JSON)
//    public ResultBean<Boolean> isOverThreshold(AdPushTaskDto adPushTaskDto,String taskDeviceToken){
//        boolean result=false;
//        // 获取关联外键Id列表
//        Long[] fkIdList = adPushTaskDto.getAdPushTaskDetails();
//        // 构建发布内容体
//        PushTaskDto dto = new PushTaskDto();
//        dto.setPushType(adPushTaskDto.getPushType());
//        dto.setFkIdList(Arrays.asList(fkIdList));
//        List<Device> taskDevices =null;
//        List<Map<String,Object>> thresholdList=new ArrayList<>();
//        //缓存
//        ValueOperations<String, List<Device>> operations = redisTemplate.opsForValue();
//        taskDevices=operations.get(taskDeviceToken);
//        if(null==taskDevices){
//            taskDevices = pushTaskFeign.getTaskDevices(dto);
//            operations.set(taskDeviceToken,taskDevices,60*5, TimeUnit.SECONDS);
//        }
//        //获取人脸广告阈值
//        Account onLineUser = this.securityServiceInterface.getOnLineUser();
//        AdPushThresholdValue whereThresholdValue=new AdPushThresholdValue();
//        whereThresholdValue.setType(OperationConstant.ZERO);
//        whereThresholdValue.setOrgPosition(onLineUser.getOrgPosition());
//        AdPushThresholdValue adPushThresholdValue=adPushTaskFeign.getAdPushThresholdValue(whereThresholdValue);
//        Integer thresholdValue = adPushThresholdValue.getCount();
//        if(thresholdValue!=null&&thresholdValue>0){
//            for(Device device:taskDevices){
//                Long deviceId=device.getId();
//                int validAdPushCount = adPushTaskFeign.getValidAdPushCountDevice(deviceId);
//                //超过阈值
//                if(validAdPushCount>=thresholdValue){
//                    //设备名称
//                    result=true;
//                    break;
//                }
//            }
//        }
//        return new ResultBean<>(ResultEnum.SUCCESS,result);
//    }
}
