//
//  AMapRoute.m
//  react-native-anavi
//
//  Created by xiuyanger on 2020/9/15.
//

#import "AMapPathRouteView.h"
#import "AMapUtility.h"

@interface AMapPathRouteView()<AMapSearchDelegate>
@end

@implementation AMapPathRouteView {
    MAPointAnnotation *startAnnotation;
    MAPointAnnotation *destinationAnnotation;
}

-(instancetype) init {
    if(self = [super init]) {
        self.search = [[AMapSearchAPI alloc] init];
        self.search.delegate = self;
    }
    
    return self;
}

@synthesize startPoint = _startPoint;
-(void)setStartPoint:(CLLocationCoordinate2D)startCoordinate {
    if(_startPoint.latitude == startCoordinate.latitude && _startPoint.longitude == startCoordinate.longitude) {
        return;
    }
    _startPoint = startCoordinate;
    [self calculateRoute];
}
-(CLLocationCoordinate2D) startPoint {
    return _startPoint;
}

@synthesize endPoint = _endPoint;
-(void) setEndPoint:(CLLocationCoordinate2D)destinationCoordinate {
    if(_endPoint.latitude == destinationCoordinate.latitude && _endPoint.longitude == destinationCoordinate.longitude) {
        return;
    }
    _endPoint = destinationCoordinate;
    [self calculateRoute];
}
-(CLLocationCoordinate2D) endPoint {
    return _endPoint;
}

-(void) calculateRoute {
    
}

-(void) presentRoute {
    [self clear];
    [self addStartAndEndAnnotations];
}

-(AMapPathAnnotationType) routeType {
    @throw [NSException exceptionWithName:@"Not assign a routeType" reason:@"You must override this class and provide a routeType" userInfo:nil];
}

-(void) clear {
    if(startAnnotation != nil) {
        [self.mapView removeAnnotation:startAnnotation];
        startAnnotation = nil;
    }
    if(destinationAnnotation != nil) {
        [self.mapView removeAnnotation:destinationAnnotation];
        destinationAnnotation = nil;
    }
    if(self.pathRoute != nil) {
        [self.pathRoute clear];
    }
}

-(void) addToMapView:(MAMapView *)mapView {
    self.mapView = mapView;
    [self calculateRoute];
}

-(void) removeFromMapView {
    [self clear];
    
    self.mapView = nil;
}

//在地图上添加起始和终点的标注点
- (void)addStartAndEndAnnotations {
    AMapPathAnnotation *start = [[AMapPathAnnotation alloc] init];
    start.type = MANaviAnnotationTypeStart;
    start.image = self.startMarkerIcon;
    start.coordinate = self.startPoint;
    start.title = self.startMarkerTitle;
    startAnnotation = start;
    
    AMapPathAnnotation *destination = [[AMapPathAnnotation alloc] init];
    destination.type = MANaviAnnotationTypeEnd;
    destination.image = self.endMarkerIcon;
    destination.coordinate = self.endPoint;
    destination.title = self.endMarkerTitle;
    destinationAnnotation = destination;
    
    [self.mapView addAnnotation:startAnnotation];
    [self.mapView addAnnotation:destinationAnnotation];
}

#pragma mark - AMapSearchDelegate

//当路径规划搜索请求发生错误时，会调用代理的此方法
- (void)AMapSearchRequest:(id)request didFailWithError:(NSError *)error {
    NSLog(@"Error: %@", error);
    if(self.onSearchComplete) {
        self.onSearchComplete(@{@"code": @2});
    }
}

//路径规划搜索完成回调.
- (void)onRouteSearchDone:(AMapRouteSearchBaseRequest *)request response:(AMapRouteSearchResponse *)response {
    if (response.route == nil || response.route.paths.count == 0){
        if(self.onSearchComplete) {
            self.onSearchComplete(@{@"code": @1});
        }
        return;
    }
    self.route = response.route;
    if(self.onSearchComplete) {
        NSMutableArray *steps = [NSMutableArray array];
        for(AMapStep *step in self.route.paths[0].steps) {
            NSMutableArray *polyline = [NSMutableArray array];
            if(step.polyline != nil && step.polyline.length > 0) {
                NSUInteger count = 0;
                CLLocationCoordinate2D *coordinates = [AMapUtility coordinatesForString:step.polyline
                                                                        coordinateCount:&count
                                                                             parseToken:@";"];
                for(NSUInteger i = 0; i < count; ++i) {
                    CLLocationCoordinate2D location = *(coordinates + i);
                    [polyline addObject:@{@"latitude": @(location.latitude), @"longitude": @(location.longitude)}];
                }
                (void)(free(coordinates)), coordinates = NULL;
            }
            [steps addObject:@{
                @"instruction": step.instruction == nil ? @"" : step.instruction,
                @"orientation": step.orientation == nil ? @"" : step.orientation,
                @"road": step.road == nil ? @"" : step.road,
                @"distance": @(step.distance),
                @"duration": @(step.duration),
                @"action": step.action == nil ? @"": step.action,
                @"assistantAction": step.assistantAction == nil ? @"" : step.assistantAction,
                @"polyline": polyline
            }];
        }
        self.onSearchComplete(@{@"code": @0, @"path": @{@"steps": steps}});
    }
    [self presentRoute];
}
@end
