package com.sptg.gateway.controller.permissions;

import com.baomidou.mybatisplus.plugins.Page;
import com.sptg.common.core.beans.PageBean;
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.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.constant.DeviceSecurityToken;
import com.sptg.device.api.entity.Device;
import com.sptg.device.api.entity.FlowCardDevice;
import com.sptg.device.api.entity.InstructPublishLog;
import com.sptg.device.api.feigns.DeviceFeign;
import com.sptg.device.api.feigns.InstructPublishLogFeign;
import com.sptg.device.api.stream.DeviceUpdateProduceInterface;
import com.sptg.estate.api.constant.EstateSecurityToken;
import com.sptg.estate.api.dto.ResidentialDto;
import com.sptg.estate.api.entity.Residential;
import com.sptg.permissions.api.constant.PermissionsSecurityToken;
import com.sptg.permissions.api.dto.AppPackageDto;
import com.sptg.permissions.api.entity.Account;
import com.sptg.permissions.api.entity.AppPackage;
import com.sptg.permissions.api.entity.Organization;
import com.sptg.permissions.api.feigns.AppPackageFeign;
import com.sptg.statistics.api.constant.SysLogMenuConstant;
import com.sptg.statistics.api.entity.SysOperationLog;
import com.sptg.statistics.api.feigns.SysOperationLogFeign;
import lombok.AllArgsConstructor;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.util.Date;
import java.util.List;

/**
 * title: AppPackageController
 * package: com.sptg.gateway.controller.permissions
 * description:app安装包-控制器
 *
 *
 *
 */
@RestController
@RequestMapping(value = "/permissions/appPackage")
@AllArgsConstructor
public class AppPackageController {

    private final AppPackageFeign appPackageFeign;
    private final SecurityServiceInterface<Account> securityServiceInterface;
    private final SysOperationLogFeign sysOperationLogFeign;
    private final DeviceUpdateProduceInterface deviceUpdateProduceInterface;
    private final InstructPublishLogFeign instructPublishLogFeign;

    /**
     * 功能描述:分页查询app安装包列表
     * @param dto 查询条件
     * @param pageBean 分页条件
     * @return ResultBean<Page>
     *
     *
     */
    @GetMapping(value = "/pagingQuery")
    @Security(token = PermissionsSecurityToken.DEVICE_APP_PACKAGE,format = DataFormatEnum.JSON)
    public ResultBean<Page> pagingQuery(AppPackageDto dto, PageBean<AppPackage,AppPackageDto> pageBean){
        Account onLineUser = this.securityServiceInterface.getOnLineUser();
        dto.setOrgPosition(onLineUser.getOrgPosition());
        pageBean.setDto(dto);
        return this.appPackageFeign.pagingQuery(pageBean);
    }

    /**
     * 功能描述:app安装包添加
     * @param dto
     * @return  ResultBean<Boolean>
     *
     *
     */
    @PostMapping(value = "/add")
    @Security(token = PermissionsSecurityToken.DEVICE_APP_PACKAGE_ADD,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> addEntity(AppPackageDto dto){

        //  判断版本名称是否已存在
        boolean isPackageNameExist = this.appPackageFeign.checkPackageNameIsExist(dto.getPackageName());
        Assert.isTrue(!isPackageNameExist,"版本名称已存在");
        // 判断版本好是否已存在
        boolean isVersionExist = this.appPackageFeign.checkVersionIsExist(dto.getVersion());
        Assert.isTrue(!isVersionExist,"版本号已存在");

        Account onLineUser = this.securityServiceInterface.getOnLineUser();
        //机构位置
        dto.setOrgPosition(onLineUser.getOrgPosition());
        //状态
        dto.setStatus(OperationConstant.ZERO);
        //创建时间
        dto.setCreateDate(new Date());
        //创建人
        dto.setCreateAccountId(onLineUser.getId());
        //设置为正常包
        dto.setRestore(OperationConstant.ZERO);
        ResultBean<Boolean> resultBean = this.appPackageFeign.addEntity(dto);
        if(null!=resultBean.getData()&&resultBean.getData()){
            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.APP_PACKAGE, SysLogConstant.ADD_EVENT,
                    WebUtils.getIp(),dto,onLineUser,dto);
            sysOperationLogFeign.info(sysOperationLog);
            /*-------------------------------------------------------------------------------------------------------------------*/
        }
        return resultBean;
    }

