package com.ho.business.controller;

import com.alibaba.fastjson.JSONObject;
import com.ho.business.common.BusiTool;
import com.ho.business.constant.DeviceTypeConstant;
import com.ho.business.entity.Device;
import com.ho.business.entity.DeviceType;
import com.ho.business.entity.DeviceTypeConfig;
import com.ho.business.service.DeviceCallService;
import com.ho.business.service.DeviceService;
import com.ho.business.service.DeviceTypeConfigService;
import com.ho.business.vo.req.DeviceByDeviceTypeReq;
import com.ho.business.vo.req.DeviceReqVO;
import com.ho.business.vo.req.device.*;
import com.ho.business.vo.req.deviceModel.SynchronousReqVo;
import com.ho.business.vo.req.export.ExportReq;
import com.ho.business.vo.resp.DeviceRespVO;
import com.ho.business.vo.resp.point.DevicePointResp;
import com.ho.common.tools.annotation.HzPermission;
import com.ho.common.tools.annotation.LogAnnotation;
import com.ho.common.tools.annotation.TokenIgnore;
import com.ho.common.tools.constant.*;
import com.ho.common.tools.entity.SimpleUser;
import com.ho.common.tools.exception.BaseResponseCode;
import com.ho.common.tools.exception.BusinessException;
import com.ho.common.tools.exception.DataResult;
import com.ho.common.tools.service.RedisService;
import com.ho.common.tools.util.PageResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description 设备管理
 * Author yule
 * Date 2022/10/13 11:35
 */
@RestController
@RequestMapping(ContextConstant.BUSINESS + "device")
@Api(tags = "业务模块-设备管理")
public class DeviceController {

    @Autowired
    DeviceService deviceService;

    @Autowired
    DeviceTypeConfigService deviceTypeConfigService;

    @Autowired
    RedisService redisService;

    @Autowired
    BusiTool busiTool;

    @Autowired
    DeviceCallService deviceCallService;

    @PostMapping("page")
    @ApiOperation(value = "设备列表,分页")
    public DataResult<PageResult<DeviceRespVO>> page(@RequestBody @Valid DeviceReqVO deviceReqVO, HttpServletRequest request) {
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser simpleUser = busiTool.getSimpleUser(token);
        //设置集团id
        deviceReqVO.setGroupId(simpleUser.getGroupId());
        //如果 stationId没传 要查所辖电站的数据
        Integer stationId = deviceReqVO.getStationId();
        if (StringUtils.isEmpty(stationId)) {
            deviceReqVO.setStationIds(simpleUser.getStationIds());
        }
        PageResult<DeviceRespVO> list = deviceService.getPageListByInfo(deviceReqVO);
        return DataResult.success(list);
    }

    @PostMapping("add")
    @ApiOperation(value = "新增设备(做虚拟设备新增使用)")
    @LogAnnotation(title = "业务模块-设备管理", action = "新增设备虚拟设备")
    public DataResult add(@RequestBody @Valid DeviceAddReq adddevice) {
        deviceService.insertBatch(adddevice);
        return DataResult.success();
    }

