#import "JibestreamConverter.h"


static id ObjectOrNull(id object){
    return object ?: [NSNull null];
}


@implementation JibestreamConverter

+ (NSDictionary *)jMapDestinationToDict:(JMapDestination *) jMapDestination {
    NSMutableArray *waypoints = [NSMutableArray array];
    for (JMapWaypoint *waypoint in jMapDestination.waypoints){
         NSDictionary *waypointDict = [JibestreamConverter jMapWaypointToDict:waypoint];
         [waypoints addObject:waypointDict];
    }
    
    NSMutableArray *locations = [NSMutableArray array];
    for (JMapLocation *location in jMapDestination.locations){
         NSDictionary *locationDict = [JibestreamConverter jMapLocationToDict:location];
         [locations addObject:locationDict];
    }
    
    NSDictionary *dict = @{
        @"id": ObjectOrNull(jMapDestination.id),
        @"name": ObjectOrNull(jMapDestination.name),
        @"description": ObjectOrNull(jMapDestination.description),
        @"tags": ObjectOrNull(jMapDestination.tags),
        @"keywords": ObjectOrNull(jMapDestination.keywords),
        @"extensors": ObjectOrNull(jMapDestination.extensors),
        @"locations": ObjectOrNull(locations),
        @"uris": ObjectOrNull(jMapDestination.uris),
        @"displayMode": ObjectOrNull(jMapDestination.displayMode),
        @"waypoints": ObjectOrNull(waypoints),
    };
    return dict;
}

+ (NSDictionary *)jMapWaypointToDict:(JMapWaypoint *) jMapWaypoint {
    NSDictionary *dict = @{
        @"id": ObjectOrNull(jMapWaypoint.id),
        @"mapId": ObjectOrNull(jMapWaypoint.mapId),
        @"coordinates": ObjectOrNull(jMapWaypoint.coordinates),
        @"associations": ObjectOrNull([JibestreamConverter jMapAssociationToDict:jMapWaypoint.associations]),
    };
    return dict;
}

+ (NSDictionary *) jMapAssociationToDict:(JMapAssociation *) jMapAssociation{
    NSDictionary *dict = @{
        @"destinations":ObjectOrNull(jMapAssociation.destinations),
        @"amenities": ObjectOrNull(jMapAssociation.amenities),
    };
    return dict;
}

+ (NSDictionary *) jMapLocationToDict:(JMapLocation *) jMapLocation{
    NSDictionary *dict = @{
        @"mapId":ObjectOrNull(jMapLocation.mapId),
        @"waypointIds": ObjectOrNull(jMapLocation.waypointIds),
    };
    return dict;
}

//+ (NSDictionary *) jMapUriCollectionToDict:(JMapUriCollection *) jMapUriCollection{
//    NSDictionary *dict = @{
//        @"mapId":ObjectOrNull(jMapLocation.mapId),
//        @"waypointIds": ObjectOrNull(jMapLocation.waypointIds),
//    };
//    return dict;
//}






+ (NSDictionary *)jMapPathPerFloorToDict:(JMapPathPerFloor *) jMapPathPerFloor jMapController:(JMapController *) controller{

    NSMutableArray *points = [NSMutableArray array];
    
    

    for (NSUInteger i = 0; i < [jMapPathPerFloor.mapPoints count]; i++) {

        
        JMapPoint * jMapPoint = jMapPathPerFloor.mapPoints[i];
        JMapASNode *jMapASNode = jMapPathPerFloor.points[i];
        JMapWaypoint *jMapWaypoint = [controller.currentMap.waypoints getById:[jMapASNode.nodeId intValue]];
        
        NSDictionary * jMapWaypointDict = [JibestreamConverter jMapWaypointToDict:jMapWaypoint];
        // NSDictionary * jMapPointDict = [JibestreamConverter jMapPointToDict:jMapPoint];

        CGPoint convertPoint = CGPointMake(jMapPoint.x, jMapPoint.y);
        convertPoint = [JMapUtils convertPoint:convertPoint fromProjection:@"jmap:local" toProjection:@"EPSG:4326" inVenue:controller.activeVenue];
        

        NSDictionary *pointDict = @{
            @"id": ObjectOrNull(jMapWaypoint.id),
            @"mapId": ObjectOrNull(jMapWaypoint.mapId),
            // @"coordinates":ObjectOrNull(jMapWaypointDict[@"coordinates"]),
            @"associations": ObjectOrNull(jMapWaypointDict[@"associations"]),
            // @"xyz": ObjectOrNull(jMapPointDict),
            @"x":ObjectOrNull(@(jMapPoint.x)),
            @"y":ObjectOrNull(@(jMapPoint.y)),
            @"z":ObjectOrNull(@(jMapPoint.z)),
            @"latitude": ObjectOrNull(@(convertPoint.y)),
            @"longitude": ObjectOrNull(@(convertPoint.x))
        };
        
        [points addObject:pointDict];
    }
    
    
    NSDictionary *dict = @{
        @"mapId": ObjectOrNull(jMapPathPerFloor.mapId),
        @"mover": ObjectOrNull([JibestreamConverter jMapPathTypeToDict:jMapPathPerFloor.mover]),
        @"points": points,
        @"cost": @(jMapPathPerFloor.cost),
        @"pixelDistance": jMapPathPerFloor.pixelDistance,
        @"mmDistance": jMapPathPerFloor.mmDistance,
    };
  return dict;
}

