package com.ruoyi.device.service.impl;

import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.device.domain.entity.TsbDevice;
import com.ruoyi.device.domain.vo.TsbDeviceHomeVo;
import com.ruoyi.device.mapper.TsbDeviceMapper;
import com.ruoyi.device.mapper.TsbUserDeviceMapper;
import com.ruoyi.device.mqtt.enums.DeviceLineStatusEnum;
import com.ruoyi.device.mqtt.handler.DeviceOnlineManager;
import com.ruoyi.device.mqtt.vo.DeviceOnlineInfo;
import com.ruoyi.device.service.ITsbDeviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 调试宝设备 业务层处理
 *
 * @author lwm
 */
@Service
public class TsbDeviceServiceImpl implements ITsbDeviceService
{
    @Autowired
    private TsbDeviceMapper tsbDeviceMapper;

    @Autowired
    private TsbUserDeviceMapper tsbUserDeviceMapper;

    @Autowired
    private DeviceOnlineManager deviceOnlineManager;

    /**
     * 根据条件分页查询设备数据
     *
     * @param tsbDevice 设备信息
     * @return 设备数据集合信息
     */
    @Override
    @DataScope(deptAlias = "d")
    public List<TsbDevice> selectTsbDeviceList(TsbDevice tsbDevice)
    {
        return tsbDeviceMapper.selectTsbDeviceList(tsbDevice);
    }

    /**
     * 首页设备卡片列表（含绑定用户、部门）
     *
     * @param tsbDevice 设备信息
     * @return 设备列表
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<TsbDeviceHomeVo> selectTsbDeviceHomeList(TsbDevice tsbDevice)
    {
        if (tsbDevice == null)
        {
            tsbDevice = new TsbDevice();
        }
        List<TsbDeviceHomeVo> list = tsbDeviceMapper.selectTsbDeviceHomeList(tsbDevice);
        fillDeviceOnlineInfo(list);
        return list;
    }

    /**
     * 填充设备在线信息
     *
     * @param list 设备列表
     */
    private void fillDeviceOnlineInfo(List<TsbDeviceHomeVo> list)
    {
        if (StringUtils.isEmpty(list))
        {
            return;
        }
        for (TsbDeviceHomeVo vo : list)
        {
            DeviceOnlineInfo info = deviceOnlineManager.getDeviceLoginInfo(vo.getDeviceSn());
            if (info != null && DeviceLineStatusEnum.isOnLine(info.getLineStatus()))
            {
                vo.setLineStatus(DeviceLineStatusEnum.ON_LINE.getStatus());
                vo.setOnlineUserName(info.getUserName());
                vo.setHeartbeatTime(info.getHeartbeatTime());
            }
            else
            {
                vo.setLineStatus(DeviceLineStatusEnum.OFF_LINE.getStatus());
            }
        }
    }

    /**
     * 按 SN码 查询当前用户有操作权限的设备
     *
     * @param deviceSn 设备 SN 码
     * @return 设备信息
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public TsbDevice selectAccessibleDeviceBySn(Long deviceSn)
    {
        if (deviceSn == null)
        {
            return null;
        }
        TsbDevice query = new TsbDevice();
        query.setDeviceSn(deviceSn);
        return tsbDeviceMapper.selectAccessibleDeviceBySn(query);
    }

    /**
     * 根据设备ID查询设备（未删除）
     *
     * @param deviceId 设备ID
     * @return 设备信息
     */
    @Override
    public TsbDevice selectTsbDeviceById(Long deviceId)
    {
        return tsbDeviceMapper.selectTsbDeviceById(deviceId);
    }

    /**
     * 校验 IMEI 是否唯一
     *
     * @param device 设备信息
     * @return 结果
     */
    @Override
    public boolean checkImeiUnique(TsbDevice device)
    {
        Long deviceId = StringUtils.isNull(device.getDeviceId()) ? -1L : device.getDeviceId();
        TsbDevice info = tsbDeviceMapper.checkImeiUnique(device.getImei());
        if (StringUtils.isNotNull(info) && info.getDeviceId().longValue() != deviceId.longValue())
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 校验设备 SN 是否唯一
     *
     * @param device 设备信息
     * @return 结果
     */
    @Override
    public boolean checkDeviceSnUnique(TsbDevice device)
    {
        Long deviceId = StringUtils.isNull(device.getDeviceId()) ? -1L : device.getDeviceId();
        TsbDevice info = tsbDeviceMapper.checkDeviceSnUnique(device.getDeviceSn());
        if (StringUtils.isNotNull(info) && info.getDeviceId().longValue() != deviceId.longValue())
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 新增调试宝设备
     *
     * @param device 设备信息
     * @return 结果
     */
    @Override
    @Transactional
    public int insertTsbDevice(TsbDevice device)
    {
        if (StringUtils.isEmpty(device.getStatus()))
        {
            device.setStatus(UserConstants.NORMAL);
        }
        return tsbDeviceMapper.insertTsbDevice(device);
    }

    /**
     * 修改调试宝设备
     *
     * @param device 设备信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateTsbDevice(TsbDevice device)
    {
        return tsbDeviceMapper.updateTsbDevice(device);
    }

    /**
     * 修改设备状态
     *
     * @param device 设备信息（deviceId、status）
     * @return 结果
     */
    @Override
    @Transactional
    public int updateTsbDeviceStatus(TsbDevice device)
    {
        return tsbDeviceMapper.updateTsbDevice(device);
    }

    /**
     * 批量逻辑删除设备；若仍有用户绑定则不允许删除
     *
     * @param deviceIds 需要删除的设备ID
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteTsbDeviceByIds(Long[] deviceIds)
    {
        for (Long deviceId : deviceIds)
        {
            if (tsbUserDeviceMapper.countBindByDeviceId(deviceId) > 0)
            {
                TsbDevice d = tsbDeviceMapper.selectTsbDeviceById(deviceId);
                String tip = StringUtils.isNotNull(d) ? String.valueOf(d.getDeviceSn()) : String.valueOf(deviceId);
                throw new ServiceException(String.format("设备[%s]已绑定用户，请先解绑", tip));
            }
        }
        return tsbDeviceMapper.deleteTsbDeviceByIds(deviceIds);
    }

    /**
     * 强制删除：先删绑定，再逻辑删设备
     *
     * @param deviceIds 设备主键数组
     * @return 影响行数（以设备表为准）
     */
    @Override
    @Transactional
    public int forceDeleteTsbDeviceByIds(Long[] deviceIds)
    {
        if (StringUtils.isEmpty(deviceIds))
        {
            return 0;
        }
        tsbUserDeviceMapper.deleteTsbUserDeviceByDeviceIds(deviceIds);
        return tsbDeviceMapper.deleteTsbDeviceByIds(deviceIds);
    }
}
