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

#import "BCAPoiSearchTask.h"
#import "BCAMapNavigateModel.h"

#import <BaiduMapAPI_Base/BMKBaseComponent.h>
#import <BaiduMapAPI_Search/BMKSearchComponent.h>

@interface BCAPoiSearchTask ()<BMKPoiSearchDelegate>

@property (nonatomic, strong) BCALocation *currentLocation;
@property (nonatomic, strong) NSArray<BCALocation *> *locations;
@property (nonatomic, copy) BCAPoiSearchCompletionBlock completion;
@property (nonatomic, assign) NSInteger completedCount;
@property (nonatomic, strong) NSError *lastError;
@property (nonatomic, assign) BOOL isCancelled;
@property (nonatomic, assign) BOOL isFinished;

@property (nonatomic, strong) NSMutableDictionary<NSNumber *, BMKPoiSearch *> *poiSearchs;

@end

@implementation BCAPoiSearchTask

- (instancetype)initWithLocations:(NSArray<BCALocation *> *)locations
                  currentLocation:(BCALocation *)currentLocation
                       completion:(BCAPoiSearchCompletionBlock)completion {
    if (self = [super init]) {
        _locations = [locations copy];
        _completion = [completion copy];
        _currentLocation = currentLocation;
        _completedCount = 0;
        _isCancelled = NO;
    }
    return self;
}

- (void)start {
    if (self.locations.count == 0) {
        if (self.completion) {
            self.completion(@[], nil);
        }
        return;
    }
    
    self.poiSearchs = [NSMutableDictionary dictionary];
    
    for (NSInteger i = 0; i < self.locations.count; i++) {
        BCALocation *location = self.locations[i];
        
        // 本地位置或已有坐标，不请求
        if ([location.name isEqualToString:kMapNavigateCurrentStartTitle]) {
            location.coordinate = self.currentLocation.coordinate;
            self.completedCount++;
            continue;
        }
        
        if (location.coordinate.latitude > 0 & location.coordinate.longitude > 0) {
            self.completedCount++;
            continue;
        }
        
        BMKPoiSearch *searcher = [self searchPoiWithLocation:location];
        self.poiSearchs[@(i)] = searcher;
    }
}

- (void)cancel {
    self.isCancelled = YES;
    if (self.completion) {
        NSError *error = self.lastError ? self.lastError : [NSError errorWithDomain:NSCocoaErrorDomain code:-1001 userInfo:nil];
        self.completion(self.locations, error);
    }
}

- (BMKPoiSearch *)searchPoiWithLocation:(BCALocation *)location {
    BMKPOICitySearchOption *cityOption = [[BMKPOICitySearchOption alloc] init];
    cityOption.keyword = location.name;
    cityOption.city = self.currentLocation.city;
    cityOption.isCityLimit = YES;
    
    BMKPoiSearch *searcher = [[BMKPoiSearch alloc] init];
    searcher.delegate = self;
    
    BOOL success = [searcher poiSearchInCity:cityOption];
    if (!success) {
        NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain code:BCAPoiSearchErrorCallFail userInfo:nil];
        self.lastError = error;
        [self cancel];
    }
    
    return searcher;
}

- (BOOL)checkTaskFinished {
    if (self.completedCount >= self.locations.count) {
        if (self.completion) {
            self.completion(self.locations, nil);
        }
        self.isFinished = YES;
        return YES;
    } else {
        return NO;
    }
}

#pragma mark - BMKPoiSearchDelegate

- (void)onGetPoiResult:(BMKPoiSearch *)searcher result:(BMKPOISearchResult *)poiResult errorCode:(BMKSearchErrorCode)errorCode {
    if (self.isCancelled || self.isFinished) {
        return;
    }
    
    if (errorCode == BMK_SEARCH_NO_ERROR && poiResult.poiInfoList.count > 0) {
        // 检索成功
        BMKPoiInfo *poiInfo = [poiResult.poiInfoList firstObject];
        
        NSInteger index = [[[self.poiSearchs allKeysForObject:searcher] firstObject] integerValue];
        if (index < self.locations.count) {
            // replacing with BMKPoiSearchResult
            BCALocation *location = [self.locations objectAtIndex:index];
            location.coordinateType = 1;
            location.coordinate = poiInfo.pt;
            location.name = poiInfo.name;
            location.detailAddress = poiInfo.address;
            location.province = poiInfo.province;
            location.city = poiInfo.city;
        }
        self.completedCount++;
    } else {
        // 检索失败
        NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain code:BCAPoiSearchErrorSearchFail userInfo:nil];
        self.lastError = error;
        self.searchErrorCode = errorCode;
        [self cancel];
    }
    
    [self checkTaskFinished];
}

@end
