package com.ics.admin.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
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.extension.service.impl.ServiceImpl;
import com.ics.admin.domain.Room;
import com.ics.admin.domain.meeting.Equipment;
import com.ics.admin.domain.meeting.RoomEquipment;
import com.ics.admin.mapper.meeting.EquipmentMapper;
import com.ics.admin.mapper.meeting.RoomEquipmentMapper;
import com.ics.admin.service.IRoomService;
import com.ics.admin.service.meeting.IEquipmentService;
import com.ics.admin.service.meeting.IRoomEquipmentService;
import com.ics.common.utils.DeviceUtils;
import com.ics.common.utils.IpUtils;
import com.ics.common.utils.spring.BeanContext;
import com.ics.common.utils.spring.SpringContextHolder;
import com.ics.common.utils.spring.SpringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import com.ics.admin.mapper.meeting.UserEquipmentMapper;
import com.ics.admin.domain.meeting.UserEquipment;
import com.ics.admin.service.meeting.IUserEquipmentService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.annotation.Resource;
import javax.swing.*;


/**
 * 用户设备关联Service业务层处理
 *
 * @author chen
 * @date 2024-02-25
 */
@RequiredArgsConstructor
@Service
public class UserEquipmentServiceImpl extends ServiceImpl<UserEquipmentMapper, UserEquipment> implements IUserEquipmentService {
    @Autowired
    private UserEquipmentMapper userEquipmentMapper;

    @Autowired
    private IRoomEquipmentService roomEquipmentService;

    @Autowired
    private RoomEquipmentMapper roomEquipmentMapper;

    @Autowired
    private IRoomService roomService;

    @Autowired
    private IEquipmentService equipmentService;



    /**
     * 查询用户设备关联
     *
     * @param id 用户设备关联ID
     * @return 用户设备关联
     */
    @Override
    public UserEquipment selectUserEquipmentById(Long id) {
        return userEquipmentMapper.selectById(id);
    }

