package com.ycwl.basic.service.pc.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ycwl.basic.model.pc.device.entity.DeviceEntity;
import com.ycwl.basic.model.pc.device.req.DeviceBatchSortRequest;
import com.ycwl.basic.model.wvp.WvpSyncReqVo;
import com.ycwl.basic.repository.DeviceRepository;
import com.ycwl.basic.mapper.DeviceMapper;
import com.ycwl.basic.model.pc.device.entity.DeviceConfigEntity;
import com.ycwl.basic.model.pc.device.req.DeviceAddOrUpdateReq;
import com.ycwl.basic.model.pc.device.req.DeviceReqQuery;
import com.ycwl.basic.model.pc.device.resp.DeviceRespVO;
import com.ycwl.basic.service.pc.DeviceService;
import com.ycwl.basic.utils.ApiResponse;
import com.ycwl.basic.utils.SnowFlakeUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author：longbinbin
 * @Date：2024/12/2 16:18
 */
@Service
public class DeviceServiceImpl implements DeviceService {
    @Autowired
    private DeviceMapper deviceMapper;
    @Autowired
    private DeviceRepository deviceRepository;
    @Override
    public ApiResponse<PageInfo<DeviceRespVO>> pageQuery(DeviceReqQuery deviceReqQuery) {
        PageHelper.startPage(deviceReqQuery.getPageNum(), deviceReqQuery.getPageSize());
        List<DeviceRespVO> list = deviceMapper.list(deviceReqQuery);
        for (DeviceRespVO deviceRespVO : list) {
            DeviceEntity onlineStatus = deviceRepository.getOnlineStatus(deviceRespVO.getId());
            if (onlineStatus != null) {
                deviceRespVO.setKeepaliveAt(onlineStatus.getKeepaliveAt());
                if (new Date().getTime() - onlineStatus.getKeepaliveAt().getTime() > 300000) {
                    deviceRespVO.setOnline(0);
                } else {
                    deviceRespVO.setOnline(onlineStatus.getOnline());
                }
            } else {
                deviceRespVO.setOnline(0);
                deviceRespVO.setKeepaliveAt(null);
            }
        }
        PageInfo<DeviceRespVO> pageInfo = new PageInfo<>(list);
        return ApiResponse.success(pageInfo);
    }

    @Override
    public ApiResponse<List<DeviceRespVO>> list(DeviceReqQuery deviceReqQuery) {
        return ApiResponse.success(deviceMapper.list(deviceReqQuery));
    }

    @Override
    public ApiResponse<DeviceRespVO> getById(Long id) {
        return ApiResponse.success(deviceMapper.getById(id));
    }

    @Override
    public ApiResponse addOrUpdate(DeviceAddOrUpdateReq deviceReqQuery) {
        Long id = deviceReqQuery.getId();
        if (id == null) {
            deviceReqQuery.setId(SnowFlakeUtil.getLongId());
            if (StringUtils.isBlank(deviceReqQuery.getNo())) {
                deviceReqQuery.setNo(deviceReqQuery.getId().toString());
            }
            deviceReqQuery.setStatus(0);
            return ApiResponse.success(deviceMapper.add(deviceReqQuery));
        } else {
            deviceRepository.clearDeviceCache(deviceReqQuery.getId());
            deviceMapper.update(deviceReqQuery);
            deviceRepository.clearDeviceCache(deviceReqQuery.getId());
            return ApiResponse.success(0);
        }
    }

    @Override
    public ApiResponse deleteById(Long id) {
        return ApiResponse.success(deviceMapper.deleteById(id));
    }

    @Override
    public ApiResponse updateStatus(Long id) {
        deviceRepository.clearDeviceCache(id);
        deviceMapper.updateStatus(id);
        deviceRepository.clearDeviceCache(id);
        return ApiResponse.success(1);
    }

    @Override
    public DeviceConfigEntity getConfig(Long id) {
        DeviceConfigEntity config = deviceMapper.getConfigByDeviceId(id);
        if (config == null) {
            config = new DeviceConfigEntity();
            config.setId(SnowFlakeUtil.getLongId());
            config.setDeviceId(id);
            deviceMapper.addConfig(config);
        }
        return config;
    }

    @Override
    public void saveConfig(Long configId, DeviceConfigEntity config) {
        config.setId(configId);
        deviceMapper.updateConfig(config);
        deviceRepository.clearDeviceCache(config.getDeviceId());
    }

    @Override
    public void updateDevices(Long scenicId, WvpSyncReqVo reqVo) {
        if (reqVo == null) {
            return;
        }
        if (reqVo.getDevices() != null && !reqVo.getDevices().isEmpty()) {
            for (WvpSyncReqVo.DeviceItem deviceItem : reqVo.getDevices()) {
                DeviceEntity device = deviceRepository.getDeviceByDeviceNo(deviceItem.getDeviceNo());
                if (device != null) {
                    device.setOnline(deviceItem.getOnline());
                    device.setKeepaliveAt(deviceItem.getKeepaliveAt());
                    deviceRepository.updateOnlineStatus(device.getId(), deviceItem.getIp(), 1, deviceItem.getKeepaliveAt());
                }
            }
        }
    }

    @Override
    public ApiResponse<Boolean> sortDevice(Long deviceId, Long afterDeviceId) {
        DeviceEntity device = deviceRepository.getDevice(deviceId);
        if (device == null) {
            return ApiResponse.fail("设备不存在");
        }
        List<DeviceEntity> scenicDeviceList = deviceRepository.getAllDeviceByScenicId(device.getScenicId());
        AtomicInteger sortNum = new AtomicInteger(0);
        for (DeviceEntity item : scenicDeviceList) {
            item.setSort(sortNum.addAndGet(1));
        }
        Optional<DeviceEntity> templateOptional = scenicDeviceList.stream().filter(item -> item.getId().equals(deviceId)).findAny();
        if (templateOptional.isEmpty()) {
            return ApiResponse.fail("设备不存在");
        }
        Optional<DeviceEntity> afterTemplateOptional = scenicDeviceList.stream().filter(item -> item.getId().equals(afterDeviceId)).findAny();
        if (afterTemplateOptional.isPresent()) {
            DeviceEntity afterTemplate = afterTemplateOptional.get();
            Integer newSort = afterTemplate.getSort();
            DeviceEntity oldTemplate = templateOptional.get();
            Integer oldSort = oldTemplate.getSort();
            afterTemplate.setSort(oldSort);
            oldTemplate.setSort(newSort);
        }
        scenicDeviceList.forEach(item -> {
            deviceMapper.updateSort(item.getId(), item.getSort());
            deviceRepository.clearDeviceCache(item.getId());
            deviceRepository.clearDeviceCache(item.getNo());
            deviceRepository.clearDeviceCache(item.getNo2());
        });
        return ApiResponse.success(true);
    }

    @Override
    public ApiResponse<Boolean> batchSort(Long scenicId, DeviceBatchSortRequest request) {
        for (DeviceBatchSortRequest.SortItem item : request.getList()) {
            deviceMapper.updateSort(item.getId(), item.getSort());
            deviceRepository.clearDeviceCache(item.getId());
        }
        return ApiResponse.success(true);
    }
}
