//
//  BCALocationManager.m
//  ChatAgentApp
//
//  Created by caoshiqian on 2025/4/20.
//

#import "BCALocationManager.h"
#import <CoreLocation/CoreLocation.h>
#import <UIKit/UIKit.h>
#import <SystemConfiguration/CaptiveNetwork.h>

@implementation BCALocation

- (instancetype)initWithLocation:(CLLocation *)location placemark:(CLPlacemark *)placemark {
    self = [super init];
    if (self) {
        _coordinate = location.coordinate;
        _timestamp = location.timestamp;
        
        if (placemark) {
            _name = placemark.name;
            _province = placemark.administrativeArea;
            _city = placemark.locality;
            _district = placemark.subLocality;
            _street = placemark.thoroughfare;
            
            NSMutableString *detailAddress = [NSMutableString string];
            if (_province) [detailAddress appendString:_province];
            if (_city) [detailAddress appendFormat:@"%@", _city];
            if (_district) [detailAddress appendFormat:@"%@", _district];
            if (_street) [detailAddress appendFormat:@"%@", _street];
            if (placemark.subThoroughfare) [detailAddress appendFormat:@"%@", placemark.subThoroughfare];
            
            _detailAddress = [detailAddress copy];
            
            // 位置描述
            NSMutableString *description = [NSMutableString string];
            if (placemark.name) [description appendString:placemark.name];
            if (description.length == 0 && _detailAddress) {
                _locationDescription = _detailAddress;
            } else {
                _locationDescription = [description copy];
            }
        }
    }
    return self;
}

- (NSString *)description {
    return [NSString stringWithFormat:@"<BCALocation: %p> coordinate: {%.6f, %.6f}, province: %@, city: %@, district: %@, street: %@, detailAddress: %@, description: %@, timestamp: %@",
            self,
            self.coordinate.latitude,
            self.coordinate.longitude,
            self.province ?: @"未知",
            self.city ?: @"未知",
            self.district ?: @"未知",
            self.street ?: @"未知",
            self.detailAddress ?: @"未知",
            self.locationDescription ?: @"未知",
            self.timestamp ? [NSDateFormatter localizedStringFromDate:self.timestamp dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterMediumStyle] : @"未知"];
}

@end


@interface BCALocationManager () <CLLocationManagerDelegate>

@property (nonatomic, strong) CLLocationManager *locationManager;
@property (nonatomic, strong) BCALocation *currentLocation;
@property (nonatomic, assign) BOOL hasRequestedPermission;
@property (nonatomic, strong) NSString *lastNetworkInfo;
// 添加属性用于过滤重复位置更新
@property (nonatomic, strong) CLLocation *lastReportedLocation;
@property (nonatomic, strong) NSDate *lastReportedTime;
@property (nonatomic, assign) CLLocationDistance minimumDistanceFilter; // 最小距离过滤器（米）
@property (nonatomic, assign) NSTimeInterval minimumTimeFilter; // 最小时间过滤器（秒）

@end

@implementation BCALocationManager

- (instancetype)init {
    self = [super init];
    if (self) {
        _locationManager = [[CLLocationManager alloc] init];
        _locationManager.delegate = self;
        _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        _locationManager.distanceFilter = 10.0; // 10米
        _locationManager.allowsBackgroundLocationUpdates = YES;
        _updateInterval = 300.0; // 默认5分钟
        _hasRequestedPermission = NO;
        
        _minimumDistanceFilter = 50.0; // 默认50米距离过滤
        _minimumTimeFilter = 60.0;     // 默认60秒时间过滤
        
        // 监听网络变化
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(networkStatusChanged:)
                                                     name:@"kNetworkReachabilityChangedNotification"
                                                   object:nil];
        
        // 监听应用进入前台
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(applicationWillEnterForeground:)
                                                     name:UIApplicationWillEnterForegroundNotification
                                                   object:nil];
    }
    return self;
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

#pragma mark - Public

- (CLAuthorizationStatus)authorizationStatus {
    if (@available(iOS 14.0, *)) {
        return self.locationManager.authorizationStatus;
    } else {
        return [CLLocationManager authorizationStatus];
    }
}

- (BOOL)requestLocationPermission {
    if (_hasRequestedPermission) {
        return YES;
    }
    if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
        [self.locationManager requestWhenInUseAuthorization];
    }
    _hasRequestedPermission = YES;
    self.lastNetworkInfo = [self currentNetwork];
    return NO;
}

- (void)requestLocation {
    if (![self checkLocationPermission]) {
        return;
    }
    
    [self.locationManager requestLocation];
}

- (void)startUpdatingLocation {
    [self.locationManager startUpdatingLocation];
}

- (void)stopUpdatingLocation {
    [self.locationManager stopUpdatingLocation];
}

- (void)startUpdatingHeading {
    [self.locationManager stopUpdatingHeading];
}

- (void)stopUpdatingHeading {
    [self.locationManager stopUpdatingHeading];
}

#pragma mark - Private