    @PostMapping("update")
    @ApiOperation(value = "修改设备属性")
    @LogAnnotation(title = "业务模块-设备管理", action = "修改设备属性")
    @HzPermission(PermissionConstant.SYS_DEVICE_EDIT)
    public DataResult update(@RequestBody @Valid DeviceUpdateReq deviceUpdateReq) {
        //先查设备是否存在
        Device deviceQuery = deviceService.selectById(deviceUpdateReq.getId());
        if (deviceQuery == null) {
            throw new BusinessException(BaseResponseCode.DATA_NOT_EXISTS);
        }
//        if (deviceUpdateReq.getDeviceType() == null) {
//            throw new BusinessException(BaseResponseCode.CHOOSE_DEVICE);
//        }
        Device device = new Device();
        device.setId(deviceUpdateReq.getId());

        if (deviceUpdateReq.getDeviceName() != null) {
            device.setDeviceName(deviceUpdateReq.getDeviceName());
        }
        if (deviceUpdateReq.getDeviceType() != null) {
            device.setDeviceType(deviceUpdateReq.getDeviceType());
        }
        if (!StringUtils.isEmpty(deviceUpdateReq.getHide())) {
            device.setHide(deviceUpdateReq.getHide());
        }
        device.setProducer(deviceUpdateReq.getProducer());
        if (!StringUtils.isEmpty(deviceUpdateReq.getFlowDirection())) {
            device.setFlowDirection(deviceUpdateReq.getFlowDirection());
        }
        if (deviceUpdateReq.getProducerType() != null) {
            device.setProducerType(deviceUpdateReq.getProducerType());
        }
        if (deviceUpdateReq.getUnitType() != null) {
            device.setUnitType(deviceUpdateReq.getUnitType());
        }
        device.setGroupId(deviceQuery.getGroupId());
        device.setStationId(deviceQuery.getStationId());
        device.setVirtual(deviceQuery.getVirtual());
        device.setSrcId(deviceQuery.getSrcId());
        int i = deviceService.update(device);
        return DataResult.success();
    }


    @PostMapping("one")
    @ApiOperation(value = "根据id查询单个设备")
    public DataResult<DeviceRespVO> getDevice(@RequestBody DeviceIdReqVo deviceId) {
        DeviceRespVO deviceRespVO = deviceService.getDeviceRespVO(deviceId.getId());
        return DataResult.success(deviceRespVO);
    }

    @PostMapping("deviceType")
    @ApiOperation(value = "查询电站下的设备类型列表，不分页")
    public DataResult<List<DeviceType>> selectByStationId(@RequestBody DeviceStationReqVo dvo, HttpServletRequest request) {
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser user = redisService.getSimpleUserByToken(token);
        if (null == dvo.getStationId()) {
            return DataResult.success(new ArrayList<>());
        }
        //根据电站id查询Device表中的device_type
        List<String> deviceList = deviceService.selectDistinctDeviceTypeByStationId(dvo.getStationId());
        deviceList.removeIf(s -> {
                    boolean flag = false;
                    if (DeviceTypeConstant.STATION.equals(s)) {
                        flag = true;
                    } else if (DeviceTypeConstant.WAREHOUSE.equals(s)) {
                        flag = true;
                    } else if (DeviceTypeConstant.BAY.equals(s)) {
                        flag = true;
                    }
                    return flag;
                }
        );
        if (deviceList.isEmpty()) {
            throw new BusinessException(BaseResponseCode.STATION_DEVICE_NOT_EXIST);
        }
        List<DeviceType> deviceTypes = new ArrayList<>();
        //再根据设备类型查询名称返回
        if (!deviceList.isEmpty()) {
            //改为从deviceTypeConfig表擦
            DeviceTypeQuery deviceTypeQuery = new DeviceTypeQuery();
            deviceTypeQuery.setGroupId(user.getGroupId());
            deviceTypeQuery.setDeviceTypeList(deviceList);
            List<DeviceTypeConfig> deviceTypeConfigs = deviceTypeConfigService.queryListByCondition(deviceTypeQuery);
            for (DeviceTypeConfig deviceTypeConfig : deviceTypeConfigs) {
                DeviceType deviceType = new DeviceType();
                deviceType.setTypeId(deviceTypeConfig.getId());
                deviceType.setDeviceType(deviceTypeConfig.getDeviceType());
                deviceType.setName(deviceTypeConfig.getName());
                deviceTypes.add(deviceType);
            }
        }
        return DataResult.success(deviceTypes);
    }

    @GetMapping("{stationId}")
    @ApiOperation(value = "查询电站下的设备列表")
    public DataResult<List<DeviceRespVO>> getDeviceByStationId(@PathVariable @Valid Integer stationId,HttpServletRequest request) {
        String lang = request.getHeader(CommonConstant.LANG);
        List<DeviceRespVO> deviceList = deviceService.getDeviceByStationId(stationId,lang);
        return DataResult.success(deviceList);
    }

