package com.ho.business.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ho.business.constant.DeviceTypeConstant;
import com.ho.business.entity.DeviceTypeConfig;
import com.ho.business.entity.Station;
import com.ho.business.service.DeviceService;
import com.ho.business.service.DeviceTypeConfigService;
import com.ho.business.service.StationService;
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.resp.DeviceRespVO;
import com.ho.business.vo.resp.device.DeviceTypeSimpleResp;
import com.ho.common.tools.annotation.HzPermission;
import com.ho.common.tools.annotation.LogAnnotation;
import com.ho.common.tools.constant.CommonConstant;
import com.ho.common.tools.constant.ContextConstant;
import com.ho.common.tools.constant.PermissionConstant;
import com.ho.common.tools.constant.RedisKeyConstant;
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 com.ho.common.tools.util.PageUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author fancl
 * @desc: 设备类型配置
 * @date 2023/3/18
 */
@RestController
@RequestMapping(ContextConstant.BUSINESS + "deviceConfig")
@Api(tags = "业务模块-设备类型配置")
public class DeviceTypeConfigController {

    @Autowired
    DeviceTypeConfigService deviceTypeConfigService;

    @Autowired
    StationService stationService;

    @Autowired
    DeviceService deviceService;

    @Autowired
    RedisService redisService;

    @PostMapping("page")
    @ApiOperation(value = "分页查询设备类型配置列表")
    public DataResult<PageResult<DeviceTypeConfig>> page(@RequestBody DeviceStationPageReqVo reqVo, HttpServletRequest request) {
        //根据token查用户
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser user = redisService.getSimpleUserByToken(token);
        //改为从预置的简化表中查有效的设备
        DeviceTypeQuery deviceTypeQuery = new DeviceTypeQuery();
        deviceTypeQuery.setGroupId(user.getGroupId());
        deviceTypeQuery.setStationId(reqVo.getStationId());
        //查集团和该电站的设备类型
        //deviceTypeQuery.setType("all");
        PageHelper.startPage(reqVo.getPageNum(), reqVo.getPageSize());
        List<DeviceTypeConfig> deviceTypeConfigs = deviceTypeConfigService.queryListByCondition(deviceTypeQuery);
        //看有几个站
        Map<Integer, List<DeviceTypeConfig>> stationDeviceMap = deviceTypeConfigs.stream().filter(d -> d.getStationId() != null)
                .collect(Collectors.groupingBy(DeviceTypeConfig::getStationId));
        Map<Integer, String> stationMap = new HashMap<>();
        for (Integer stationId : stationDeviceMap.keySet()) {
            Station station = stationService.selectById(stationId);
            if (station != null) {
                stationMap.putIfAbsent(station.getId(), station.getName());
            }

        }
        //补充电站名称
        for (DeviceTypeConfig deviceTypeConfig : deviceTypeConfigs) {
            if (stationMap.containsKey(deviceTypeConfig.getStationId())) {
                deviceTypeConfig.setStationName(stationMap.get(deviceTypeConfig.getStationId()));
            }
        }
        return DataResult.success(PageUtils.getPageResult(new PageInfo<>(deviceTypeConfigs)));
    }

    @PostMapping("queryDeviceTypeListForGroup")
    @ApiOperation(value = "scope是电站的时候查询集团级别的设备类型")
    public DataResult<List<DeviceTypeConfig>> queryDeviceTypeListForGroup(HttpServletRequest request) {
        //根据token查用户
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser user = redisService.getSimpleUserByToken(token);
        DeviceTypeQuery deviceTypeQuery = new DeviceTypeQuery();
        deviceTypeQuery.setGroupId(user.getGroupId());
        deviceTypeQuery.setScope(DeviceTypeConstant.SCOPE_GROUP);
        List<DeviceTypeConfig> deviceTypeConfigs = deviceTypeConfigService.queryListByCondition(deviceTypeQuery);
        return DataResult.success(deviceTypeConfigs);
    }

    //查询单个
    @PostMapping("findOne")
    @ApiOperation(value = "根据id查询单个对象")
    public DataResult<DeviceTypeConfig> findOne(@RequestBody DeviceIdReqVo reqVo) {
        DeviceTypeConfig deviceTypeConfig = deviceTypeConfigService.queryById(reqVo.getId());
        if (deviceTypeConfig == null) {
            throw new BusinessException(BaseResponseCode.DATA_NOT_EXISTS);
        }
        return DataResult.success(deviceTypeConfig);
    }

    @PostMapping("queryListByStation")
    @ApiOperation(value = "按电站查询设备类型,维护设备的设备类型时使用")
    public DataResult<List<DeviceTypeConfig>> queryListByStation(@RequestBody DeviceStationReqVo reqVo, HttpServletRequest request) {
        //根据token查用户
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser user = redisService.getSimpleUserByToken(token);
        //改为从预置的简化表中查有效的设备
        DeviceTypeQuery deviceTypeQuery = new DeviceTypeQuery();
        deviceTypeQuery.setGroupId(user.getGroupId());
        deviceTypeQuery.setStationId(reqVo.getStationId());
        //查集团和该电站的设备类型
        deviceTypeQuery.setType("all");
        List<DeviceTypeConfig> deviceTypeConfigs = deviceTypeConfigService.queryListByCondition(deviceTypeQuery);
        return DataResult.success(deviceTypeConfigs);
    }