+ (NSDictionary *)jMapPathTypeToDict:(JMapPathType *) jMapPathType {
    NSDictionary *dict = @{
        @"moverId": ObjectOrNull(jMapPathType.id),
        @"speed": ObjectOrNull(jMapPathType.speed),
        @"accessibility": ObjectOrNull(@(jMapPathType.accessibility.floatValue)),
        @"typeName": ObjectOrNull(jMapPathType.name),
        @"svg": ObjectOrNull(nil),
    };
  return dict;
}

//+ (NSDictionary *)jMapPointToDict:(JMapPoint *) jMapPoint {
//    NSDictionary *dict = @{
//        @"x": ObjectOrNull(@(jMapPoint.x)),
//        @"y": ObjectOrNull(@(jMapPoint.y)),
//        @"z": ObjectOrNull(@(jMapPoint.z)),
//    };
//  return dict;
//}

//JIBESTREAM_GEOFENCE = {
//  id: number;
//  name: string;
//  coordinates: number[][];
//};

+ (NSMutableDictionary *) jMapGeofenceArrayToDict:(NSArray<JMapGeofenceInstance *> * )geofences {

    NSMutableString *geofenceStr = [NSMutableString new];
        
    NSMutableArray * geofenceList = [NSMutableArray array];
    for (JMapGeofenceInstance * instance in geofences) {
        NSMutableDictionary * geofenceDict = [NSMutableDictionary dictionary];
        geofenceDict[@"name"] = instance.instanceName;
        geofenceDict[@"id"] = instance.instanceId;
        geofenceDict[@"coordinates"] = instance.coordinates.firstObject;
        [geofenceList addObject:geofenceDict];
    }
    
    NSMutableDictionary * geofenceEvent = [NSMutableDictionary dictionary];
    geofenceEvent[@"entered"] = @(NO);
    geofenceEvent[@"geofences"] = geofenceList;
    
    return geofenceEvent;
}

+ (NSDictionary *)jMapPointToDict:(JMapPoint *) jMapPoint {
    NSDictionary *dict = @{
        @"x": ObjectOrNull(@(jMapPoint.x)),
        @"y": ObjectOrNull(@(jMapPoint.y)),
        @"z": ObjectOrNull(@(jMapPoint.z)),
    };
  return dict;
}

//+ (NSDictionary *)jMapASNodeToDict:(JMapASNode *) jMapASNode {
//    NSDictionary *dict = @{
//        @"id": ObjectOrNull(jMapASNode.nodeId),
//        @"mapId": ObjectOrNull(jMapASNode.mapId),
//        @"coordinates": ObjectOrNull(jMapPoint.z),
//    };
//  return dict;
//}

+ (UIColor *)colorFromHexString:(NSString *)hexString {
    NSString *cleanedString = [hexString stringByReplacingOccurrencesOfString:@"#" withString:@""];
    NSScanner *scanner = [NSScanner scannerWithString:cleanedString];
    unsigned int hexValue = 0;
    
    if (![scanner scanHexInt:&hexValue]) {
        return [UIColor blackColor]; // Return black color for invalid input
    }
    
    CGFloat red = ((hexValue & 0xFF0000) >> 16) / 255.0;
    CGFloat green = ((hexValue & 0x00FF00) >> 8) / 255.0;
    CGFloat blue = (hexValue & 0x0000FF) / 255.0;
    
    return [UIColor colorWithRed:red green:green blue:blue alpha:1.0];
}


+ (UIImage *) imageFromDict:(NSDictionary *)imageDict {
    NSString * iconURI = [imageDict objectForKey:@"iconUrl"];
    if(iconURI.length >0){
        NSData * imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:iconURI]];
        UIImage * newImage = [UIImage imageWithData: imageData];
        return newImage;
    }
    return NULL;
}

@end