    @PostMapping("DeviceByStationIds")
    @ApiOperation(value = "批量查询电站下的设备列表")
    public DataResult<List<DeviceRespVO>> getDeviceByStationIds(@RequestBody @Valid List<Integer> stationIds) {
        List<DeviceRespVO> deviceList = deviceService.getDeviceByStationIds(stationIds);
        return DataResult.success(deviceList);
    }

    @PostMapping("updateDevice")
    @ApiOperation(value = "修改设备属性")
    @HzPermission(PermissionConstant.SYS_DEVICE_EDIT)
    public DataResult updateDevice(@RequestBody @Valid DeviceUpdateReq deviceUpdateReq) {
        //先查设备是否存在
        Device deviceQuery = deviceService.selectById(deviceUpdateReq.getId());
        if (deviceQuery == null) {
            throw new BusinessException(BaseResponseCode.DATA_NOT_EXISTS);
        }
        if (deviceUpdateReq.getDeviceType() == null) {
            throw new BusinessException(BaseResponseCode.CHOOSE_DEVICE);
        }
        Device device = new Device();
        device.setId(deviceUpdateReq.getId());
        if (!StringUtils.isEmpty(deviceUpdateReq.getCategory())) {
            device.setCategory(deviceUpdateReq.getCategory());
        }
        if (!StringUtils.isEmpty(deviceUpdateReq.getDeviceName())) {
            device.setDeviceName(deviceUpdateReq.getDeviceName());
        }
        if (!StringUtils.isEmpty(deviceUpdateReq.getDeviceType())) {
            device.setDeviceType(deviceUpdateReq.getDeviceType());
        }
        /*if (deviceUpdateReq.getDeviceType() == null) {
            throw new BusinessException(BaseResponseCode.CHOOSE_DEVICE);
        }*/
        JSONObject jsonObject = new JSONObject();
        //设备型号,经度,维度等信息存入json
        if (deviceUpdateReq.getLatitude() != null) {
            jsonObject.put("latitude", deviceUpdateReq.getLatitude());
        }
        if (deviceUpdateReq.getLongitude() != null) {
            jsonObject.put("longitude", deviceUpdateReq.getLongitude());
        }
        if (deviceUpdateReq.getAddress() != null) {
            jsonObject.put("address", deviceUpdateReq.getAddress());
        }
        if (deviceUpdateReq.getDeviceModel() != null) {
            jsonObject.put("deviceModel", deviceUpdateReq.getDeviceModel());
        }
        if (deviceUpdateReq.getKwhFee() != null) {
            jsonObject.put("kwhFee", deviceUpdateReq.getKwhFee());
        }
        if (deviceUpdateReq.getServiceFee() != null) {
            jsonObject.put("serviceFee", deviceUpdateReq.getServiceFee());
        }
        if (!jsonObject.isEmpty()) {
            device.setDeviceJson(jsonObject);
        }

        int i = deviceService.updateChargePile(device);
        return DataResult.success();
    }

    @PostMapping("pageByDeviceType")
    @ApiOperation(value = "设备列表,不分页(设备批量下发页面查询使用)")
    public DataResult<List<DeviceRespVO>> pageByDeviceType(@RequestBody @Valid DeviceByDeviceTypeReq vo, HttpServletRequest request) {
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser simpleUser = busiTool.getSimpleUser(token);
        DeviceReqVO deviceReqVO = new DeviceReqVO();
        //设置集团id
        deviceReqVO.setGroupId(simpleUser.getGroupId());
        deviceReqVO.setDeviceTypePrefix(vo.getDeviceType());
        List<DeviceRespVO> pageListByDeviceType = deviceService.getListByDeviceType(deviceReqVO);
        return DataResult.success(pageListByDeviceType);
    }

    @PostMapping("getInterval")
    @ApiOperation(value = "查询电站下的间隔")
    public DataResult<List<DeviceRespVO>> getInterval(@RequestBody DeviceIntervalReqVo vo) {
        vo.setCategory(CommonConstant.TWO);
        List<DeviceRespVO> deviceList = deviceService.getIntervalDevice(vo);
        return DataResult.success(deviceList);
    }

