//
//  MBIMResolveHandleOperation.m
//  kordophoned
//
//  Created by James Magahern on 10/1/24.
//  Copyright © 2024 James Magahern. All rights reserved.
//

#import "MBIMResolveHandleOperation.h"

#import "IMCore_ClassDump.h"
#import "IMMessageItem+Encoded.h"

/*
 # Response:
 Dictionary {
    "resolvedHandle": <Encoded IMHandle>
    "status": valid | invalid | unknown,
    "existingChat": chatGUID | null
 }
 
 # IMHandle:
 Dictionary {
    "id"   : resolvedID
    "name" : fullName | null
 }
 */

@interface NSNumber (IDSStatusUtility)
- (NSString *)_idsStatusDescription;
@end

@implementation NSNumber (IDSStatusUtility)
- (NSString *)_idsStatusDescription
{
    switch ([self unsignedIntegerValue]) {
        case 1: return @"valid";
        case 2: return @"invalid";
        default:
            return @"unknown";
    }
}
@end

@interface IMHandle (Encoded)
- (NSDictionary *)mbim_dictionaryRepresentation;
@end

@implementation IMHandle (Encoded)
- (NSDictionary *)mbim_dictionaryRepresentation
{
    return @{
        @"id"   : [self ID],
        @"name" : [self name] ?: [NSNull null],
    };
}
@end

@implementation MBIMResolveHandleOperation

+ (void)load { [super load]; }

+ (NSString *)endpointName
{
    return @"resolveHandle";
}

- (void)main
{
    NSString *specifiedIdentifier = [[self valueForQueryItemWithName:@"id"] _stripFZIDPrefix];
    if (!specifiedIdentifier) {
        MBIMLogError(@"No handle ID provided.");
        HTTPErrorResponse *response = [[HTTPErrorResponse alloc] initWithErrorCode:500];
        self.serverCompletionBlock(response);
        
        return;
    }
    
    if (IMStringIsPhoneNumber(specifiedIdentifier)) {
        // Phone numbers will require a country code guess here.
        // Passing nil, I presume, will make some kind of guess for the country code (useNetworkCountryCode).
        specifiedIdentifier = IMCopyIDForPhoneNumber(specifiedIdentifier, nil, YES);
    }
    
    NSString *canonicalAddress = [specifiedIdentifier _bestGuessURI];
 
    IMAccount *iMessageAccount = [[IMAccountController sharedInstance] bestAccountForService:[IMServiceImpl iMessageService]];
    IMHandle *loginHandle = [iMessageAccount loginIMHandle];
    
    NSString *lastAddressedHandle = [[[loginHandle ID] _stripFZIDPrefix] _bestGuessURI];
    IMChatCalculateServiceForSendingNewComposeMaybeForce(@[ canonicalAddress ], lastAddressedHandle, nil, NO, IMStringIsEmail(canonicalAddress), NO, NO, NO, [iMessageAccount service], ^(BOOL allAddressesiMessageCapable, NSDictionary * _Nullable perRecipientAvailability, BOOL checkedServer, IMChatServiceForSendingAvailabilityError error)
    {
        NSError *encodingError = nil;
        NSObject<HTTPResponse> *response = nil;
        
        do {
            // Assume we have returned just one key here.
            NSString *resolvedHandleID = [[perRecipientAvailability allKeys] firstObject];
            if (!resolvedHandleID) {
                MBIMLogError(@"Unexpected missing handle id");
                response = [[HTTPErrorResponse alloc] initWithErrorCode:500];
                break;
            }
            
            IMHandle *resolvedHandle = [iMessageAccount imHandleWithID:resolvedHandleID];
            if (!resolvedHandle) {
                MBIMLogError(@"Couldn't resolve handle");
                response = [[HTTPErrorResponse alloc] initWithErrorCode:500];
                break;
            }
            
            NSString *handleStatus = [[perRecipientAvailability objectForKey:resolvedHandleID] _idsStatusDescription];
            
            IMChat *existingChat = [[IMChatRegistry sharedInstance] existingChatForIMHandle:resolvedHandle];
            
            NSDictionary *responseDict = @{
                @"resolvedHandle" : [resolvedHandle mbim_dictionaryRepresentation],
                @"status" : handleStatus,
                @"existingChat" : [existingChat guid] ?: [NSNull null],
            };
            
            NSData *data = [NSJSONSerialization dataWithJSONObject:responseDict options:0 error:&encodingError];
            if (encodingError) {
                response = [[HTTPErrorResponse alloc] initWithErrorCode:500];
            } else {
                response = [[MBIMDataResponse alloc] initWithData:data contentType:@"application/json"];
            }
        } while (0);
        
        self.serverCompletionBlock(response);
    });
}

@end