    /**
     * 功能描述:设置恢复包
     * @param appIds
     * @return  ResultBean<Boolean>
     *
     *
     */
    @PostMapping(value = "/setRestore")
    @Security(token = PermissionsSecurityToken.DEVICE_APP_PACKAGE_SET_RESTORE,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> setRestore(@RequestBody List<String> appIds){
        if (null == appIds || appIds.size() <= 0){
            //  参数异常
            return new ResultBean<>(ResultEnum.PARAMETER_ANOMALY);
        }else{
            boolean b = this.appPackageFeign.setRestore(appIds);
            if(b){
                return new ResultBean<>(ResultEnum.SUCCESS,true);
            }else{
                return new ResultBean<>(ResultEnum.SUCCESS,false);
            }
        }
    }

    /**
     * 功能描述:app安装包信息修改
     * @param dto
     * @return public ResultBean<Boolean>
     *
     *
     */
    @PostMapping(value = "/edit")
    @Security(token = PermissionsSecurityToken.DEVICE_APP_PACKAGE_EDIT,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> editEntity(AppPackageDto dto){
        Account onLineUser = this.securityServiceInterface.getOnLineUser();
        AppPackage oldObj = this.appPackageFeign.getEntity(dto.getId());
        ResultBean<Boolean> resultBean = this.appPackageFeign.editEntity(dto);
        if(null!=resultBean.getData()&&resultBean.getData()){
            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            AppPackage newObj = this.appPackageFeign.getEntity(dto.getId());
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.APP_PACKAGE, SysLogConstant.ALTER_EVENT,
                    WebUtils.getIp(),dto,onLineUser,oldObj,newObj);
            sysOperationLogFeign.info(sysOperationLog);
            /*-------------------------------------------------------------------------------------------------------------------*/
        }
        return resultBean;
    }

    /**
     * 功能描述:根据id删除app安装包记录
     * @param id
     * @return ResultBean<Boolean>
     *
     *
     */
    @GetMapping(value = "/delete/{id}")
    @Security(token = PermissionsSecurityToken.DEVICE_APP_PACKAGE_DELETE,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> deleteEntity(@PathVariable(value="id") Long id){
        Account onLineUser = this.securityServiceInterface.getOnLineUser();
        AppPackage oldObj = this.appPackageFeign.getEntity(id);
        AppPackageDto dto=new AppPackageDto();
        dto.setId(id);
        //机构位置
        dto.setOrgPosition(onLineUser.getOrgPosition());
        ResultBean<Boolean> resultBean = this.appPackageFeign.deleteEntity(dto);
        if(null!=resultBean.getData()&&resultBean.getData()){
            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.APP_PACKAGE, SysLogConstant.DELETE_EVENT,
                    WebUtils.getIp(),dto,onLineUser,oldObj);
            sysOperationLogFeign.info(sysOperationLog);
            /*-------------------------------------------------------------------------------------------------------------------*/
        }
        return resultBean;
    }

    /**
     * 功能描述:全部升级
     * @param id
     * @return ResultBean<Boolean>
     *
     *
     */
    @GetMapping(value = "/allDeviceUpgrade/{id}")
    @Security(token = PermissionsSecurityToken.DEVICE_APP_PACKAGE_UPGRADE,format = DataFormatEnum.JSON)
    public ModelAndView allDeviceUpgrade(@PathVariable(value="id")Long id){
        AppPackage appPackage = this.appPackageFeign.getEntity(id);
        Assert.notNull(appPackage,"安装包Id不存在");
        ModelAndView modelAndView = new ModelAndView("device/device-app-package-upgrade");
        modelAndView.addObject("id",id);
        modelAndView.addObject("deviceFactory",appPackage.getDeviceFactory());
        modelAndView.addObject("deviceModelNumber",appPackage.getDeviceModelNumber());
        modelAndView.addObject("version",appPackage.getVersion());
        return modelAndView;
    }

    /**
     * 功能描述:部分设备升级
     * @return ResultBean<Boolean>
     *
     *
     */
    @PostMapping(value = "/deviceUpgrade")
    @Security(token = PermissionsSecurityToken.DEVICE_APP_PACKAGE_UPGRADE,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> deviceUpgrade(Long [] deviceIds){
        Assert.isTrue(deviceIds.length > 0,"请选中需要更新的设备");
        //  异步下发更新指令
        AppPackage appPackage = new AppPackage();
        appPackage.setUpdateMethod(2);
        appPackage.setDeviceIds(deviceIds);
        Message<AppPackage> build = MessageBuilder.withPayload(appPackage).build();
        this.deviceUpdateProduceInterface.output().send(build);
        return new ResultBean<>(ResultEnum.SUCCESS,true);
    }

    @GetMapping(value = "/getPackagePageByFactory")
    @Security(token = PermissionsSecurityToken.DEVICE_APP_PACKAGE,format = DataFormatEnum.JSON)
    public ResultBean<Page> getPackagePageByFactory(AppPackageDto dto, PageBean<AppPackage,AppPackageDto> pageBean){
        Account onLineUser = this.securityServiceInterface.getOnLineUser();
        dto.setOrgPosition(onLineUser.getOrgPosition());
        pageBean.setDto(dto);
        return this.appPackageFeign.pagingQuery(pageBean);
    }

    /**
     * 功能描述:部分设备选择升级包升级【设备列表选择版本升级】
     * @return ResultBean<Boolean>
     *
     *
     */
    @PostMapping(value = "/deviceSelectPackageUpgrade")
    @Security(token = PermissionsSecurityToken.DEVICE_APP_PACKAGE_UPGRADE,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> deviceSelectPackageUpgrade(AppPackage appPackage){
        String[] ids = appPackage.getDeviceId().split(",");
        Long[] deviceIds = new Long[ids.length];
        for (int i = 0; i < ids.length; i++){
            deviceIds[i] = Long.parseLong(ids[i]);
        }
        Assert.isTrue(deviceIds.length > 0,"请选中需要更新的设备");
        AppPackage dbAppPackage = this.appPackageFeign.getEntity(appPackage.getId());
        Assert.notNull(dbAppPackage,"所选升级包不存在");
        dbAppPackage.setUpdateMethod(3);
        dbAppPackage.setDeviceIds(deviceIds);
        Message<AppPackage> build = MessageBuilder.withPayload(dbAppPackage).build();
        this.deviceUpdateProduceInterface.output().send(build);
        return new ResultBean<>(ResultEnum.SUCCESS,true);
    }

    /**
     * 功能描述:更新启用状态
     * @param dto
     * @return ResultBean<Boolean>
     *
     *
     */
    @PostMapping(value = "/updateEnable")
    @Security(token = PermissionsSecurityToken.DEVICE_APP_PACKAGE_ENABLE,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> updateEnable(AppPackageDto dto){
        Account onLineUser = this.securityServiceInterface.getOnLineUser();
        //机构位置
        dto.setOrgPosition(onLineUser.getOrgPosition());
        return this.appPackageFeign.updateEnable(dto);
    }

    /**
     * 功能描述: 根据版本号模糊查询
     * @param dto
     * @return ResultBean<AppPackage>
     *
     */
    @GetMapping(value = "/getListByLikeVersion")
    @Security(format = DataFormatEnum.JSON)
    public ResultBean<AppPackage> getListByLikeVersion(AppPackageDto dto){
        return this.appPackageFeign.getListByLikeVersion(dto);
    }

    /**
     * 功能描述:设备升级页面初始化
     * @return ModelAndView
     */
    @GetMapping("/log4appPackage")
    @Security(token = PermissionsSecurityToken.DEVICE_APP_PACKAGE_LOG,format = DataFormatEnum.VIEW)
    public ModelAndView log4appPackage(String version){
        ModelAndView modelAndView = new ModelAndView("device/log-app-package");
        modelAndView.addObject("version", version);
        return modelAndView;
    }

    /**
     * 获取版本升级日志
     * @param publishLog（publishData附带version信息，用于匹配过滤）
     * @param pageBean
     * @return
     */
    @GetMapping(value = "/pageAppPackage")
    @Security(token = PermissionsSecurityToken.DEVICE_APP_PACKAGE_LOG,format = DataFormatEnum.JSON)
    public ResultBean<Page> pageAppPackage(InstructPublishLog publishLog, PageBean<InstructPublishLog,InstructPublishLog> pageBean){
        pageBean.setDto(publishLog);
        return this.instructPublishLogFeign.pageAppPackage(pageBean);
    }
}
