package com.usky.eg.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.usky.common.core.bean.CommonPage;
import com.usky.common.core.exception.BusinessException;
import com.usky.common.core.util.UUIDUtils;
import com.usky.common.security.utils.SecurityUtils;
import com.usky.eg.domain.EgDevice;
import com.usky.eg.domain.MeetingFace;
import com.usky.eg.domain.MeetingFaceDevice;
import com.usky.eg.mapper.EgDeviceMapper;
import com.usky.eg.mapper.MeetingFaceDeviceMapper;
import com.usky.eg.mapper.MeetingFaceMapper;
import com.usky.eg.service.EgDeviceService;
import com.usky.common.mybatis.core.AbstractCrudService;
import com.usky.eg.service.vo.EgDeviceRequestVO;
import com.usky.iot.RemoteIotTaskService;
import com.usky.transfer.RemoteTransferService;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 门禁_设备信息表 服务实现类
 * </p>
 *
 * @author zyj
 * @since 2024-11-27
 */
@Service
public class EgDeviceServiceImpl extends AbstractCrudService<EgDeviceMapper, EgDevice> implements EgDeviceService {
    @Autowired
    private MeetingFaceDeviceMapper meetingFaceDeviceMapper;
    @Autowired
    private MeetingFaceMapper meetingFaceMapper;
    @Autowired
    private EgDeviceMapper egDeviceMapper;
    @Autowired
    private RemoteIotTaskService remoteIotTaskService;

    @Autowired
    private RemoteTransferService remoteTransferService;

    @Override
    public CommonPage<EgDevice> page(EgDeviceRequestVO requestVO){
        IPage<EgDevice> page = new Page<>(requestVO.getCurrent(),requestVO.getSize());
        Integer tenantId ;

        if(StringUtils.isNotBlank(requestVO.getDomain())){
            tenantId = egDeviceMapper.sysTenantId(requestVO.getDomain());
        }else{
            tenantId = SecurityUtils.getTenantId();
        }

        LambdaQueryWrapper<EgDevice> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.like(StringUtils.isNotBlank(requestVO.getDeviceName()),EgDevice::getDeviceName,requestVO.getDeviceName())
                .like(StringUtils.isNotBlank(requestVO.getInstallAddress()),EgDevice::getInstallAddress,requestVO.getInstallAddress())
                .eq(null != requestVO.getServiceStatus(),EgDevice::getServiceStatus,requestVO.getServiceStatus())
                .eq(null != requestVO.getId(),EgDevice::getId,requestVO.getId())
                .eq(null != requestVO.getDeviceUuid(),EgDevice::getDeviceUuid, requestVO.getDeviceUuid())
                .eq(EgDevice::getTenantId,tenantId)
                .orderByDesc(EgDevice::getId);
        page = this.page(page,queryWrapper);
        if(!page.getRecords().isEmpty()){

            LambdaQueryWrapper<MeetingFace> meetingFaceQuery = Wrappers.lambdaQuery();
            meetingFaceQuery.select(MeetingFace::getFid,MeetingFace::getCreateTime,MeetingFace::getVefNum,MeetingFace::getFaceName,MeetingFace::getRemark,MeetingFace::getFaceStatus,MeetingFace::getCardNum,MeetingFace::getBindDevice,MeetingFace::getDeptId,MeetingFace::getTenantId,MeetingFace::getUserId)
                    .eq(MeetingFace::getTenantId,tenantId);
            List<MeetingFace> meetingAllFaceList = meetingFaceMapper.selectList(meetingFaceQuery);

            for (int i = 0; i < page.getRecords().size(); i++) {
                if(Objects.nonNull(page.getRecords().get(i).getBindFace()) ||StringUtils.isNotBlank(page.getRecords().get(i).getBindFace())){
                    String[] fidListStr = page.getRecords().get(i).getBindFace().split(",");
                    Integer[] fidList = Arrays.stream(fidListStr).map(Integer::parseInt).toArray(Integer[]::new);

                    List<MeetingFace> meetingFaceList = new ArrayList<>();
                    for (int j = 0; j < fidList.length; j++) {
                        for (int k = 0; k < meetingAllFaceList.size(); k++) {
                            if(fidList[j] == meetingAllFaceList.get(k).getFid()){
                                meetingFaceList.add(meetingAllFaceList.get(k));
                                break;
                            }
                        }
                    }
                    page.getRecords().get(i).setMeetingFaceList(meetingFaceList);
                }

            }
        }

        return new CommonPage<>(page.getRecords(),page.getTotal(),requestVO.getSize(),requestVO.getCurrent());
    }

