package com.erp.user.service.auth.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.erp.user.dto.auth.DeviceResponse;
import com.erp.user.entity.auth.LoginDevice;
import com.erp.user.mapper.LoginDeviceMapper;
import com.erp.user.service.auth.DeviceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 设备管理服务实现
 */
@Slf4j
@Service
public class DeviceServiceImpl extends ServiceImpl<LoginDeviceMapper, LoginDevice> 
        implements DeviceService {
    
    @Override
    public LoginDevice createDevice(Long userId, Long tenantId, String deviceName,
                                     String deviceType, String deviceFingerprint,
                                     String loginIp, String loginLocation, String userAgent) {
        // 先查找是否存在相同设备指纹的设备
        LoginDevice existingDevice = null;
        if (deviceFingerprint != null) {
            existingDevice = this.getOne(new LambdaQueryWrapper<LoginDevice>()
                    .eq(LoginDevice::getUserId, userId)
                    .eq(LoginDevice::getDeviceFingerprint, deviceFingerprint)
                    .eq(LoginDevice::getStatus, 1));
        }
        
        if (existingDevice != null) {
            // 更新已有设备
            existingDevice.setLastActiveAt(LocalDateTime.now());
            existingDevice.setLoginIp(loginIp);
            existingDevice.setLoginLocation(loginLocation);
            existingDevice.setUserAgent(userAgent);
            this.updateById(existingDevice);
            log.info("更新已有设备: deviceId={}, userId={}", existingDevice.getId(), userId);
            return existingDevice;
        }
        
        // 创建新设备
        LoginDevice device = new LoginDevice();
        device.setUserId(userId);
        device.setTenantId(tenantId);
        device.setDeviceName(deviceName);
        device.setDeviceType(deviceType);
        device.setDeviceFingerprint(deviceFingerprint);
        device.setLoginIp(loginIp);
        device.setLoginLocation(loginLocation);
        device.setUserAgent(userAgent);
        device.setLastActiveAt(LocalDateTime.now());
        device.setStatus(1);
        device.setCreatedAt(LocalDateTime.now());
        
        this.save(device);
        log.info("创建设备: deviceId={}, userId={}, deviceName={}", device.getId(), userId, deviceName);
        
        return device;
    }
    
    @Override
    public List<LoginDevice> getLoginDevices(Long userId) {
        return this.list(new LambdaQueryWrapper<LoginDevice>()
                .eq(LoginDevice::getUserId, userId)
                .eq(LoginDevice::getStatus, 1)
                .orderByDesc(LoginDevice::getLastActiveAt));
    }
    
    @Override
    public List<DeviceResponse> getUserDevices(Long userId) {
        List<LoginDevice> devices = getLoginDevices(userId);
        
        return devices.stream()
                .map(this::toDeviceResponse)
                .collect(Collectors.toList());
    }
    
    @Override
    public void invalidateDevice(Long deviceId, Long userId) {
        LoginDevice device = this.getOne(new LambdaQueryWrapper<LoginDevice>()
                .eq(LoginDevice::getId, deviceId)
                .eq(LoginDevice::getUserId, userId));
        
        if (device != null) {
            device.setStatus(0);
            this.updateById(device);
            log.info("使设备失效: deviceId={}, userId={}", deviceId, userId);
        }
    }
    
    @Override
    public void invalidateAllDevices(Long userId, Long exceptDeviceId) {
        List<LoginDevice> devices = this.list(new LambdaQueryWrapper<LoginDevice>()
                .eq(LoginDevice::getUserId, userId)
                .eq(LoginDevice::getStatus, 1)
                .ne(exceptDeviceId != null, LoginDevice::getId, exceptDeviceId));
        
        for (LoginDevice device : devices) {
            device.setStatus(0);
        }
        
        this.updateBatchById(devices);
        log.info("使所有设备失效: userId={}, exceptDeviceId={}, count={}", userId, exceptDeviceId, devices.size());
    }
    
    @Override
    public void updateLastActive(Long deviceId) {
        if (deviceId != null) {
            LoginDevice device = this.getById(deviceId);
            if (device != null) {
                device.setLastActiveAt(LocalDateTime.now());
                this.updateById(device);
            }
        }
    }
    
    private DeviceResponse toDeviceResponse(LoginDevice device) {
        return DeviceResponse.builder()
                .id(device.getId())
                .deviceName(device.getDeviceName())
                .deviceType(device.getDeviceType())
                .loginIp(device.getLoginIp())
                .loginLocation(device.getLoginLocation())
                .lastActiveAt(device.getLastActiveAt() != null ? 
                        device.getLastActiveAt().toString() : null)
                .isCurrent(false)
                .build();
    }
}
