package com.seer.teach.iot.api;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.seer.teach.common.enums.ResultCodeEnum;
import com.seer.teach.common.utils.AssertUtils;
import com.seer.teach.iot.api.req.UserDeviceReqDTO;
import com.seer.teach.iot.api.resp.DeviceRespDTO;
import com.seer.teach.iot.api.resp.UserDeviceRespDTO;
import com.seer.teach.iot.convert.DevicesConvert;
import com.seer.teach.iot.convert.UserDeviceConvert;
import com.seer.teach.iot.module.entity.DevicesEntity;
import com.seer.teach.iot.module.entity.UserDevicesEntity;
import com.seer.teach.iot.service.DevicesService;
import com.seer.teach.iot.service.UserDevicesService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@Service
public class UserDeviceServiceApiImpl implements UserDeviceServiceApi {

    private final UserDevicesService userDevicesService;

    private final DevicesService devicesService;
    /**
     * 根据设备号获取用户 ID
     *
     * @param device 设备号（如 SN 编号）
     * @return 用户 ID
     * @throws IllegalArgumentException 如果设备不存在或未绑定用户
     */
    @Override
    public Integer getUserIdByDevice(String device) {
        DevicesEntity devices = devicesService.getOne(new LambdaQueryWrapper<DevicesEntity>()
                .eq(DevicesEntity::getUnionId, device));
        AssertUtils.notNull(devices, ResultCodeEnum.DEVICE_NOT_FOUND);
        UserDevicesEntity userDevice = userDevicesService.getOne(new LambdaQueryWrapper<UserDevicesEntity>()
                .eq(UserDevicesEntity::getDeviceId, devices.getId()));
        AssertUtils.notNull(userDevice, ResultCodeEnum.EQUIPMENT_NOT_BIND);

        return userDevice.getUserId();
    }

    /**
     * 保存用户与设备的绑定关系
     *
     * @param userDeviceReqDTO 用户设备绑定请求参数
     * @return 是否保存成功
     */
    @Override
    public boolean save(UserDeviceReqDTO userDeviceReqDTO) {
        UserDevicesEntity userDevice = userDevicesService.getOne(new LambdaQueryWrapper<UserDevicesEntity>()
                .eq(UserDevicesEntity::getDeviceId, userDeviceReqDTO.getDeviceId()));
        AssertUtils.isNull(userDevice, ResultCodeEnum.DEVICE_IS_BIND);
        userDevice = new UserDevicesEntity();
        userDevice.setUserId(userDeviceReqDTO.getUserId());
        userDevice.setDeviceId(userDeviceReqDTO.getDeviceId());
        return userDevicesService.save(userDevice);
    }

    /**
     * 根据主键 ID 获取用户设备关系
     *
     * @param id 用户设备关系 ID
     * @return 用户设备响应对象
     */
    @Override
    public UserDeviceRespDTO getUserDeviceById(Integer id) {
        UserDevicesEntity userDevice = userDevicesService.getById(id);
        return UserDeviceConvert.INSTANCE.convertOne(userDevice);
    }

    /**
     * 根据用户 ID 获取用户设备关系
     *
     * @param userId 用户 ID
     * @return 用户设备响应对象
     */
    @Override
    public UserDeviceRespDTO getUserDeviceByUserId(Integer userId) {
        UserDevicesEntity userDevice = userDevicesService.getOne(
                new LambdaQueryWrapper<UserDevicesEntity>()
                        .eq(UserDevicesEntity::getUserId, userId));
        return UserDeviceConvert.INSTANCE.convertOne(userDevice);
    }

    @Override
    public UserDeviceRespDTO getUserDeviceByDeviceId(Integer deviceId) {
        UserDevicesEntity userDevice = userDevicesService.getOne(
                new LambdaQueryWrapper<UserDevicesEntity>()
                        .eq(UserDevicesEntity::getDeviceId, deviceId));
        return UserDeviceConvert.INSTANCE.convertOne(userDevice);
    }

    /**
     * 根据用户 ID 获取设备 ID
     *
     * @param userId 用户 ID
     * @return 设备 ID
     * @throws IllegalArgumentException 如果未绑定设备或设备不存在
     */
    @Override
    public Integer getDeviceIdByUserId(Integer userId) {
        UserDevicesEntity userDevice = userDevicesService.getOne(
                new LambdaQueryWrapper<UserDevicesEntity>()
                        .eq(UserDevicesEntity::getUserId, userId));
        AssertUtils.notNull(userDevice, ResultCodeEnum.EQUIPMENT_NOT_BIND);
        DevicesEntity device = devicesService.getById(userDevice.getDeviceId());
        AssertUtils.notNull(device, ResultCodeEnum.DEVICE_NOT_FOUND);
        return device.getId();
    }

    /**
     * 根据用户 ID 获取设备号
     *
     * @param userId 用户 ID
     * @return 设备号字符串
     * @throws IllegalArgumentException 如果未绑定设备或设备不存在
     */
    @Override
    public String getDeviceByUserId(Integer userId) {
        UserDevicesEntity userDevice = userDevicesService.getOne(
                new LambdaQueryWrapper<UserDevicesEntity>()
                        .eq(UserDevicesEntity::getUserId, userId));
        AssertUtils.notNull(userDevice, ResultCodeEnum.EQUIPMENT_NOT_BIND);

        DevicesEntity devices = devicesService.getById(userDevice.getDeviceId());
        AssertUtils.notNull(devices, ResultCodeEnum.DEVICE_NOT_FOUND);
        return devices.getUnionId();
    }

    @Override
    public DeviceRespDTO getDeviceDTOByUserId(Integer userId) {
        UserDevicesEntity userDevice = userDevicesService.getOne(new LambdaQueryWrapper<UserDevicesEntity>()
                .eq(UserDevicesEntity::getUserId, userId));
        AssertUtils.notNull(userDevice,ResultCodeEnum.USER_NOT_BIND_DEVICE);
        DevicesEntity device = devicesService.getById(userDevice.getDeviceId());
        AssertUtils.notNull(device,ResultCodeEnum.DEVICE_NOT_FOUND);
        return DevicesConvert.INSTANCE.toDeviceDTO(device);
    }

    /**
     * 根据设备 ID 获取用户 ID
     *
     * @param deviceId 设备 ID
     * @return 用户 ID
     * @throws IllegalArgumentException 如果未绑定用户或设备不存在
     */
    @Override
    public Integer getUserIdByDeviceId(Integer deviceId) {
        UserDevicesEntity userDevice = userDevicesService.getOne(
                new LambdaQueryWrapper<UserDevicesEntity>()
                        .eq(UserDevicesEntity::getDeviceId, deviceId));
        AssertUtils.notNull(userDevice, ResultCodeEnum.EQUIPMENT_NOT_BIND);

        DevicesEntity device = devicesService.getById(userDevice.getDeviceId());
        AssertUtils.notNull(device, ResultCodeEnum.DEVICE_NOT_FOUND);

        return userDevice.getUserId();
    }
}