    @PostMapping("getIntervalDevice")
    @ApiOperation(value = "查询间隔下的设备")
    public DataResult<List<DeviceRespVO>> getIntervalDevice(@RequestBody DeviceIntervalReqVo vo) {
        List<DeviceRespVO> deviceList = deviceService.getIntervalDevice(vo);
        return DataResult.success(deviceList);
    }

    @ApiOperation(value = "树状结构设备(设备带接入点，告警页面专用)")
    @PostMapping("treeDevices")
    public DataResult<List<DevicePointResp>> treeDevices(@RequestBody DeviceStationReqVo deviceTypeReq,HttpServletRequest request) {
        String lang = request.getHeader(CommonConstant.LANG);
        List<DeviceRespVO> deviceList = deviceService.selectAllDeviceAndSrcIdNotZero(deviceTypeReq.getStationId(),lang);
        List<DeviceRespVO> deviceRespVOS = deviceService.selectDeviceByStationId(deviceTypeReq.getStationId(),lang);
        Map<Integer, List<DeviceRespVO>> dataMap = deviceRespVOS.stream().collect(Collectors.groupingBy(DeviceRespVO::getId));
        for (DeviceRespVO deviceRespVO : deviceList) {
            if (!dataMap.containsKey(deviceRespVO.getId())) {
                deviceRespVOS.add(deviceRespVO);
            }
        }
        List<DevicePointResp> treeDevices = new ArrayList<>();
        if (!deviceRespVOS.isEmpty()) {
            treeDevices = deviceTypeConfigService.getTreeDevices(deviceRespVOS);
        }
        return DataResult.success(treeDevices);
    }

    @ApiOperation(value = "树状结构设备(储能总览，设备列表页面专用)")
    @PostMapping("homePageTreeDevices")
    public DataResult<List<DevicePointResp>> homePageTreeDevices(@RequestBody DeviceTreeReq vo,HttpServletRequest request) {
        String lang = request.getHeader(CommonConstant.LANG);
        List<DeviceRespVO> deviceRespVOS = deviceService.selectByIdAndSrcIdNotZero(vo.getStationId(),lang);
        List<DevicePointResp> treeDevices = new ArrayList<>();
        if (!deviceRespVOS.isEmpty()) {
            treeDevices = deviceTypeConfigService.getTreeDevices(deviceRespVOS, vo.getSrcId());
        }
        return DataResult.success(treeDevices);
    }

    @ApiOperation(value = "平铺过滤隐藏的真实设备(储能总览，设备列表页面APP专用)")
    @PostMapping("appHomePageDevices")
    public DataResult<List<DeviceRespVO>> appHomePageDevices(@RequestBody DeviceTreeReq vo,HttpServletRequest request) {
        String lang = request.getHeader(CommonConstant.LANG);
        List<DeviceRespVO> deviceRespVOS = deviceService.selectByIdAndSrcIdNotZero(vo.getStationId(),lang);
        deviceRespVOS = deviceRespVOS.stream().filter(i -> i.getCategory() > CommonConstant.TWO).collect(Collectors.toList());
        return DataResult.success(deviceRespVOS);
    }

    @ApiOperation(value = "根据条件生成树状结构设备")
    @PostMapping("treeVirtualDevices")
    public DataResult<List<DevicePointResp>> treeVirtualDevices(@RequestBody DeviceTreeReq vo,HttpServletRequest request) {
        String lang = request.getHeader(CommonConstant.LANG);
        List<DeviceRespVO> deviceRespVOS = deviceService.selectAllDeviceAndSrcIdNotZero(vo.getStationId(),lang);
        List<DevicePointResp> treeDevices = new ArrayList<>();
        if (null != deviceRespVOS && !deviceRespVOS.isEmpty()) {
            List<DeviceRespVO> deviceGroupRespVOS = deviceService.selectGroup(deviceRespVOS);
            if (!deviceGroupRespVOS.isEmpty()) {
                treeDevices = deviceTypeConfigService.getTreeDevices(deviceGroupRespVOS, vo.getSrcId());
            }
        }
        return DataResult.success(treeDevices);
    }

