//
//  HPAPI.m
//  HotPocket
//
//  Created by Tomek Wójcik on 23/09/2025.
//

#import "HPAPI.h"

#import "HPCredentialsHelper.h"
#import "HPRPCClient.h"

@implementation HPAPI (HPAPIPrivate)

#pragma mark - Private interface

-(void)updateRPCClientCredentials {
    HPCredentials *credentials = [[HPCredentialsHelper sharedHelper] getCredentials];
    self.rpcClient.baseURL = credentials.rpcURL;
    self.rpcClient.accessToken = credentials.accessToken;
}

@end

@implementation HPAPI

#pragma mark - Initialization

-(id)init {
    if (self = [super init]) {
        self.rpcClient = [[HPRPCClient alloc] initWithBaseURL:nil accessToken:nil];

        [self updateRPCClientCredentials];
        
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(onCredentialsChanged:)
                                                     name:@"HPCredentialsChanged"
                                                   object:nil];
    }
    
    return self;
}

-(id)initWithRPCClientDelegate:(id<HPRPCClientDelegate>)rpcClientDelegate {
    if (self = [self init]) {
        self.rpcClient.delegate = rpcClientDelegate;
    }
    
    return self;
}

-(void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

#pragma mark - Public interface

+(NSDictionary *)getAccessTokenMeta {
    NSBundle *mainBundle = [NSBundle mainBundle];
    
    return @{
        @"version": [mainBundle.infoDictionary valueForKey:@"CFBundleShortVersionString"],
        @"platform": [mainBundle.infoDictionary valueForKey:@"HPAPIAccessTokenPlatform"],
    };
}

-(NSString *)checkAuth {
    if (self.rpcClient.hasCredentials == NO) {
        return nil;
    }
    
    NSString *callId = [[NSUUID UUID] UUIDString];

    BOOL callResult = [self.rpcClient call:callId
                                    method:@"accounts.auth.check_access_token"
                                    params:@[self.rpcClient.accessToken, [HPAPI getAccessTokenMeta]]
                                 endopoint:@"/accounts/rpc/"];
    if (callResult == NO) {
        return nil;
    }
    
    return callId;
}

-(void)checkAuth:(HPAPICheckAuthCompletionHandler)completionHandler {
    if (self.rpcClient.hasCredentials == NO) {
        completionHandler(NO, nil, nil);
    } else {
        NSString *callId = [[NSUUID UUID] UUIDString];
        BOOL callResult = [self.rpcClient call:callId
                                        method:@"accounts.auth.check_access_token"
                                        params:@[self.rpcClient.accessToken, [HPAPI getAccessTokenMeta]]
                                     endopoint:@"/accounts/rpc/" completionHandler:^(NSString *finalCallId, HPRPCCallResult *result) {
            BOOL authValid = YES;
            if (result.error != nil) {
                authValid = NO;
            } else if ([(NSNumber *)result.result boolValue] == NO) {
                authValid = NO;
            }
            
            completionHandler(authValid, result.error, finalCallId);
        }];
    }
}

-(NSString *)save:(NSURL *)url {
    if (self.rpcClient.hasCredentials == NO) {
        return nil;
    }
    
    if (url == nil) {
        return nil;
    }
    
    NSString *callId = [[NSUUID UUID] UUIDString];
    BOOL callResult = [self.rpcClient call:callId method:@"saves.create" params:@[[url absoluteString]]];
    if (callResult == NO) {
        return nil;
    }
    
    return callId;
}

-(BOOL)save:(NSURL *)url completionHandler:(HPRPCClientCompletionHandler)completionHandler {
    if (self.rpcClient.hasCredentials == NO) {
        return NO;
    }
    
    if (url == nil) {
        return NO;
    }
    
    NSString *callId = [[NSUUID UUID] UUIDString];
    return [self.rpcClient call:callId
                         method:@"saves.create"
                         params:@[[url absoluteString]]
              completionHandler:completionHandler];
}

#pragma mark - Notification handlers

-(void)onCredentialsChanged:(NSNotification *)notification {
    [self updateRPCClientCredentials];
}
@end