    /**
     * 查询用户设备关联列表
     *
     * @param userEquipment 用户设备关联
     * @return 用户设备关联
     */
    @Override
    public List<UserEquipment> selectUserEquipmentList(UserEquipment userEquipment) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(null != userEquipment.getEquipmentId(),"equipment_id",userEquipment.getEquipmentId());
        queryWrapper.eq(null != userEquipment.getUserId(),"user_id",userEquipment.getUserId());
        queryWrapper.eq(null != userEquipment.getStartTime(),"start_time",userEquipment.getStartTime());
        queryWrapper.eq(null != userEquipment.getEndDate(),"end_date",userEquipment.getEndDate());
        queryWrapper.in(CollUtil.isNotEmpty(userEquipment.getUserIds()),"user_id",userEquipment.getUserIds());
        return userEquipmentMapper.selectList(queryWrapper);
    }

    /**
     * 新增用户设备关联
     *
     * @param userEquipment 用户设备关联
     * @return 结果
     */
    @Transactional
    @Override
    public int insertUserEquipment(UserEquipment userEquipment) {
        return userEquipmentMapper.insert(userEquipment);
    }

    /**
     * 修改用户设备关联
     *
     * @param userEquipment 用户设备关联
     * @return 结果
     */
    @Override
    public int updateUserEquipment(UserEquipment userEquipment) {
        return userEquipmentMapper.updateById(userEquipment);
    }

    /**
     * 删除用户设备关联对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteUserEquipmentByIds(String ids) {
        String[] idsArray = StrUtil.split(ids, ",");
        return userEquipmentMapper.deleteBatchIds(CollUtil.toList(idsArray));
    }

    /**
     * 删除用户设备关联信息
     *
     * @param id 用户设备关联ID
     * @return 结果
     */
    @Override
    public int deleteUserEquipmentById(Long id) {
        return userEquipmentMapper.deleteUserEquipmentById(id);
    }

    @Override
    public List<UserEquipment> getEquipmentByUserId(Long userId) {


        List<UserEquipment> list = baseMapper.selectList(new QueryWrapper<UserEquipment>().eq("user_id", userId).groupBy("equipment_id"));
        if (CollUtil.isEmpty(list)) {
            return list;
        }
//        List<Equipment> equipment = equipmentService.selectEquipmentList(new Equipment());

        //todo 查看对应的设备的状态
//        updateDeviceDataSource(equipment);


        ArrayList<Equipment> equipments = new ArrayList<>();
        // 查出所有用户的设备，然后根据设备id 查出所在的房间号
        for (UserEquipment userEquipment : list) {
            QueryWrapper<RoomEquipment> wrapper = new QueryWrapper<>();
            wrapper.eq("equipment_id", userEquipment.getEquipmentId());
            RoomEquipment roomEquipment = roomEquipmentMapper.selectOne(wrapper);
            if (null != roomEquipment) {
                Room room = roomService.selectRoomById(roomEquipment.getRoomId());
                userEquipment.setRoomName(room.getName());
                userEquipment.setRoomId(room.getId());
            }
            Equipment equipment1 = equipmentService.selectEquipmentById(userEquipment.getEquipmentId());
            if (null != equipment1) {
                equipments.add(equipment1);
                userEquipment.setEquipmentName(equipment1.getEquipmentName());
                if (equipment1.getStatus() == 0L) {
                    userEquipment.setEquipmentStatus("在线");
                } else {
                    userEquipment.setEquipmentStatus("离线");
                }
            }
        }
        return list;
    }
    @Transactional
    @Override
    public int deleteUserEquipmentByEquipmentId(Long id) {

        UpdateWrapper<UserEquipment> wrapper = new UpdateWrapper<>();
        wrapper.eq("equipment_id", id);
        return userEquipmentMapper.delete(wrapper);
    }

    @Override
    public UserEquipment selectUserAndEquipment(Long userId, Long id) {

        QueryWrapper<UserEquipment> wrapper = new QueryWrapper<>();
        wrapper.eq("equipment_id", id);
        wrapper.eq("user_id", userId);
        return userEquipmentMapper.selectOne(wrapper);
    }

    @Override
    public int selectCountByUserIdAndDeviceId(UserEquipment userEquipment1) {

        // 开门时，时间提前。
//        QueryWrapper<UserEquipment> wrapper = new QueryWrapper<>();
//        wrapper.eq("equipment_id", userEquipment1.getEquipmentId());
//        wrapper.eq("user_id", userEquipment1.getUserId());
//        wrapper.gt("end_date", DateUtil.date());
//        wrapper.lt("start_time", DateUtil.date());
//        return userEquipmentMapper.selectCount(wrapper);


//        LambdaQueryWrapper<UserEquipment> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(UserEquipment::getEquipmentId, userEquipment1.getEquipmentId())
//                .eq(UserEquipment::getUserId, userEquipment1.getUserId())
//                .gt(UserEquipment::getEndDate, DateUtil.date())
//                .lt(UserEquipment::getStartTime, DateUtil.date());
        return userEquipmentMapper.selectCountByUserIdAndDeviceId(userEquipment1);
    }

    @Override
    public int selectListByEquipmentId(Long id) {
        QueryWrapper<UserEquipment> wrapper = new QueryWrapper<>();
        wrapper.eq("equipment_id", id);
        return userEquipmentMapper.selectCount(wrapper);
    }

    @Override
    public int deleteUserEquipmentByUserId(Long userId,Long deviceId) {
        UpdateWrapper<UserEquipment> wrapper = new UpdateWrapper<>();
        wrapper.eq("user_id", userId);
        wrapper.eq("equipment_id", deviceId);
        return userEquipmentMapper.delete(wrapper);
    }

    @Override
    public int selectListByUserId(Long userId) {
        QueryWrapper<UserEquipment> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        return userEquipmentMapper.selectCount(wrapper);
    }

    @Override
    public List<UserEquipment> selectUserEquipmentNum(UserEquipment userEquipment) {

        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(null != userEquipment.getEquipmentId(),"equipment_id",userEquipment.getEquipmentId());
        queryWrapper.eq(null != userEquipment.getUserId(),"user_id",userEquipment.getUserId());
        queryWrapper.eq(null != userEquipment.getStartTime(),"start_time",userEquipment.getStartTime());
        queryWrapper.eq(null != userEquipment.getEndDate(),"end_date",userEquipment.getEndDate());
        queryWrapper.in(CollUtil.isNotEmpty(userEquipment.getUserIds()),"user_id",userEquipment.getUserIds());
        queryWrapper.groupBy("equipment_id");
        return userEquipmentMapper.selectList(queryWrapper);
    }

    @Override
    public List<UserEquipment> selectUserEquipmentNumByUserId(UserEquipment userEquipment) {

        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(null != userEquipment.getEquipmentId(),"equipment_id",userEquipment.getEquipmentId());
        queryWrapper.eq(null != userEquipment.getUserId(),"user_id",userEquipment.getUserId());
        queryWrapper.eq(null != userEquipment.getStartTime(),"start_time",userEquipment.getStartTime());
        queryWrapper.eq(null != userEquipment.getEndDate(),"end_date",userEquipment.getEndDate());
        queryWrapper.in(CollUtil.isNotEmpty(userEquipment.getUserIds()),"user_id",userEquipment.getUserIds());
        queryWrapper.groupBy("user_id");
        return userEquipmentMapper.selectList(queryWrapper);
    }

    @Override
    public List<Long> selectEquipmentIdByUserId(Long userId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id",userId);
        List<UserEquipment> list = userEquipmentMapper.selectList(queryWrapper);
        List<Long> deviceIds = list.stream().
                map(UserEquipment::getEquipmentId).
                collect(Collectors.toList());
        return deviceIds;
    }

    @Override
    public List<Long> selectEquipmentIdByEquipmentId(Long id) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("equipment_id",id);
        List<UserEquipment> list = userEquipmentMapper.selectList(queryWrapper);
        List<Long> userIds = list.stream().
                map(UserEquipment::getUserId).
                collect(Collectors.toList());
        return userIds;

    }


    public void updateDeviceDataSource(List<Equipment> equipments) {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

        RequestContextHolder.setRequestAttributes(requestAttributes,true);


        // 创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        CountDownLatch countDownLatch = new CountDownLatch(equipments.size());
        // 开始任务
        for (Equipment equipment : equipments) {

            executorService.submit(() -> {
                EquipmentMapper equipmentMapper = BeanContext.getApplicationContext().getBean(EquipmentMapper.class);

                try {
//                    Equipment equipment1 = equipmentMapper.selectEquipmentById(equipment.getId());
//                    System.out.println(equipment1);
                    //
                    Boolean isHost = DeviceUtils.ping(equipment.getIp());
                    if (!isHost) {
                        equipment.setStatus(2L);
                        equipmentMapper.updateEquipment(equipment);
                    } else {
                        String active = DeviceUtils.getActive(equipment.getIp());
                        JSONObject jsonObject = JSONUtil.parseObj(active);
                        JSONObject data = (JSONObject) jsonObject.get("data");
                        String aBoolean = (String) data.get("isActivated");
                        Boolean aBoolean1 = Boolean.valueOf(aBoolean);
                        if (aBoolean1) {
                            equipment.setStatus(0L);
                        } else {
                            equipment.setStatus(2L);
                        }
                        equipmentMapper.updateEquipment(equipment);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                    // 处理异常
                } finally {
                    countDownLatch.countDown();
                }
            });
        }
        // 等待所有线程执行完成
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


}