- (BOOL)checkLocationPermission {
    CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
    
    if (status == kCLAuthorizationStatusNotDetermined && !_hasRequestedPermission) {
        NSError *error = [NSError errorWithDomain:@"BCALocationErrorDomain"
                                             code:1
                                         userInfo:@{NSLocalizedDescriptionKey: @"首次使用必须由用户主动触发位置权限请求"}];
        [self notifyDelegateOfError:error];
        return NO;
    }
    
    if (status == kCLAuthorizationStatusDenied || status == kCLAuthorizationStatusRestricted) {
        NSError *error = [NSError errorWithDomain:@"BCALocationErrorDomain"
                                             code:2
                                         userInfo:@{NSLocalizedDescriptionKey: @"位置权限被拒绝"}];
        [self notifyDelegateOfError:error];
        return NO;
    }
    
    return YES;
}

- (NSString *)currentNetwork {
    NSArray *interfaceNames = (__bridge_transfer NSArray *)CNCopySupportedInterfaces();
    NSString *networkInfo = @"";
    
    for (NSString *interfaceName in interfaceNames) {
        NSDictionary *networkInfoDict = (__bridge_transfer NSDictionary *)CNCopyCurrentNetworkInfo((__bridge CFStringRef)interfaceName);
        if (networkInfoDict[@"SSID"]) {
            networkInfo = [NSString stringWithFormat:@"%@", networkInfoDict[@"SSID"]];
            break;
        }
    }
    
    return networkInfo;
}

- (BOOL)hasNetworkChanged {
    NSString *currentNetworkInfo = [self currentNetwork];
    BOOL changed = ![self.lastNetworkInfo isEqualToString:currentNetworkInfo];
    if (changed) {
        self.lastNetworkInfo = currentNetworkInfo;
    }
    
    return changed;
}

- (void)notifyDelegateOfError:(NSError *)error {
    if ([self.delegate respondsToSelector:@selector(locationManagerDidFailWithError:)]) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.delegate locationManagerDidFailWithError:error];
        });
    }
}

#pragma mark - Notification Handlers

- (void)networkStatusChanged:(NSNotification *)notification {
    if (_hasRequestedPermission && [self hasNetworkChanged] && self.isUpdatingLocation) {
        [self.locationManager requestLocation];
    }
}

- (void)applicationWillEnterForeground:(NSNotification *)notification {
    if (_hasRequestedPermission && self.isUpdatingLocation) {
        [self.locationManager requestLocation];
    }
}

#pragma mark - CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
    BOOL authorized = (status == kCLAuthorizationStatusAuthorizedWhenInUse ||
                       status == kCLAuthorizationStatusAuthorizedAlways);

    if ([self.delegate respondsToSelector:@selector(locationManagerDidChangeAuthorizationStatus:)]) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.delegate locationManagerDidChangeAuthorizationStatus:authorized];
        });
    }
    
    if (authorized && self.isUpdatingLocation) {
        [manager requestLocation];
    }
}

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
    CLLocation *location = [locations lastObject];
    
    // 过滤逻辑：检查是否需要处理此位置更新
    if (![self shouldProcessLocation:location]) {
        return;
    }
    
    // 更新最后报告的位置和时间
    self.lastReportedLocation = location;
    self.lastReportedTime = [NSDate date];
    
    // 反向地理编码获取地址信息
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        if (error) {
            [self notifyDelegateOfError:error];
            return;
        }
        
        CLPlacemark *placemark = [placemarks firstObject];
        BCALocation *bcaLocation = [[BCALocation alloc] initWithLocation:location placemark:placemark];
//        bcaLocation.coordinate = BMKCoordTrans(location.coordinate, BMK_COORDTYPE_GPS, BMK_COORDTYPE_BD09LL);
        bcaLocation.coordinateType = 1;
        
        self.currentLocation = bcaLocation;
        
        if ([self.delegate respondsToSelector:@selector(locationManagerDidUpdateLocation:)]) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [self.delegate locationManagerDidUpdateLocation:bcaLocation];
            });
        }
    }];
}

// 添加判断是否应该处理位置更新的方法
- (BOOL)shouldProcessLocation:(CLLocation *)location {
    // 如果是首次位置更新，直接处理
    if (!self.lastReportedLocation || !self.lastReportedTime) {
        return YES;
    }
    
    // 检查位置精度，如果精度太差，可能不值得更新
    if (location.horizontalAccuracy < 0 || location.horizontalAccuracy > 100) {
        return NO;
    }
    
    // 检查时间间隔
    NSTimeInterval timeSinceLastReport = [[NSDate date] timeIntervalSinceDate:self.lastReportedTime];
    if (timeSinceLastReport < self.minimumTimeFilter) {
        // 时间间隔太短，检查距离变化是否足够大
        CLLocationDistance distance = [location distanceFromLocation:self.lastReportedLocation];
        if (distance < self.minimumDistanceFilter) {
            // 距离变化不够大，不处理此更新
            return NO;
        }
    }
    
    // 检查位置时间戳，避免处理过时的位置
    if ([location.timestamp compare:self.lastReportedLocation.timestamp] == NSOrderedAscending) {
        // 这是一个更早的位置，忽略它
        return NO;
    }
    
    return YES;
}

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
    
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    [self notifyDelegateOfError:error];
}

@end
