//
//  BCAMapNavigateModel.m
//  ChatAgentApp
//
//  Created by caoshiqian on 2025/4/21.
//

#import "BCAMapNavigateModel.h"
#import "BCALocationManager.h"
#import "BCAMapNavigateDriveModel.h"
#import "BNaviUtil.h"

NSString *const kMapNavigateParamTypeKey     = @"navi_type";
NSString *const kMapNavigateParamStartKey    = @"start_position";
NSString *const kMapNavigateParamEndKey      = @"navi_position";

NSString *const kMapNavigateCurrentStartTitle = @"我的位置";

@interface BCAMapNavigateModel ()<BCALocationManagerDelegate, BNNaviSoundDelegate>

@property (nonatomic, strong) BCALocationManager *locationManager;
@property (nonatomic, assign) int agentAudioState;

@end

@implementation BCAMapNavigateModel

+ (instancetype)modelWithParams:(NSDictionary *)params {
    BCAMapNavigateModel *model = nil;
    NSString *typeStr = [params objectForKey:kMapNavigateParamTypeKey];
    if ([typeStr isEqualToString:@"drive"] || typeStr.length == 0) {
        model = [[BCAMapNavigateDriveModel alloc] initWithParams:params];
    } else {
        // not supported
    }
    return model;
}

- (instancetype)initWithParams:(NSDictionary *)params {
    if (self = [super init]) {
        [[BNaviUtil sharedInstance] setSoundDelegate:self];
        [[BNaviUtil sharedInstance] initMap];
        [[BNaviUtil sharedInstance] initNavi];
        [self resolveParams:params];
    }
    return self;
}

- (BN_NaviType)naviType {
    return BN_NaviTypeReal;
}

- (void)startRoutePlan {
    
}

- (void)enterNaviPage {
    
}

- (void)startNavigation {
    
}

- (void)startLocating {
    [self.locationManager requestLocationPermission];
    [self.locationManager stopUpdatingLocation];
    [self.locationManager stopUpdatingHeading];
    [self.locationManager startUpdatingLocation];
    [self.locationManager startUpdatingHeading];
}

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

- (UIView *)routePlanPreviewView {
    return nil;
}

- (void)onAgentAudioStateChange:(int)state {
    self.agentAudioState = state;
}

#pragma mark - private

- (void)resolveParams:(NSDictionary *)params {
    // 起点
    NSString *start = [params objectForKey:kMapNavigateParamStartKey];
    if (start.length == 0 || [self isParamCurrentPosition:start]) {
        start = kMapNavigateCurrentStartTitle;
    }
    BCALocation *startLoc = [[BCALocation alloc] init];
    startLoc.name = start;
    self.startPosition = startLoc;
    
    // 途经点 & 终点
    self.endPositions = [NSMutableArray array];
    NSMutableArray *ends = [NSMutableArray array];
    id endsParam = [params objectForKey:kMapNavigateParamEndKey];
    if ([endsParam isKindOfClass:[NSArray class]]) {
        [ends addObjectsFromArray:endsParam];
    } else if ([endsParam isKindOfClass:[NSString class]]) {
        NSArray *endArray = [endsParam componentsSeparatedByString:@","];
        [ends addObjectsFromArray:endArray];
    }
    
    for (NSString *end in ends) {
        BCALocation *loc = [[BCALocation alloc] init];
        loc.name = end;
        [self.endPositions addObject:loc];
    }
}

- (BOOL)isParamCurrentPosition:(NSString *)param {
    NSArray *startKeys = @[ @"我的位置", @"当前位置", @"现在位置" ];
    for (NSString *key in startKeys) {
        if ([param containsString:key]) {
            return YES;
        }
    }
    return NO;
}

- (BCALocationManager *)locationManager {
    if (!_locationManager) {
        _locationManager = [[BCALocationManager alloc] init];
        _locationManager.delegate = self;
    }
    return _locationManager;
}

#pragma mark - BCALocationManagerDelegate

- (void)locationManagerDidChangeAuthorizationStatus:(BOOL)authorized {
    NSLog(@"[map][location] didChangeAuthorizationStatus: %@", @(authorized));
    
    CLAuthorizationStatus status = [self.locationManager authorizationStatus];
    if (status == kCLAuthorizationStatusAuthorizedWhenInUse || status == kCLAuthorizationStatusAuthorizedAlways) {
        [[BNaviUtil sharedInstance] setAlwaysUpdatingLocation:YES];
    }
}

- (void)locationManagerDidUpdateLocation:(BCALocation *)location {
    NSLog(@"[map][location] didUpdateLocation: %@", location.description);
}

- (void)locationManagerDidFailWithError:(NSError *)error {
    NSLog(@"[map][location] didFailWithError: %@", error);
}

#pragma mark - BNNaviSoundDelegate

- (void)onPlayTTS:(NSString *)text userInfo:(NSDictionary *)userInfo {
    NSLog(@"[map] onPlayTTS text = %@", text);
    // 发送TTS播报到收到状态回调消息之间有延迟，会导致连续输出文本，仍然造成打断，这里在本地发送时直接视为已进入说话状态
    [self onAgentAudioStateChange:1];
    [self.delegate mapNavigateModel:self onPlayTTS:text];
}

- (void)onPlayVoiceSound:(BNVoiceSoundType)type filePath:(NSString *)filePath {
    NSLog(@"[map] onPlayTTS type = %i，filePath = %@", type, filePath);
}

- (void)onTTSAuthorized:(BOOL)success {
    
}

- (BOOL)ttsIsPlaying {
    NSLog(@"[map] ttsIsPlaying: %d", self.agentAudioState);
    return self.agentAudioState == 1;
}

#pragma mark - callback

- (void)callbackFinishWithCode:(NSInteger)code error:(NSError *)error {
    if ([self.delegate respondsToSelector:@selector(mapNavigateModel:finishWithError:)]) {
        NSError *err = [NSError errorWithDomain:NSCocoaErrorDomain code:code userInfo:error.userInfo];
        [self.delegate mapNavigateModel:self finishWithError:err];
    }
}

- (void)callbackFinishWithCode:(NSInteger)code message:(NSString *)message {
    if ([self.delegate respondsToSelector:@selector(mapNavigateModel:finishWithError:)]) {
        NSError *err = [NSError errorWithDomain:NSCocoaErrorDomain code:code userInfo:@{ NSLocalizedDescriptionKey: message }];
        [self.delegate mapNavigateModel:self finishWithError:err];
    }
}

- (void)callbackRoutePlanDidFinished:(NSDictionary *)info {
    if ([self.delegate respondsToSelector:@selector(mapNavigateModel:routePlanDidFinished:)]) {
        [self.delegate mapNavigateModel:self routePlanDidFinished:@{}];
    }
}

@end
