package com.ruoyi.framework.websocket;


import com.ruoyi.system.domain.UserLocation;
//import lombok.RequiredArgsConstructor;
//import lombok.RequiredArgsConstructor;
//import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Qualifier;

import java.util.List;
import java.util.Collections;  // 添加这个导入

@Service
//@RequiredArgsConstructor
public class LocationService {

    private final RedisTemplate<String, UserLocation> redisTemplate;
    private static final String LOCATION_KEY = "user:location:";
    private static final double EARTH_RADIUS = 6371.0; // 地球半径，单位公里

    // 使用构造器注入，并指定使用哪个RedisTemplate
    public LocationService(@Qualifier("locationRedisTemplate") RedisTemplate<String, UserLocation> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public void updateLocation(UserLocation location) {
        redisTemplate.opsForValue().set(LOCATION_KEY + location.getUserId(), location);
    }

    public List<UserLocation> getNearbyUsers(String userId, double radius) {
        UserLocation currentUser = redisTemplate.opsForValue().get(LOCATION_KEY + userId);
        if (currentUser == null) {
            return Collections.emptyList();
        }

        return redisTemplate.keys(LOCATION_KEY + "*").stream()
                .map(key -> redisTemplate.opsForValue().get(key))
                .filter(loc -> loc != null && !loc.getUserId().equals(userId))
                .filter(loc -> calculateDistance(currentUser, loc) <= radius)
                .collect(Collectors.toList());
    }

    private double calculateDistance(UserLocation loc1, UserLocation loc2) {
        double lat1 = Math.toRadians(loc1.getLatitude());
        double lon1 = Math.toRadians(loc1.getLongitude());
        double lat2 = Math.toRadians(loc2.getLatitude());
        double lon2 = Math.toRadians(loc2.getLongitude());

        double dlon = lon2 - lon1;
        double dlat = lat2 - lat1;

        double a = Math.pow(Math.sin(dlat / 2), 2)
                + Math.cos(lat1) * Math.cos(lat2)
                * Math.pow(Math.sin(dlon / 2), 2);

        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

        return EARTH_RADIUS * c;
    }
}
