package com.fuyuanshen.equipment.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fuyuanshen.common.core.domain.model.LoginUser;
import com.fuyuanshen.common.core.exception.BadRequestException;
import com.fuyuanshen.common.core.utils.SpringUtils;
import com.fuyuanshen.common.core.utils.StringUtils;
import com.fuyuanshen.common.mybatis.core.page.PageQuery;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
import com.fuyuanshen.common.satoken.utils.AppLoginHelper;
import com.fuyuanshen.common.satoken.utils.LoginHelper;
import com.fuyuanshen.customer.domain.Customer;
import com.fuyuanshen.customer.mapper.CustomerMapper;
import com.fuyuanshen.equipment.domain.*;
import com.fuyuanshen.equipment.domain.dto.AppDeviceBo;
import com.fuyuanshen.equipment.domain.form.DeviceForm;
import com.fuyuanshen.equipment.domain.query.DeviceAssignmentQuery;
import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria;
import com.fuyuanshen.equipment.domain.query.DeviceTypeQueryCriteria;
import com.fuyuanshen.equipment.domain.vo.*;
import com.fuyuanshen.equipment.enums.BindingStatusEnum;
import com.fuyuanshen.equipment.enums.CommunicationModeEnum;
import com.fuyuanshen.equipment.enums.DeviceActiveStatusEnum;
import com.fuyuanshen.equipment.mapper.*;
import com.fuyuanshen.equipment.service.*;
import com.fuyuanshen.equipment.utils.FileHashUtil;
import com.fuyuanshen.system.domain.vo.SysOssVo;
import com.fuyuanshen.system.domain.vo.SysRoleVo;
import com.fuyuanshen.system.service.ISysOssService;
import com.fuyuanshen.system.service.ISysRoleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @Description:
 * @Author: WY
 * @Date: 2025/5/16
 **/
