//
//  AuthorizationProgressViewController.m
//  HotPocket (macOS)
//
//  Created by Tomek Wójcik on 20/09/2025.
//

#import "AuthorizationProgressViewController.h"

#import "AppDelegate.h"
#import "AuthorizationViewController.h"
#import "HPAuthFlow.h"
#import "HPCredentialsHelper.h"
#import "MainViewController.h"
#import "NSBundle+HotPocketExtensions.h"
#import "ReplaceAnimator.h"

@interface AuthorizationProgressViewController (AuthorizationProgressViewControllerPrivate)

#pragma mark - Private interface

-(void)presentAuthorizationError;

@end

@implementation AuthorizationProgressViewController

#pragma mark - View lifecycle

-(instancetype)initWithCoder:(NSCoder *)coder {
    if (self = [super initWithCoder:coder]) {
        self.authorizationURL = nil;
        self.webAuthenticationSession = nil;
        self.userCancelledSession = NO;
    }
    
    return self;
}

-(void)viewDidLoad {
    [super viewDidLoad];
    self.progressLabelTitle = NSLocalizedString(@"Continue to sign in in your browser...", @"Continue to sign in in your browser...");
}

-(void)viewWillAppear {
    AppDelegate *appDelegate = [[NSApplication sharedApplication] delegate];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                            selector:@selector(onAuthFlowDidFinish:)
                                                 name:@"AuthFlowDidFinish"
                                               object:appDelegate.authFlow];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(onAuthFlowDidReceiveAuthParams:)
                                                 name:@"AuthFlowDidReceiveAuthParams"
                                               object:appDelegate.authFlow];
    
    [self.progressIndicator startAnimation:self];
}

-(void)viewDidAppear {
    [super viewDidAppear];
    AppDelegate *appDelegate = [[NSApplication sharedApplication] delegate];
    
    ASWebAuthenticationSessionCompletionHandler completionHandler = ^(NSURL *url, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (error != nil) {
#ifdef DEBUG
                NSLog(@"[AuthorizationViewController.session completionHandler] error=`%@`", error);
#endif
                if (error.code == ASWebAuthenticationSessionErrorCodeCanceledLogin) {
                    self.userCancelledSession = YES;
                }
                [self presentAuthorizationError];
            } else {
                HPAuthParams *receivedAuthParams = [appDelegate.authFlow handlePostAuthenticateURL:url];
                if (receivedAuthParams != nil) {
                    [[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
                    [appDelegate.authFlow handleAuthParams:receivedAuthParams];
                } else {
                    [self presentAuthorizationError];
                }
            }
            
            self.webAuthenticationSession = nil;
        });
    };
    
    ASWebAuthenticationSessionCallback *callback = [ASWebAuthenticationSessionCallback callbackWithCustomScheme:[NSBundle postAuthenticateURLScheme]];
    self.webAuthenticationSession = [[ASWebAuthenticationSession alloc] initWithURL:self.authorizationURL
                                                                           callback:callback
                                                                  completionHandler:completionHandler];
    self.webAuthenticationSession.presentationContextProvider = self;
#ifdef DEBUG
    self.webAuthenticationSession.prefersEphemeralWebBrowserSession = YES;
#endif
    
    if (self.webAuthenticationSession.canStart == NO) {
        [self presentAuthorizationError];
        return;
    }
    
    [self.webAuthenticationSession start];
}

-(void)viewDidDisappear {
    [super viewDidDisappear];
    self.webAuthenticationSession = nil;

    [self.progressIndicator stopAnimation:self];
    
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

#pragma mark - Actions

-(IBAction)doCancel:(id)sender {
    [self.webAuthenticationSession cancel];
}

#pragma mark - Private interface

-(void)presentAuthorizationError {
    if (self.userCancelledSession == NO) {
        NSAlert *alert = [[NSAlert alloc] init];
        alert.alertStyle = NSAlertStyleCritical;
        alert.messageText = NSLocalizedString(@"Oops!", @"Oops!");
        alert.informativeText = NSLocalizedString(@"HotPocket couldn't complete this operation.", @"HotPocket couldn't complete this operation.");
        [alert beginSheetModalForWindow:self.view.window completionHandler:^(NSModalResponse response) {
            AuthorizationViewController *authorizationViewController = [self.storyboard instantiateControllerWithIdentifier:@"AuthorizationViewController"];
            [self presentViewController:authorizationViewController animator:[[ReplaceAnimator alloc] init]];
        }];
    } else {
        AuthorizationViewController *authorizationViewController = [self.storyboard instantiateControllerWithIdentifier:@"AuthorizationViewController"];
        [self presentViewController:authorizationViewController animator:[[ReplaceAnimator alloc] init]];
    }
}

#pragma mark - Notification handlers

-(void)onAuthFlowDidFinish:(NSNotification *)notification {
    dispatch_async(dispatch_get_main_queue(), ^{
        HPCredentials *credentials = [[HPCredentialsHelper sharedHelper] getCredentials];
        
        [[NSApplication sharedApplication] requestUserAttention:NSInformationalRequest];
        [[NSApplication sharedApplication] activateIgnoringOtherApps:YES];
        
        if (credentials.usable == NO) {
            [self presentAuthorizationError];
        } else {
            MainViewController *mainViewController = [self.storyboard instantiateControllerWithIdentifier:@"MainViewController"];
            [self presentViewController:mainViewController animator:[[ReplaceAnimator alloc] init]];
        }
    });
}

-(void)onAuthFlowDidReceiveAuthParams:(NSNotification *)notification {
    self.progressLabelTitle = NSLocalizedString(@"Processing authorization...", @"Processing authorization...");
}

# pragma mark - ASWebAuthenticationPresentationContextProviding implementation

-(ASPresentationAnchor)presentationAnchorForWebAuthenticationSession:(ASWebAuthenticationSession *)session {
    return self.view.window;
}

@end