    @ApiOperation(value = "根据条件生成树状结构设备（真实设备）")
    @TokenIgnore
    @PostMapping("treeTrueDevices")
    public DataResult<List<DevicePointResp>> treeTrueDevices(@RequestBody DeviceTreeReq vo,HttpServletRequest request) {
        String lang = request.getHeader(CommonConstant.LANG);
        List<DeviceRespVO> deviceRespVOS = deviceService.selectAllDeviceAndSrcIdNotZero(vo.getStationId(),lang);
        deviceRespVOS = deviceRespVOS.stream().filter(i -> CommonConstant.ZERO.equals(i.getVirtual())).collect(Collectors.toList());
        List<DeviceRespVO> deviceGroupRespVOS = deviceService.selectGroup(deviceRespVOS);
        List<DevicePointResp> treeDevices = new ArrayList<>();
        if (!deviceGroupRespVOS.isEmpty()) {
            treeDevices = deviceTypeConfigService.getTreeDevices(deviceGroupRespVOS, vo.getSrcId());
        }
        return DataResult.success(treeDevices);
    }

    /**
     * 增加删除功能，且只删除新增的虚拟设备；
     *
     * @param deviceId
     * @return
     */
    @PostMapping("delete")
    @ApiOperation(value = "删除")
    @LogAnnotation(title = "业务模块-设备管理", action = "删除虚拟设备")
    public DataResult deletePlanningPolicy(@RequestBody DeviceIdReqVo deviceId) {
        deviceService.deleteById(deviceId.getId());
        return DataResult.success();
    }

    //4、增加一个真实设备列表（v0 c3）
    @PostMapping("getRealDevice")
    @ApiOperation(value = "查询电站下的真实设备")
    public DataResult<List<Device>> getRealDevice(@RequestBody DeviceIntervalReqVo vo) {
        Device device = new Device();
        device.setStationId(vo.getStationId());
        device.setVirtual(CommonConstant.ZERO);
        device.setCategory(CommonConstant.THREE);
        List<Device> deviceList = deviceService.getRealDevice(device);
        return DataResult.success(deviceList);
    }

    //加一个查询虚拟设备的接口
    @PostMapping("getVirtualDevice")
    @ApiOperation(value = "查询虚拟设备的接口")
    public DataResult<List<Device>> getVirtualDevice(@RequestBody DeviceIntervalReqVo vo) {
        Device device = new Device();
        device.setStationId(vo.getStationId());
        device.setVirtual(CommonConstant.ONE);
        device.setCategory(CommonConstant.THREE);
        device.setDeviceName(vo.getName());
        List<Device> deviceList = deviceService.getRealDevice(device);
        return DataResult.success(deviceList);
    }

    @PostMapping("getChildDevice")
    @ApiOperation(value = "查询设备下子设备")
    public DataResult<List<Device>> getChildDevice(@RequestBody DeviceIntervalReqVo vo) {
        Device device = new Device();
        device.setStationId(vo.getStationId());
        device.setPid(vo.getSrcId());
        List<Device> deviceList = deviceService.getRealDevice(device);
        return DataResult.success(deviceList);
    }

    //一键同步功能
    @PostMapping("/getSynchronousVD")
    @ApiOperation(value = "一键同步虚拟设备功能")
    @LogAnnotation(title = "业务模块-设备管理", action = "一键同步虚拟设备功能")
    //deviceType
    public DataResult getSynchronousVD(@RequestBody SynchronousReqVo vo) {
        deviceService.getSynchronousVD(vo);
        return DataResult.success();
    }

    /**
     * 导出数据
     * @param vo
     * @param response
     */
    @PostMapping("/exportExcel")
    @ApiOperation(value = "导出数据")
    public void exportExcel(@RequestBody ExportReq vo, HttpServletResponse response) {
        deviceService.exportExcel(vo,response);
    }


    /**
     * 导入文件
     * @param file
     * @param type
     */
    @PostMapping("/importExcel")
    @ApiOperation(value = "导入数据")
    public DataResult importExcel(@RequestBody MultipartFile file,@RequestParam Integer type) {
        deviceService.importExcel(file,type);
        return DataResult.success();
    }
}
