package com.ho.business.controller;


import com.ho.business.entity.DeviceTypeCol;
import com.ho.business.entity.ModelDeviceCol;
import com.ho.business.entity.ModelTypeCol;
import com.ho.business.service.DeviceModelService;
import com.ho.business.service.ModelDeviceColService;
import com.ho.business.vo.req.deviceModel.DeviceColSelectReqVo;
import com.ho.business.vo.req.deviceModel.DeviceModelAddReqVo;
import com.ho.business.vo.req.deviceModel.DeviceModelDeleteReqVo;
import com.ho.business.vo.req.deviceModel.DeviceTypeColAddReq;
import com.ho.common.tools.annotation.HzPermission;
import com.ho.common.tools.annotation.LogAnnotation;
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.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.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
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 javax.validation.Valid;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author gyan
 * @desc: 设备端和模型的增删改查
 * @DateTime: 2023/3/7 16:43
 */
@RestController
@RequestMapping(ContextConstant.BUSINESS + "deviceModel")
@Api(tags = "业务模块-设备_模型字段管理")
public class DeviceModelController {

    @Autowired
    DeviceModelService deviceModelService;

    @Autowired
    ModelDeviceColService modelDeviceColService;

    @Autowired
    RedisService redisService;

    @Autowired
    RedissonClient redissonClient;

    //设备字典表 （新增 修改 查询入参（deviceType ） 删除（加判断逻辑，查看是否已经引用））
    @PostMapping("addBatchDevice")
    @ApiOperation(value = "新增设备字段接口")
    @LogAnnotation(title = "设备字段管理", action = "新增设备字段信息")
    @HzPermission(PermissionConstant.SYS_EMSDEVICE_ADD)
    public DataResult<DeviceTypeCol> addBatchDevice(@RequestBody @Validated DeviceModelAddReqVo vo) {

        //增加分布式锁
        //定义锁
        RLock lock = null;
        try {
            lock = redissonClient.getLock(RedisKeyConstant.LOCK_KEY_EQUIPMENT_FIELD);
            //获取锁,没有获取到锁的阻塞在lock.lock() 这行
            lock.lock();
            deviceModelService.addBatchDevice(vo);
        } finally {
            if (lock != null && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        return DataResult.success();
    }

    @PostMapping("addDeviceTypeCol")
    @ApiOperation(value = "新增单个设备字段接口")
    @LogAnnotation(title = "设备字段管理", action = "新增设备字段信息")
    public DataResult<DeviceTypeCol> addDeviceTypeCol(@RequestBody @Validated DeviceTypeColAddReq vo) {
        //增加分布式锁
        //定义锁
        RLock lock = null;
        try {
            lock = redissonClient.getLock(RedisKeyConstant.LOCK_KEY_EQUIPMENT_FIELD);
            //获取锁,没有获取到锁的阻塞在lock.lock() 这行
            lock.lock();
            deviceModelService.addDeviceTypeCol(vo);
        } finally {
            if (lock != null && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        return DataResult.success();
    }

    @PostMapping("deleteBatchDevice")
    @ApiOperation(value = "批量删除设备字段")
    @LogAnnotation(title = "设备字段管理", action = "批量删除设备字段")
    @HzPermission(PermissionConstant.SYS_EMSDEVICE_DELETE)
    public DataResult deleteBatchDevice(@RequestBody @Valid DeviceModelDeleteReqVo vo) {
        deviceModelService.deleteBatchDevice(vo);
        return DataResult.success();

    }

    @PostMapping("/deviceColPage")
    @ApiOperation(value = "分页查询设备字段接口")
    public DataResult<PageResult<DeviceTypeCol>> deviceColPage(@RequestBody DeviceColSelectReqVo vo) {
        //PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<DeviceTypeCol> deviceColPage = deviceModelService.deviceColPage(vo);
        //通过type和DeviceTypeColId 去关联表中查找数据，然后对比
        List<Integer> collect = deviceColPage.stream().map(DeviceTypeCol::getId).collect(Collectors.toList());
        List<ModelDeviceCol> modelDeviceCols = modelDeviceColService.selectByDeviceIds(collect, vo.getType());
        Map<Integer, List<ModelDeviceCol>> modelMap = modelDeviceCols.stream().collect(Collectors.groupingBy(ModelDeviceCol::getDeviceColId));
        for (DeviceTypeCol deviceTypeCol : deviceColPage) {
            if (modelMap.get(deviceTypeCol.getId()) != null) {
                deviceTypeCol.setChange(false);
            } else {
                deviceTypeCol.setChange(true);
            }
        }
        //PageResult pageResult = PageUtils.getPageResult(new PageInfo<>(deviceColPage));
        return DataResult.success(deviceColPage);
    }


    //模型字典表 （新增 修改 查询 删除）
    @PostMapping("/ModelColPage")
    @ApiOperation(value = "分页查询模型字段接口")
    public DataResult<PageResult<ModelTypeCol>> ModelColPage(@RequestBody DeviceColSelectReqVo vo) {
        List<ModelTypeCol> modelColPage = deviceModelService.ModelColPage(vo);
        //查询已经被使用过的模型字段 根据deviceType 和模型Id进行查询
        List<Integer> collect = modelColPage.stream().map(ModelTypeCol::getId).collect(Collectors.toList());

        List<ModelDeviceCol> modelDeviceCols = modelDeviceColService.selectByModelType(collect, vo.getType());

        //增加模型是否被使用判断
        Map<Integer, List<ModelDeviceCol>> modelMap = modelDeviceCols.stream().collect(Collectors.groupingBy(ModelDeviceCol::getModelColId));
        for (ModelTypeCol modelTypeCol : modelColPage) {
            if (modelMap.get(modelTypeCol.getId()) != null) {
                modelTypeCol.setChange(false);
            } else {
                modelTypeCol.setChange(true);
            }
        }
        return DataResult.success(modelColPage);
    }

    @PostMapping("addBatchModel")
    @ApiOperation(value = "新增模型字段接口")
    @HzPermission(PermissionConstant.SYS_EMSMODEL_ADD)
    @LogAnnotation(title = "模型字段管理", action = "新增模型字段信息")
    public DataResult<ModelTypeCol> addBatchModel(@RequestBody @Valid DeviceModelAddReqVo vo, HttpServletRequest request) {
        String token = request.getHeader(RedisKeyConstant.User.ACCESS_TOKEN);
        SimpleUser user = redisService.getSimpleUserByToken(token);
        vo.setGroupId(user.getGroupId());
        //增加分布式锁
        //定义锁
        RLock lock = null;
        try {
            lock = redissonClient.getLock(RedisKeyConstant.LOCK_KEY_MODEL_CONFIG);
            //获取锁,没有获取到锁的阻塞在lock.lock() 这行
            lock.lock();
            deviceModelService.addBatchModel(vo);
        } finally {
            if (lock != null && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        return DataResult.success();
    }

    @PostMapping("deleteBatchModel")
    @ApiOperation(value = "批量删除模型字段")
    @LogAnnotation(title = "模型字段管理", action = "批量删除模型字段")
    @HzPermission(PermissionConstant.SYS_EMSMODEL_DELETE)
    public DataResult deleteBatchModel(@RequestBody @Valid DeviceModelDeleteReqVo vo) {
        deviceModelService.deleteBatchModel(vo);
        return DataResult.success();

    }

}