    @Override
    public CommonPage<EgDevice> wePage(EgDeviceRequestVO requestVO){
        long userId = SecurityUtils.getUserId();
        //人员设备权限校验，校验通过，可以下发命令控制设备
        Integer fid = baseMapper.getMeetingFaceData(userId);
//        if(fid == null){
//            throw new BusinessException("人脸卡号信息未注册");
//        }
        Integer[] deviceFid = baseMapper.getMeetingFaceDeviceList(fid);
//        if(deviceFid.length == 0){
//            throw new BusinessException("人员未绑定设备，请检查");
//        }

        IPage<EgDevice> page = new Page<>(requestVO.getCurrent(),requestVO.getSize());
        if(deviceFid.length > 0){
            LambdaQueryWrapper<EgDevice> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.like(StringUtils.isNotBlank(requestVO.getDeviceName()),EgDevice::getDeviceName,requestVO.getDeviceName())
                    .like(StringUtils.isNotBlank(requestVO.getInstallAddress()),EgDevice::getInstallAddress,requestVO.getInstallAddress())
                    .eq(null != requestVO.getServiceStatus(),EgDevice::getServiceStatus,requestVO.getServiceStatus())
                    .eq(null != requestVO.getId(),EgDevice::getId,requestVO.getId())
                    .in(EgDevice::getId,deviceFid)
                    .eq(EgDevice::getTenantId,SecurityUtils.getTenantId())
                    .orderByDesc(EgDevice::getId);
            page = this.page(page,queryWrapper);
        }


        return new CommonPage<>(page.getRecords(),page.getTotal(),requestVO.getSize(),requestVO.getCurrent());
    }

    @Override
    public void add(EgDevice egDevice){
        if(checkNameUnique(egDevice)){
            throw new BusinessException("新增门禁门号设备'"+egDevice.getDeviceId()+","+egDevice.getEgNumber()+"'失败，设备已存在");
        }
        if(checkDeviceNameUnique(egDevice)){
            throw new BusinessException("新增门禁设备'"+egDevice.getDeviceName()+"'失败，设备已存在");
        }

        egDevice.setDeviceUuid(UUIDUtils.uuid());
        egDevice.setCreateBy(SecurityUtils.getUsername());
        egDevice.setCreateTime(LocalDateTime.now());
        egDevice.setTenantId(SecurityUtils.getTenantId());

        this.save(egDevice);

        String[] fids = new String[0];
        if(Objects.nonNull(egDevice.getBindFace()) || StringUtils.isNotBlank(egDevice.getBindFace())){
            fids = egDevice.getBindFace().split(",");
        }
        if(fids.length > 0){
            for (int i = 0; i < fids.length; i++) {
                egDeviceMapper.insertMeetingFaceDevice(Integer.parseInt(fids[i]),egDevice.getId());
            }
        }

        remoteIotTaskService.addDeviceInfo("502_USKY", egDevice.getDeviceUuid(),egDevice.getDeviceId()+egDevice.getEgNumber(),egDevice.getDeviceName(),egDevice.getInstallAddress(),egDevice.getServiceStatus());
    }

    @Override
    public void update(EgDevice egDevice) {

        String[] fids = new String[0];
        if(Objects.nonNull(egDevice.getBindFace()) || StringUtils.isNotBlank(egDevice.getBindFace())){
            fids = egDevice.getBindFace().split(",");

            egDeviceMapper.deleteMeetingFaceDevice(egDevice.getId());
        }else{
            EgDevice one = this.getById(egDevice.getId());
            egDevice.setBindFace(one.getBindFace());
        }
        if(fids.length > 0){
            for (int i = 0; i < fids.length; i++) {
                egDeviceMapper.insertMeetingFaceDevice(Integer.parseInt(fids[i]),egDevice.getId());
            }
        }


        if(checkNameUnique(egDevice)){
            throw new BusinessException("修改门禁门号设备'"+egDevice.getDeviceId()+","+egDevice.getEgNumber()+"'失败，设备已存在");
        }
        if(checkDeviceNameUnique(egDevice)){
            throw new BusinessException("新增门禁设备'"+egDevice.getDeviceName()+"'失败，设备已存在");
        }

        egDevice.setUpdateBy(SecurityUtils.getUsername());
        egDevice.setUpdateTime(LocalDateTime.now());

        this.updateById(egDevice);
    }