@Slf4j
@Service
@RequiredArgsConstructor
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements DeviceService {

    public static final String USER_ID_SEPARATOR = ":";

    private final ISysRoleService roleService;

    private final DeviceMapper deviceMapper;
    private final DeviceTypeMapper deviceTypeMapper;
    private final CustomerMapper customerMapper;

    private final ISysOssService ossService;

    private final DeviceAssignmentsService deviceAssignmentsService;
    private final DeviceAssignmentsMapper deviceAssignmentsMapper;

    private final DeviceTypeGrantsService deviceTypeGrantsService;
    private final DeviceTypeGrantsMapper deviceTypeGrantsMapper;

    private final DeviceFenceAccessRecordMapper deviceFenceAccessRecordMapper;
    private final FileHashUtil fileHashUtil;
    private final IAppBusinessFileService appBusinessFileService;
    private final IAppOperationVideoService appOperationVideoService;


    /**
     * 分页查询设备
     *
     * @param criteria 条件
     * @param page     分页参数
     * @return
     * @throws IOException
     */
    @Override
    public TableDataInfo<Device> queryAll(DeviceQueryCriteria criteria, Page<Device> page) throws IOException {

        criteria.setCurrentOwnerId(LoginHelper.getUserId());
        if (criteria.getDeviceType() != null) {
            DeviceTypeGrants deviceTypeGrant = deviceTypeGrantsMapper.selectById(criteria.getDeviceType());
            if (deviceTypeGrant != null) {
                criteria.setDeviceType(deviceTypeGrant.getDeviceTypeId());
            }
        }

        // 管理员
        String username = LoginHelper.getUsername();
        if (username.equals("admin")) {
            criteria.setIsAdmin(true);
        }
        // 角色管理员
        Long userId = LoginHelper.getUserId();
        List<SysRoleVo> roles = roleService.selectRolesAuthByUserId(userId);
        if (CollectionUtil.isNotEmpty(roles)) {
            for (SysRoleVo role : roles) {
                if (role.getRoleKey().equals("admin")) {
                    criteria.setIsAdmin(true);
                }
            }
        }

        IPage<Device> devices = deviceMapper.findAll(criteria, page);

        List<Device> records = devices.getRecords();
        for (Device record : records) {
            if (record.getDevicePic() == null) {
                record.setDevicePic("");
            }
        }

        return new TableDataInfo<Device>(records, devices.getTotal());
    }

    @Override
    public TableDataInfo<Device> queryAllTerminal(DeviceQueryCriteria criteria, Page<Device> page) throws IOException {
        // 角色管理员
        Long userId = LoginHelper.getUserId();
        List<SysRoleVo> roles = roleService.selectRolesAuthByUserId(userId);
        boolean isAdmin = false;
        if (CollectionUtil.isNotEmpty(roles)) {
            for (SysRoleVo role : roles) {
                if (role.getRoleKey().equals("admin")) {
                    isAdmin = true;
                    criteria.setIsAdmin(true);
                    break;
                }
            }
        }

        IPage<Device> devices = deviceMapper.findAllTerminal(criteria, page);
        return new TableDataInfo<Device>(devices.getRecords(), devices.getTotal());
    }


    @Override
    public List<Device> queryAll(DeviceQueryCriteria criteria) {

        // 角色管理员
        Long userId = LoginHelper.getUserId();
        List<SysRoleVo> roles = roleService.selectRolesAuthByUserId(userId);
        boolean isAdmin = false;
        if (CollectionUtil.isNotEmpty(roles)) {
            for (SysRoleVo role : roles) {
                if (role.getRoleKey().equals("admin")) {
                    isAdmin = true;
                    criteria.setIsAdmin(true);
                    break;
                }
            }
        }

        // 只有非admin用户才设置当前用户ID条件
        if (!isAdmin) {
            criteria.setCurrentOwnerId(LoginHelper.getUserId());
        }
        return deviceMapper.findAll(criteria);

    }


    /**
     * 查询所有设备
     *
     * @param criteria 筛选条件
     * @return
     */
    @Override
    public List<Device> queryAllDevices(DeviceQueryCriteria criteria) {
        return deviceMapper.findAllDevices(criteria);
    }


    /**
     * 新增设备
     *
     * @param deviceForm
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addDevice(DeviceForm deviceForm) throws Exception {

        if (deviceForm.getDeviceMac() != null && deviceForm.getBluetoothName() == null) {
            throw new BadRequestException("请填写蓝牙名称！！！");
        }

        Device device1 = deviceMapper.selectOne(new QueryWrapper<Device>().eq("device_mac", deviceForm.getDeviceMac()));
        if (device1 != null) {
            throw new BadRequestException("设备MAC已存在！！！");
        }
        Device device2 = deviceMapper.selectOne(new QueryWrapper<Device>().eq("device_imei", deviceForm.getDeviceImei()));
        if (device2 != null) {
            throw new BadRequestException("设备IMEI已存在！！！");
        }

        DeviceTypeGrants typeGrants = new DeviceTypeGrants();

        // 修改为：
        Long userId;
        LoginUser loginUser;
        try {
            loginUser = LoginHelper.getLoginUser();
            userId = loginUser != null ? loginUser.getUserId() : 1938143703108689922L; // 如果没有登录用户，使用默认系统用户ID
        } catch (Exception e) {
            userId = 1938143703108689922L; // 出现异常时使用默认系统用户ID
            loginUser = new LoginUser();
            loginUser.setUserId(userId);
            loginUser.setNickname("admin");
            loginUser.setTenantId("894078"); // 设置租户ID
        }

        if (deviceForm.getDeviceType() != null) {
            DeviceTypeQueryCriteria queryCriteria = new DeviceTypeQueryCriteria();
            queryCriteria.setDeviceTypeId(deviceForm.getDeviceType());
            typeGrants = deviceTypeGrantsMapper.selectById(queryCriteria.getDeviceTypeId());
            if (typeGrants == null) {
                throw new Exception("设备类型不存在!!!");
            }
        }

        // 检查设备类型是否存在，如果不存在则创建
        DeviceType deviceType = null;
        if (deviceForm.getDeviceType() != null) {
            deviceType = deviceTypeMapper.selectById(typeGrants.getDeviceTypeId());
        } else if (deviceForm.getTypeName() != null) {
            deviceType = deviceTypeMapper.selectOne(new QueryWrapper<DeviceType>().eq("type_name", deviceForm.getTypeName()));
        }

        if (deviceType == null && deviceForm.getTypeName() != null) {
            // 创建新的设备类型
            DeviceType newDeviceType = new DeviceType();
            newDeviceType.setTypeName(deviceForm.getTypeName());
            newDeviceType.setIsSupportBle("是".equals(deviceForm.getIsSupportBle()) || "1".equals(deviceForm.getIsSupportBle()));

            // 设置定位方式
            if (deviceForm.getLocateMode() != null) {
                switch (deviceForm.getLocateMode()) {
                    case "无":
                        newDeviceType.setLocateMode("0");
                        break;
                    case "GPS":
                        newDeviceType.setLocateMode("1");
                        break;
                    case "基站":
                        newDeviceType.setLocateMode("2");
                        break;
                    case "wifi":
                        newDeviceType.setLocateMode("3");
                        break;
                    case "北斗":
                        newDeviceType.setLocateMode("4");
                        break;
                    default:
                        newDeviceType.setLocateMode(deviceForm.getLocateMode());
                }
            }

            // 设置通讯方式
            if (deviceForm.getCommunicationMode() != null) {
                switch (deviceForm.getCommunicationMode()) {
                    case "4G":
                        newDeviceType.setCommunicationMode("0");
                        break;
                    case "蓝牙":
                        newDeviceType.setCommunicationMode("1");
                        break;
                    case "4G&蓝牙":
                        newDeviceType.setCommunicationMode("2");
                        break;
                    default:
                        newDeviceType.setCommunicationMode(deviceForm.getCommunicationMode());
                }
            }

            newDeviceType.setAppModelDictionary(deviceForm.getAppModelDictionary());
            newDeviceType.setPcModelDictionary(deviceForm.getPcModelDictionary());

            // 校验设备类型名称
            List<DeviceType> existingTypes = deviceTypeMapper.selectList(new QueryWrapper<DeviceType>().eq("type_name", newDeviceType.getTypeName()));
            if (CollectionUtil.isNotEmpty(existingTypes)) {
                throw new RuntimeException("设备类型名称已存在，无法新增!!!");
            }

            newDeviceType.setCreateByName(loginUser.getNickname());
            newDeviceType.setTenantId(loginUser.getTenantId());
            deviceTypeMapper.insert(newDeviceType);

            // 重新查询确保获取到正确的ID
            deviceType = deviceTypeMapper.selectOne(new QueryWrapper<DeviceType>().eq("type_name", deviceForm.getTypeName()));

            // 自动授权给自己
            DeviceTypeGrants deviceTypeGrants = new DeviceTypeGrants();
            deviceTypeGrants.setDeviceTypeId(deviceType.getId());
            deviceTypeGrants.setCustomerId(loginUser.getUserId());
            deviceTypeGrants.setGrantorCustomerId(loginUser.getUserId());
            deviceTypeGrants.setGrantedAt(new Date());
            deviceTypeGrants.setTenantId(loginUser.getTenantId());
            deviceTypeGrantsMapper.insert(deviceTypeGrants);
        }

        if (deviceType == null) {
            throw new Exception("设备类型不存在!!!");
        }

        // 保存图片并获取URL
        if (deviceForm.getFile() != null) {
            String fileHash = fileHashUtil.hash(deviceForm.getFile());
            SysOssVo upload = ossService.updateHash(deviceForm.getFile(), fileHash);
            // 强制将HTTP替换为HTTPS
            if (upload.getUrl() != null && upload.getUrl().startsWith("http://")) {
                upload.setUrl(upload.getUrl().replaceFirst("^http://", "https://"));
            }
            // 设置图片路径
            deviceForm.setDevicePic(upload.getUrl());
        }

        // 转换对象并插入数据库
        Device device = new Device();

        BeanUtil.copyProperties(deviceForm, device, true);
        device.setDeviceNo(createDeviceNo());
        device.setCurrentOwnerId(loginUser.getUserId());
        device.setOriginalOwnerId(loginUser.getUserId());
        device.setCreateByName(loginUser.getNickname());
        device.setTypeName(deviceType.getTypeName());
        device.setDeviceType(deviceType.getId());
        device.setDevicePic(deviceType.getDevicePic());
        device.setTenantId(loginUser.getTenantId());
        if (device.getDeviceImei() != null) {
            device.setPubTopic("A/" + device.getDeviceImei());
            device.setSubTopic("B/" + device.getDeviceImei());
        }
        // 0 未绑定
        device.setBindingStatus(0);
        deviceMapper.insert(device);

        // 查询设备类型的文件列表
        // 4. 核心优化：同步设备类型的文件列表 (一行代码)
        appBusinessFileService.cloneFiles(deviceType.getId(), device.getId());
        // 同步设备类型的视频列表
        appOperationVideoService.cloneFiles(deviceType.getId(), device.getId());

        // 新增设备类型记录
        DeviceAssignments assignments = new DeviceAssignments();
        assignments.setDeviceId(device.getId());
        assignments.setAssignedAt(LocalDateTime.now());
        // 分配者
        assignments.setAssignerId(loginUser.getUserId());
        assignments.setAssignerName(loginUser.getUsername());
        // 接收者
        assignments.setAssigneeId(loginUser.getUserId());
        assignments.setActive(DeviceActiveStatusEnum.ACTIVE.getCode());
        String lever = USER_ID_SEPARATOR + loginUser.getUserId();
        assignments.setLever(lever);
        assignments.setTenantId(loginUser.getTenantId());
        deviceAssignmentsService.save(assignments);

    }


    private String createDeviceNo() {
        String uuidStr = UUID.fastUUID().toString(); // 获取带 - 的标准格式字符串
        return uuidStr.replaceAll("-", "");
    }


    /**
     * 更新设备信息
     *
     * @param deviceForm /
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(DeviceForm deviceForm) throws Exception {
        DeviceAssignments deviceAssignments = deviceAssignmentsMapper.selectById(deviceForm.getId());

        DeviceTypeQueryCriteria deviceTypeQueryCriteria = new DeviceTypeQueryCriteria();
        deviceTypeQueryCriteria.setDeviceTypeId(deviceAssignments.getDeviceId());
        // 被授权的客户
        // deviceTypeQueryCriteria.setCustomerId(LoginHelper.getUserId());
        List<DeviceType> deviceTypes = deviceTypeMapper.findAll(deviceTypeQueryCriteria);
        if (deviceTypes.isEmpty()) {
            throw new Exception("设备类型不存在!!!");
        }
        Device device = deviceMapper.selectById(deviceAssignments.getDeviceId());
        if (device == null) {
            throw new Exception("设备不存在!!!");
        }
        // 设备类型
        Long deviceType = device.getDeviceType();

        // 处理上传的图片
        if (deviceForm.getFile() != null) {
            String fileHash = fileHashUtil.hash(deviceForm.getFile());
            SysOssVo oss = ossService.updateHash(deviceForm.getFile(), fileHash);
            // 强制将HTTP替换为HTTPS
            if (oss.getUrl() != null && oss.getUrl().startsWith("http://")) {
                oss.setUrl(oss.getUrl().replaceFirst("^http://", "https://"));
            }
            deviceForm.setDevicePic(oss.getUrl());
        }

        // 更新字段
        BeanUtil.copyProperties(deviceForm, device, true);
        device.setId(deviceAssignments.getDeviceId());
        device.setDeviceType(deviceType);
        device.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        deviceMapper.updateById(device);
    }


    /**
     * 删除设备
     *
     * @param ids /
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(List<Long> ids) {
        List<Long> invalidIds = new ArrayList<>();

        for (Long id : ids) {
            DeviceAssignments deviceAssignment = deviceAssignmentsMapper.selectById(id);
            if (deviceAssignment == null) {
                continue;
            }
            Device device = deviceMapper.selectById(deviceAssignment.getDeviceId());

            if (StringUtils.isNotEmpty(deviceAssignment.getAssigneeName())) {
                throw new BadRequestException(device.getDeviceName() + ":设备已分配，请先解绑设备！！！");
            }

            if (device.getBindingStatus() != null && device.getBindingStatus().equals(1)) {
                throw new BadRequestException(device.getDeviceName() + ":设备已绑定，请先解绑设备！！！");
            }

            // 接收者
            if (Objects.equals(deviceAssignment.getAssigneeId(), device.getOriginalOwnerId())) {
                invalidIds.add(deviceAssignment.getDeviceId());
            }

            // 删除设备:分配记录
            deviceAssignmentsMapper.delete(new LambdaQueryWrapper<DeviceAssignments>()
                    .eq(DeviceAssignments::getDeviceId, deviceAssignment.getDeviceId())
                    .eq(DeviceAssignments::getAssigneeId, deviceAssignment.getAssigneeId()));

        }

        deviceAssignmentsMapper.deleteByIds(ids);
        deviceMapper.deleteByIds(invalidIds);
    }


    /**
     * 分配客户
     *
     * @param customerVo
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assignCustomer(CustomerVo customerVo) {

        if (customerVo.getDeviceIds().isEmpty() || customerVo.getCustomerId() == null) {
            throw new RuntimeException("请选择设备或客户");
        }

        // 获取当前登录用户
        LoginUser loginUser = LoginHelper.getLoginUser();
        // 获取分配用户信息
        Customer assignUser = customerMapper.selectById(customerVo.getCustomerId());
        // 获取分配设备信息
        List<DeviceAssignments> assignments = deviceAssignmentsMapper.selectByIds(customerVo.getDeviceIds());

        // 批量更新设备状态
        List<DeviceTypeGrants> deviceTypeGrants = new ArrayList<>();
        for (DeviceAssignments assignment : assignments) {

            if (assignment.getToCustomerId() != null && assignment.getToCustomerId() != 0L) {
                log.info("设备已经分配客户！！！");
                throw new RuntimeException("设备已经分配客户！！！");
            }

            Device device = deviceMapper.selectById(assignment.getDeviceId());

            // 如果设备已分配给需要分配的客户，则跳过
            DeviceAssignmentQuery dq = DeviceAssignmentQuery.builder().deviceId(device.getId()).assigneeId(customerVo.getCustomerId())
                    .active(DeviceActiveStatusEnum.ACTIVE.getCode()).lever(assignment.getLever() + USER_ID_SEPARATOR).build();
            // 查询分配
            List<DeviceAssignments> assignmentsList = deviceAssignmentsMapper.deviceAssignmentsMapper(dq);
            if (CollectionUtil.isNotEmpty(assignmentsList)) {
                log.info("设备 {} 已分配给客户 {}", device.getDeviceName(), device.getCustomerName());
                continue;
            }

            // 更改分配客户
            assignment.setAssigneeName(assignUser.getNickName());
            assignment.setToCustomerId(customerVo.getCustomerId());
            deviceAssignmentsMapper.updateById(assignment);

            // 设备失效
            // 获取用户的设备记录
            DeviceAssignmentQuery dq1 = DeviceAssignmentQuery.builder().deviceId(device.getId()).assignerId(loginUser.getUserId())
                    .active(DeviceActiveStatusEnum.ACTIVE.getCode()).lever(assignment.getLever() + USER_ID_SEPARATOR).build();
            List<DeviceAssignments> ag = deviceAssignmentsMapper.deviceAssignmentsMapper(dq1);
            if (CollectionUtil.isNotEmpty(ag)) {
                for (DeviceAssignments d : ag) {
                    d.setActive(DeviceActiveStatusEnum.INACTIVE.getCode());
                    deviceAssignmentsMapper.updateById(d);
                }
            }

            // 新增设备类型记录
            DeviceAssignments dam = new DeviceAssignments();
            dam.setDeviceId(device.getId());
            dam.setAssignedAt(LocalDateTime.now());
            // 分配者
            dam.setAssignerId(loginUser.getUserId());
            dam.setAssignerName(loginUser.getUsername());
            // 接收者
            dam.setAssigneeId(assignUser.getCustomerId());
            // assignments.setAssigneeName(assignUser.getUsername());
            dam.setActive(DeviceActiveStatusEnum.ACTIVE.getCode());
            String lever = assignment.getLever() + USER_ID_SEPARATOR + assignUser.getCustomerId();
            dam.setLever(lever);
            deviceAssignmentsService.save(dam);

            // 判断设备类型是否存在
            DeviceTypeGrants dtg = deviceTypeGrantsMapper.selectOne(new LambdaQueryWrapper<DeviceTypeGrants>()
                    .eq(DeviceTypeGrants::getDeviceTypeId, device.getDeviceType())
                    .eq(DeviceTypeGrants::getCustomerId, assignUser.getCustomerId()));
            if (dtg != null) {
                continue;
            }
            // 创建并保存设备类型授权记录
            DeviceTypeGrants deviceTypeGrant = new DeviceTypeGrants();
            deviceTypeGrant.setGrantedAt(new Date());
            deviceTypeGrant.setDeviceTypeId(device.getDeviceType());
            // 关联分配记录
            deviceTypeGrant.setAssignmentId(dam.getId());
            // 被授权的客户
            deviceTypeGrant.setCustomerId(customerVo.getCustomerId());
            // 授权方客户
            deviceTypeGrant.setGrantorCustomerId(loginUser.getUserId());
            deviceTypeGrants.add(deviceTypeGrant);
        }

        deviceTypeGrantsService.saveBatch(deviceTypeGrants);

    }

    /**
     * 创建并保存设备类型授权记录
     *
     * @param device           当前设备对象
     * @param currentUser      当前登录用户
     * @param customerVo       客户信息
     * @param deviceTypeGrants 授权记录集合
     */
    private void createAndSaveDeviceTypeGrants(Device device, LoginUser currentUser, CustomerVo customerVo, List<DeviceTypeGrants> deviceTypeGrants) {
        // Long generatedId = NanoId.generate(NanoIdLengthEnum.HIGH_CONCURRENCY.getLength());
        DeviceTypeGrants deviceTypeGrant = new DeviceTypeGrants();
        deviceTypeGrant.setGrantedAt(new Date());
        deviceTypeGrant.setDeviceTypeId(device.getDeviceType());
        // deviceTypeGrant.setAssignmentId(generatedId);
        deviceTypeGrant.setCustomerId(customerVo.getCustomerId());
        deviceTypeGrant.setGrantorCustomerId(currentUser.getUserId());
        deviceTypeGrants.add(deviceTypeGrant);
    }


    /**
     * 撤回设备
     *
     * @param ids
     */
    @Override
    @Transactional
    public void withdrawDevice(List<Long> ids) {

        for (Long id : ids) {
            DeviceAssignments assignment = deviceAssignmentsMapper.selectById(id);
            Device device = deviceMapper.selectById(assignment.getDeviceId());
            // 接收者
            assignment.setAssigneeName("");
            assignment.setToCustomerId(0L);
            deviceAssignmentsMapper.updateById(assignment);

            // 获取所有已分配的设备
            DeviceAssignmentQuery dq = DeviceAssignmentQuery.builder().deviceId(device.getId())
                    .active(DeviceActiveStatusEnum.ACTIVE.getCode()).lever(assignment.getLever() + USER_ID_SEPARATOR).build();
            // 查询分配
            List<DeviceAssignments> assignmentsList = deviceAssignmentsMapper.deviceAssignmentsMapper(dq);
            for (DeviceAssignments assignments : assignmentsList) {
                assignments.setActive(DeviceActiveStatusEnum.INACTIVE.getCode());
                deviceAssignmentsMapper.updateById(assignments);
            }
        }

    }


    /**
     * 解绑设备
     *
     * @param deviceForm
     */
    @Override
    @Transactional
    public void unbindDevice(DeviceForm deviceForm) {

    }

    /**
     * WEB端查看APP客户设备绑定
     *
     * @param bo
     * @param pageQuery
     * @return
     */
    @Override
    public TableDataInfo<AppDeviceVo> queryAppDeviceList(DeviceQueryCriteria bo, PageQuery pageQuery) {
        if (bo.getBindingUserId() == null) {
            Long userId = AppLoginHelper.getUserId();
            bo.setBindingUserId(userId);
        }
        Page<AppDeviceVo> result = baseMapper.queryAppBindDeviceList(pageQuery.build(), bo);
        return TableDataInfo.build(result);
    }

    @Override
    public int bindDevice(AppDeviceBo bo) {
        Integer mode = bo.getCommunicationMode();
        Long userId = AppLoginHelper.getUserId();
        if (mode == CommunicationModeEnum.FOUR_G.getValue()) {

            String deviceImei = bo.getDeviceImei();
            QueryWrapper<Device> qw = new QueryWrapper<Device>()
                    .eq("device_imei", deviceImei);
            List<Device> devices = baseMapper.selectList(qw);
            if (devices.isEmpty()) {
                throw new RuntimeException("请先将设备入库！！！");
            }
            Device device = devices.get(0);
            if (device.getBindingStatus() != null && device.getBindingStatus() == BindingStatusEnum.BOUND.getCode()) {
                throw new RuntimeException("设备已绑定");
            }
            UpdateWrapper<Device> deviceUpdateWrapper = new UpdateWrapper<>();
            deviceUpdateWrapper.eq("id", device.getId())
                    .set("binding_status", BindingStatusEnum.BOUND.getCode())
                    .set("binding_user_id", userId)
                    .set("binding_time", new Date());


            return baseMapper.update(null, deviceUpdateWrapper);
        } else if (mode == CommunicationModeEnum.BLUETOOTH.getValue()) {
            String deviceMac = bo.getDeviceMac();
            QueryWrapper<Device> qw = new QueryWrapper<Device>()
                    .eq("device_mac", deviceMac);
            List<Device> devices = baseMapper.selectList(qw);
            if (devices.isEmpty()) {
                throw new RuntimeException("请先将设备入库！！！");
            }
            Device device = devices.get(0);
            if (device.getBindingStatus() != null && device.getBindingStatus() == BindingStatusEnum.BOUND.getCode()) {
                throw new RuntimeException("设备已绑定");
            }
            UpdateWrapper<Device> deviceUpdateWrapper = new UpdateWrapper<>();
            deviceUpdateWrapper.eq("id", device.getId())
                    .set("binding_status", BindingStatusEnum.BOUND.getCode())
                    .set("binding_user_id", userId)
                    .set("binding_time", new Date());
            return baseMapper.update(null, deviceUpdateWrapper);
        } else {
            throw new RuntimeException("通讯方式错误");
        }

    }

    @Override
    public int unBindDevice(Long id) {
        Device device = baseMapper.selectById(id);
        if (device == null) {
            throw new RuntimeException("请先将设备入库！！！");
        }
//        DeviceType deviceType = deviceTypeMapper.selectById(device.getDeviceType());
//        String mode = deviceType.getCommunicationMode();
        UpdateWrapper<Device> deviceUpdateWrapper = new UpdateWrapper<>();
        deviceUpdateWrapper.eq("id", device.getId())
                .set("binding_status", BindingStatusEnum.UNBOUND.getCode())
                .set("binding_user_id", null)
                .set("binding_time", null);
        return baseMapper.update(null, deviceUpdateWrapper);
    }


    /**
     * WEB端解绑设备
     *
     * @param id
     * @return
     */
    @Override
    public int webUnBindDevice(Long id) {
        DeviceAssignments deviceAssignment = deviceAssignmentsMapper.selectById(id);
        if (deviceAssignment == null) {
            throw new RuntimeException("请先将设备入库！！！");
        }
        return unBindDevice(deviceAssignment.getDeviceId());
    }


    /**
     * 查询设备MAC号
     *
     * @param mac
     * @return
     */
    @Override
    public Boolean queryDevice(String mac) {
        QueryWrapper<Device> wrapper = new QueryWrapper<>();
        wrapper.eq("device_mac", mac);
        List<Device> deviceList = deviceMapper.selectList(wrapper);
        if (CollectionUtil.isNotEmpty(deviceList)) {
            return true;
        }
        return false;
    }


    /**
     * 获取数据总览
     *
     * @return
     */
    @Override
    public DataOverviewVo getDataOverview() {
        DataOverviewVo dataOverviewVo = deviceMapper.getDataOverview();
        return dataOverviewVo;
    }


    /**
     * 获取设备分类
     *
     * @return
     */
    @Override
    public EquipmentClassificationVo getEquipmentClassification() {
        EquipmentClassificationVo equipmentClassification = deviceMapper.getEquipmentClassification();
        equipmentClassification.getTotal();
        return equipmentClassification;
    }


    /**
     * 获取告警信息
     *
     * @return
     */
    @Override
    public AlarmInformationVo getAlarmInformation() {
        AlarmInformationVo alarmInformation = deviceMapper.getAlarmInformation();
        return alarmInformation;
    }

    /**
     * 获取设备使用数据
     *
     * @param deviceTypeId 设备ID
     * @param range        时间范围 1:半年 2:一年
     * @return 每月使用数据列表
     */
    @Override
    public List<Map<String, Object>> getEquipmentUsageData(Long deviceTypeId, Integer range) {
        List<Map<String, Object>> equipmentUsageData = deviceMapper.getEquipmentUsageData(deviceTypeId, range);
        return equipmentUsageData;

    }

    @Override
    public Device selectDeviceByImei(String deviceImei) {
        return baseMapper.selectDeviceByImei(deviceImei);
    }

    /**
     * 获取设备总览
     *
     * @return
     */
    @Override
    public DeviceOverviewVo getDeviceOverview() {
        return deviceMapper.getDeviceOverview();
    }

    /**
     * 获取设备通讯方式统计
     *
     * @return 设备通讯方式统计列表
     */
    @Override
    public List<DeviceCommunicationModeStatisticsVo> getDeviceCommunicationModeStatistics() {
        return deviceMapper.getDeviceCommunicationModeStatistics();
    }

    @Override
    public List<DeviceUsageFrequencyVo> getDeviceUsageFrequency(int days) {
        return deviceMapper.getDeviceUsageFrequency(days);
    }

    /**
     * 根据设备IMEI更新设备的经纬度信息
     *
     * @param deviceImei 设备IMEI
     * @param longitude  经度
     * @param latitude   纬度
     * @return 是否更新成功
     */
    @Override
    public boolean updateDeviceLocationByImei(String deviceImei, String longitude, String latitude) {
        // 根据设备IMEI查询设备
        Device device = deviceMapper.selectDeviceByImei(deviceImei);
        if (device == null) {
            return false;
        }

        // 更新设备的经纬度信息
        device.setLongitude(longitude);
        device.setLatitude(latitude);

        // 更新数据库中的设备信息
        return deviceMapper.updateById(device) > 0;
    }


    /**
     * 根据条件查询设备位置信息
     *
     * @param groupId    设备分组ID
     * @param deviceType 设备类型
     * @param deviceImei 设备IMEI
     * @return 设备位置信息列表
     */
    @Override
    public List<DeviceLocationVo> getDeviceLocationInfo(Long groupId, Long deviceType, String deviceImei) {
        // 构建查询条件
        DeviceQueryCriteria criteria = new DeviceQueryCriteria();
        criteria.setGroupId(groupId);
        criteria.setDeviceType(deviceType);
        criteria.setDeviceImei(deviceImei);

        // 查询符合条件的设备
        List<Device> devices = deviceMapper.findDevices(criteria);

        // 构建返回结果
        List<DeviceLocationVo> result = new ArrayList<>();

        // 注入电子围栏服务
        IDeviceGeoFenceService geoFenceService = SpringUtils.getBean(IDeviceGeoFenceService.class);
        // 注入设备告警Mapper
        DeviceAlarmMapper deviceAlarmMapper = SpringUtils.getBean(DeviceAlarmMapper.class);

        for (Device device : devices) {
            DeviceLocationVo vo = new DeviceLocationVo();
            vo.setDeviceId(device.getId());
            vo.setDeviceName(device.getDeviceName());
            vo.setLongitude(device.getLongitude());
            vo.setLatitude(device.getLatitude());

            // 检查设备是否在电子围栏内
            if (StringUtils.isNotBlank(device.getLongitude()) && StringUtils.isNotBlank(device.getLatitude())) {
                // 查询设备最新的围栏进出记录
                DeviceFenceAccessRecordVo latestRecord = deviceFenceAccessRecordMapper.selectLatestRecordByDeviceId(String.valueOf(device.getId()));

                // 判断是否在围栏内
                if (latestRecord != null) {
                    // 如果最新的记录是进入围栏(事件类型为1)，则设备在围栏内
                    if (latestRecord.getEventType() != null && latestRecord.getEventType() == 1L) {
                        vo.setInFence(true);

                        // 获取围栏完整信息
                        DeviceGeoFence fenceInfo = geoFenceService.getById(latestRecord.getFenceId());
                        if (fenceInfo != null) {
                            vo.setFenceInfo(fenceInfo);
                        }
                    } else {
                        vo.setInFence(false);
                    }
                } else {
                    vo.setInFence(false);
                }
            } else {
                vo.setInFence(false);
            }

            // 检查设备是否正在告警（只要当前设备处于报警状态，且不是电子围栏告警）
            if (StringUtils.isNotBlank(device.getDeviceImei())) {
                DeviceAlarmVo latestAlarm = deviceAlarmMapper.selectLatestByDeviceImei(device.getDeviceImei());
                // 判断是否正在告警：未处理的告警(treatmentState=1)且不是电子围栏告警(deviceAction!=3)
                if (latestAlarm != null &&
                        latestAlarm.getTreatmentState() != null &&
                        latestAlarm.getTreatmentState() == 1 &&
                        latestAlarm.getDeviceAction() != null &&
                        latestAlarm.getDeviceAction() != 3) {
                    vo.setIsAlarming(true);
                } else {
                    vo.setIsAlarming(false);
                }
            } else {
                vo.setIsAlarming(false);
            }

            result.add(vo);
        }

        return result;
    }


}