    @PostMapping("queryList")
    @ApiOperation(value = "根据用户所在组，查询集团级的设备类型")
    public DataResult<List<DeviceTypeConfig>> queryList(HttpServletRequest request) {
        //根据token查用户
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser user = redisService.getSimpleUserByToken(token);
        //改为从预置的简化表中查有效的设备
        DeviceTypeQuery deviceTypeQuery = new DeviceTypeQuery();
        deviceTypeQuery.setGroupId(user.getGroupId());
        //查集团设备类型
        deviceTypeQuery.setScope(CommonConstant.ONE);
        List<DeviceTypeConfig> deviceTypeConfigs = deviceTypeConfigService.queryListByCondition(deviceTypeQuery);
        return DataResult.success(deviceTypeConfigs);
    }

    @PostMapping("queryDeviceTypeByGroup")
    @ApiOperation(value = "查集团设备类型(只显示大类型)")
    public DataResult<List<DeviceTypeSimpleResp>> queryDeviceTypeByGroup(HttpServletRequest request) {
        //根据token查用户
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser user = redisService.getSimpleUserByToken(token);
        //改为从预置的简化表中查有效的设备
        DeviceTypeQuery deviceTypeQuery = new DeviceTypeQuery();
        deviceTypeQuery.setGroupId(user.getGroupId());
        //查集团级
        deviceTypeQuery.setScope(DeviceTypeConstant.SCOPE_GROUP);
        List<DeviceTypeConfig> deviceTypeConfigs = deviceTypeConfigService.queryListByCondition(deviceTypeQuery);
        //要返回的结果对象
        List<DeviceTypeSimpleResp> deviceTypeList = new ArrayList<>();
        //各种逆变器类型需要汇总,截取_前面的
        String deviceTypeNew = null;
        for (DeviceTypeConfig deviceTypeConfig : deviceTypeConfigs) {
            deviceTypeNew = deviceTypeConfig.getDeviceType();
            if (deviceTypeNew.contains("_")) {
                deviceTypeNew = deviceTypeNew.substring(0, deviceTypeNew.indexOf("_"));
                deviceTypeConfig.setDeviceType(deviceTypeNew);
            }
        }
        Map<String, List<DeviceTypeConfig>> deviceTypeMap = deviceTypeConfigs.stream().collect(Collectors.groupingBy(DeviceTypeConfig::getDeviceType));
        for (Map.Entry<String, List<DeviceTypeConfig>> entry : deviceTypeMap.entrySet()) {
            DeviceTypeSimpleResp deviceTypeSimple = new DeviceTypeSimpleResp();
            deviceTypeSimple.setDeviceType(entry.getKey());
            DeviceTypeConfig deviceTypeConfig = entry.getValue().get(0);
            String deviceTypeName = deviceTypeConfig.getName();
            if (deviceTypeName.contains("(")) {
                deviceTypeName = deviceTypeName.substring(0, deviceTypeName.indexOf("("));
            }
            deviceTypeSimple.setDeviceTypeName(deviceTypeName);
            deviceTypeList.add(deviceTypeSimple);
        }

        return DataResult.success(deviceTypeList);
    }