    @Override
    public void attachUpdate(EgDevice egDevice){

        EgDevice one = this.getById(egDevice.getId());
        egDevice.setBindFace(one.getBindFace());

        if(checkNameUnique(egDevice)){
            throw new BusinessException("更新门禁设备附加功能'"+egDevice.getDeviceId()+"'失败，设备已存在");
        }
        if(checkDeviceNameUnique(egDevice)){
            throw new BusinessException("新增门禁设备'"+egDevice.getDeviceName()+"'失败，设备已存在");
        }

        egDevice.setUpdateBy(SecurityUtils.getUsername());
        egDevice.setUpdateTime(LocalDateTime.now());

        this.updateById(egDevice);
    }

    @Override
    public void remove(Integer id){
        EgDevice egDevice = this.getById(id);
        Optional.ofNullable(egDevice).orElseThrow(() -> new BusinessException("门禁设备信息不存在"));

        LambdaQueryWrapper<MeetingFaceDevice> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(MeetingFaceDevice::getDeviceId,id);
        Integer count = meetingFaceDeviceMapper.selectCount(queryWrapper);
        if(count > 0){
            throw new BusinessException("已绑定人员不能删除");
        }

        this.removeById(id);

        remoteIotTaskService.deleteDeviceInfo(egDevice.getDeviceUuid());
    }

    @Override
    public boolean checkNameUnique(EgDevice egDevice){
        Integer id = null == egDevice.getId() ? -1 : egDevice.getId();
        LambdaQueryWrapper<EgDevice> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(EgDevice::getDeviceId,egDevice.getDeviceId())
                .eq(EgDevice::getEgNumber,egDevice.getEgNumber())
                .eq(EgDevice::getTenantId, SecurityUtils.getTenantId());
        EgDevice one = this.getOne(queryWrapper);
        return null != one && !Objects.equals(one.getId(),id);
    }

    @Override
    public boolean checkDeviceNameUnique(EgDevice egDevice){
        Integer id = null == egDevice.getId() ? -1 : egDevice.getId();
        LambdaQueryWrapper<EgDevice> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(EgDevice::getDeviceName,egDevice.getDeviceName())
                .eq(EgDevice::getTenantId, SecurityUtils.getTenantId());
        EgDevice one = this.getOne(queryWrapper);
        return null != one && !Objects.equals(one.getId(),id);
    }

    @Override
    public Map<String,Object> control(String productCode, String deviceUuid, String commandCode, String commandValue, String domain, Long userId, String userName, Integer categoryType, String gatewayUuid){
        Integer tenantId;
        long commandUserId;
        String commandUserName;
        if(StringUtils.isNotBlank(domain)){
            tenantId = baseMapper.sysTenantId(domain);
            commandUserId = userId;
            commandUserName = userName;
        }else{
            tenantId = SecurityUtils.getTenantId();
            commandUserId = SecurityUtils.getUserId();
            commandUserName = SecurityUtils.getUsername();
        }

        //人员设备权限校验，校验通过，可以下发命令控制设备
        Integer fid = baseMapper.getMeetingFaceData(commandUserId);
        if(fid == null){
            throw new BusinessException("人脸卡号信息未注册");
        }
        Integer[] deviceFid = baseMapper.getMeetingFaceDeviceList(fid);
        if(deviceFid.length == 0){
            throw new BusinessException("人员未绑定设备，请检查");
        }

        LambdaQueryWrapper<EgDevice> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.select(EgDevice::getId)
                .eq(EgDevice::getDeviceUuid,deviceUuid);
        EgDevice one = this.getOne(queryWrapper);
        if(one != null){
            boolean exist = Arrays.asList(deviceFid).contains(one.getId());
            if(!exist){
                throw new BusinessException("暂无权限");
            }
        }else{
            throw new BusinessException("设备未注册，请先注册");
        }


        Map<String,Object> map = new HashMap<>();
        map.put("method","control");
        map.put("deviceUuid", deviceUuid);
        Map<String,Object> map1 = new HashMap<>();
        map1.put("commandCode",commandCode);
        map1.put("commandValue",commandValue);
        map.put("params",map1);

        if(categoryType == 3){
            return remoteTransferService.deviceControl(productCode, gatewayUuid, JSON.toJSONString(map), tenantId, commandUserId, commandUserName);
        }else{
            return remoteTransferService.deviceControl(productCode, deviceUuid, JSON.toJSONString(map), tenantId, commandUserId, commandUserName);
        }
    }
}
