package de.cannamanage.service;

import de.cannamanage.domain.entity.DeviceToken;
import de.cannamanage.domain.enums.DevicePlatform;
import de.cannamanage.service.repository.DeviceTokenRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.util.List;
import java.util.UUID;

/**
 * Manages device token registration for push notifications.
 * Max 10 devices per user to prevent abuse.
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DeviceRegistrationService {

    private static final int MAX_DEVICES_PER_USER = 10;

    private final DeviceTokenRepository deviceTokenRepository;

    /**
     * Register a device token (upsert: if token exists, update lastUsedAt).
     */
    @Transactional
    public DeviceToken registerDevice(UUID userId, DevicePlatform platform, String token, String deviceName) {
        // Check if this exact token already exists for this user
        var existing = deviceTokenRepository.findByUserIdAndToken(userId, token);
        if (existing.isPresent()) {
            var dt = existing.get();
            dt.setLastUsedAt(Instant.now());
            dt.setDeviceName(deviceName);
            log.debug("Updated existing device token for user {}", userId);
            return deviceTokenRepository.save(dt);
        }

        // Enforce max device limit
        long count = deviceTokenRepository.countByUserId(userId);
        if (count >= MAX_DEVICES_PER_USER) {
            throw new IllegalStateException("Maximum device limit (" + MAX_DEVICES_PER_USER + ") reached");
        }

        var deviceToken = DeviceToken.builder()
                .userId(userId)
                .platform(platform)
                .token(token)
                .deviceName(deviceName)
                .lastUsedAt(Instant.now())
                .build();

        log.debug("Registered new {} device for user {}", platform, userId);
        return deviceTokenRepository.save(deviceToken);
    }

    /**
     * List all registered devices for a user.
     */
    @Transactional(readOnly = true)
    public List<DeviceToken> getDevices(UUID userId) {
        return deviceTokenRepository.findByUserId(userId);
    }

    /**
     * Unregister a device by ID (owner check done in controller).
     */
    @Transactional
    public void unregisterDevice(UUID deviceId, UUID userId) {
        deviceTokenRepository.findById(deviceId).ifPresent(dt -> {
            if (dt.getUserId().equals(userId)) {
                deviceTokenRepository.delete(dt);
                log.debug("Unregistered device {} for user {}", deviceId, userId);
            }
        });
    }
}