    @PostMapping("add")
    @ApiOperation(value = "新增一个设备类型配置")
    @LogAnnotation(title = "业务模块-设备类型配置", action = "新增设备类型配置")
    @HzPermission(PermissionConstant.SYS_DEVICETYPE_ADD)
    public DataResult add(@RequestBody DeviceTypeConfigAddReq reqVo, HttpServletRequest request) {
        //根据token查用户
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser user = redisService.getSimpleUserByToken(token);
        Integer stationId = null;
        Station station = null;
        //平台用户不能新增,需要集团用户新增
        if (CommonConstant.ZERO.equals(user.getDeptId())) {
            throw new BusinessException(BaseResponseCode.PLAT_USER_CANNOT_OPERATE);
        }
        DeviceTypeQuery deviceTypeQuery = new DeviceTypeQuery();
        deviceTypeQuery.setGroupId(user.getGroupId());
        deviceTypeQuery.setScope(reqVo.getScope());
        //判断是否有重复数据
        //是集团就排除电站,只有电站才带上stationId
        if (DeviceTypeConstant.SCOPE_STATION.equals(reqVo.getScope())) {
            //当为电站时,电站id必须传递
            if (reqVo.getStationId() == null) {
                throw new BusinessException(BaseResponseCode.SCOPE_IS_STATION_ID_CANNOT_NULL);
            }
            stationId = reqVo.getStationId();
            station = stationService.selectById(stationId);
            if (station == null) {
                throw new BusinessException(BaseResponseCode.STATION_YC_NOT_EXISTS);
            }
            deviceTypeQuery.setStationId(stationId);
            //电站维度,因为前端传入的deviceType是集团的,所以查询时需要做个处理,把 deviceType 加上电站后缀
            String stationDeviceType = reqVo.getDeviceType() + "_" + station.getId();
            deviceTypeQuery.setDeviceType(stationDeviceType);
            deviceTypeQuery.setName(null);
        } else if (DeviceTypeConstant.SCOPE_GROUP.equals(reqVo.getScope())) {
            //集团级
            //devicetype 做重复判断
            deviceTypeQuery.setDeviceType(reqVo.getDeviceType());
            /* deviceTypeQuery.setName(reqVo.getName());*/
        }
        //模型名不需要判断重复
        //判断是否有同名的
        List<DeviceTypeConfig> deviceTypeConfigs = deviceTypeConfigService.queryListByCondition(deviceTypeQuery);
        if (!deviceTypeConfigs.isEmpty()) {
            throw new BusinessException(BaseResponseCode.STATION_ALREADY_EXISTS);
        }
        //创建入库数据
        DeviceTypeConfig deviceTypeConfig = new DeviceTypeConfig();
        //这几个字段是公共的
        deviceTypeConfig.setGroupId(user.getGroupId());
        deviceTypeConfig.setScope(reqVo.getScope());
        deviceTypeConfig.setModelName(reqVo.getModelName());
        //集团级 的 设备类型使用用户输入的
        if (DeviceTypeConstant.SCOPE_GROUP.equals(reqVo.getScope())) {
            deviceTypeConfig.setDeviceType(reqVo.getDeviceType());
            deviceTypeConfig.setName(reqVo.getName());

        } else if (DeviceTypeConstant.SCOPE_STATION.equals(reqVo.getScope())) {
            deviceTypeConfig.setStationId(reqVo.getStationId());
            //电站维度的设备类型 是全局类型 增加_stationId后缀
            deviceTypeConfig.setDeviceType(reqVo.getDeviceType() + "_" + station.getId());
            deviceTypeConfig.setName(reqVo.getName() + "_" + station.getName());
        }
        //创建人 创建时间
        deviceTypeConfig.setCreator(user.getUserId());
        deviceTypeConfig.setCreateTime(new Date());
        //scope是集团级 name不做修改, 如果是电站级 ,deviceType后缀加上电站id
        deviceTypeConfigService.add(deviceTypeConfig);
        return DataResult.success();
    }

    @PostMapping("update")
    @ApiOperation(value = "更新设备类型配置")
    public DataResult update(@RequestBody DeviceTypeConfigAddReq reqVo) {
        deviceTypeConfigService.update(reqVo);
        return DataResult.success();
    }


    @PostMapping("delete")
    @ApiOperation(value = "删除一个设备类型配置")
    @LogAnnotation(title = "业务模块-设备类型配置", action = "删除设备类型配置")
    @HzPermission(PermissionConstant.SYS_DEVICETYPE_DELETE)
    public DataResult delete(@RequestBody DeviceIdReqVo reqVo, HttpServletRequest request) {
        //先查是否有这个id
        DeviceTypeConfig deviceTypeConfig = deviceTypeConfigService.queryById(reqVo.getId());
        if (deviceTypeConfig == null) {
            throw new BusinessException(BaseResponseCode.DATA_NOT_EXISTS);
        }
        //根据token查用户
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser user = redisService.getSimpleUserByToken(token);
        //device表被引用就不能删除
        DeviceReqVO deviceReqVO = new DeviceReqVO();
        deviceReqVO.setGroupId(user.getGroupId());
        List<String> deviceTypeList = new ArrayList<>();
        deviceTypeList.add(deviceTypeConfig.getDeviceType());
        deviceReqVO.setDeviceTypeList(deviceTypeList);
        List<DeviceRespVO> deviceList = deviceService.getList(deviceReqVO);
        if (!deviceList.isEmpty()) {
            throw new BusinessException(BaseResponseCode.REFERENCES_EXIST_DELETED_DATA);
        }
        //逻辑删除,记录删除信息
        DeviceTypeConfig deviceTypeConfigDeleted = new DeviceTypeConfig();
        deviceTypeConfigDeleted.setId(deviceTypeConfig.getId());
        deviceTypeConfigDeleted.setDeleted(CommonConstant.DELETED_FLAG);
        deviceTypeConfigService.updateById(deviceTypeConfigDeleted);
        return DataResult.success();
    }

    @PostMapping("/syDeviceTypeConfig")
    @ApiOperation(value = "一键同步设备类型配置")
    @LogAnnotation(title = "业务模块-设备类型配置", action = "一键同步设备类型配置")
    public DataResult syDeviceTypeConfig(@RequestBody SynchronousReqVo vo) {
        if (vo.getStationId() == null) {
            throw new BusinessException(BaseResponseCode.PLEASE_CHECK_SRC_STATION);
        }
        if (vo.getModelStationId() == null || vo.getDesStationName() == null) {
            throw new BusinessException(BaseResponseCode.PLEASE_CHECK_MODEL_STATION);
        }
        int result = deviceTypeConfigService.syDeviceTypeConfig(vo);
        return DataResult.success(result);
    }
}
