#import "SystemAudioLoopbackViewController.h"
#import <GMESDK/TMGEngine.h>
#import "DispatchCenter.h"

@interface SystemAudioLoopbackViewController () <ITMGDelegate>

@property (nonatomic, strong) NSTextField *playerPathTextField;
@property (nonatomic, strong) NSButton *startButton;
@property (nonatomic, strong) NSButton *stopButton;
@property (nonatomic, strong) NSSlider *volumeSlider;
@property (nonatomic, strong) NSTextView *logTextView;
@property (nonatomic, strong) NSScrollView *logScrollView;

@end

@implementation SystemAudioLoopbackViewController

- (void)loadView {
    self.view = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 450, 400)];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"System Audio Loopback Test";
    [self setupUI];
    
    [[DispatchCenter getInstance] addDelegate:self];
}

- (void)dealloc {
    [[DispatchCenter getInstance] removeDelegate:self];
}

- (void)setupUI {
    // Player Path Input
    NSTextField *pathLabel = [[NSTextField alloc] initWithFrame:NSMakeRect(20, 360, 100, 20)];
    pathLabel.stringValue = @"Player Path:";
    pathLabel.editable = NO;
    pathLabel.bordered = NO;
    pathLabel.backgroundColor = [NSColor clearColor];
    [self.view addSubview:pathLabel];

    self.playerPathTextField = [[NSTextField alloc] initWithFrame:NSMakeRect(120, 360, 310, 24)];
    self.playerPathTextField.placeholderString = @"Path / Process ID (Optional)";
    [self.view addSubview:self.playerPathTextField];

    // Buttons
    self.startButton = [[NSButton alloc] initWithFrame:NSMakeRect(20, 320, 100, 30)];
    self.startButton.title = @"Start";
    self.startButton.bezelStyle = NSBezelStyleRounded;
    self.startButton.target = self;
    self.startButton.action = @selector(onStartButtonClick);
    [self.view addSubview:self.startButton];

    self.stopButton = [[NSButton alloc] initWithFrame:NSMakeRect(140, 320, 100, 30)];
    self.stopButton.title = @"Stop";
    self.stopButton.bezelStyle = NSBezelStyleRounded;
    self.stopButton.target = self;
    self.stopButton.action = @selector(onStopButtonClick);
    [self.view addSubview:self.stopButton];

    // Volume Slider
    NSTextField *volumeLabel = [[NSTextField alloc] initWithFrame:NSMakeRect(20, 280, 60, 20)];
    volumeLabel.stringValue = @"Volume:";
    volumeLabel.editable = NO;
    volumeLabel.bordered = NO;
    volumeLabel.backgroundColor = [NSColor clearColor];
    [self.view addSubview:volumeLabel];

    self.volumeSlider = [[NSSlider alloc] initWithFrame:NSMakeRect(90, 280, 340, 24)];
    self.volumeSlider.minValue = 0;
    self.volumeSlider.maxValue = 200;
    self.volumeSlider.intValue = 100;
    self.volumeSlider.target = self;
    self.volumeSlider.action = @selector(onVolumeSliderChange:);
    [self.view addSubview:self.volumeSlider];

    // Log View
    self.logScrollView = [[NSScrollView alloc] initWithFrame:NSMakeRect(20, 20, 410, 240)];
    self.logScrollView.hasVerticalScroller = YES;
    self.logScrollView.borderType = NSBezelBorder;
    
    self.logTextView = [[NSTextView alloc] initWithFrame:self.logScrollView.contentView.bounds];
    self.logTextView.minSize = NSMakeSize(0.0, self.logScrollView.contentSize.height);
    self.logTextView.maxSize = NSMakeSize(FLT_MAX, FLT_MAX);
    self.logTextView.verticallyResizable = YES;
    self.logTextView.horizontallyResizable = NO;
    self.logTextView.autoresizingMask = NSViewWidthSizable;
    self.logTextView.editable = NO;
    
    self.logScrollView.documentView = self.logTextView;
    [self.view addSubview:self.logScrollView];
}

- (void)appendLog:(NSString *)log {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        [formatter setDateFormat:@"HH:mm:ss"];
        NSString *timeStr = [formatter stringFromDate:[NSDate date]];
        NSString *logStr = [NSString stringWithFormat:@"[%@] %@\n", timeStr, log];
        
        [self.logTextView.textStorage appendAttributedString:[[NSAttributedString alloc] initWithString:logStr]];
        [self.logTextView scrollRangeToVisible:NSMakeRange(self.logTextView.string.length, 0)];
    });
}

#pragma mark - Actions

- (void)onStartButtonClick {
    NSString *path = self.playerPathTextField.stringValue;
    if (path.length == 0) {
        path = nil;
    }
    
    [self appendLog:[NSString stringWithFormat:@"Calling StartSystemAudioLoopback with path: %@", path ? path : @"nil"]];
    
    QAVResult result = [[[ITMGContext GetInstance] GetAudioEffectCtrl] StartSystemAudioLoopback:path];
    if (result != QAV_OK) {
        [self appendLog:[NSString stringWithFormat:@"StartSystemAudioLoopback failed with error code: %ld", (long)result]];
    } else {
        [self appendLog:@"StartSystemAudioLoopback called successfully"];
    }
}

- (void)onStopButtonClick {
    [self appendLog:@"Calling StopSystemAudioLoopback"];
    QAVResult result = [[[ITMGContext GetInstance] GetAudioEffectCtrl] StopSystemAudioLoopback];
    if (result != QAV_OK) {
        [self appendLog:[NSString stringWithFormat:@"StopSystemAudioLoopback failed with error code: %ld", (long)result]];
    } else {
        [self appendLog:@"StopSystemAudioLoopback called successfully"];
    }
}

- (void)onVolumeSliderChange:(NSSlider *)slider {
    int volume = slider.intValue;
    [[[ITMGContext GetInstance] GetAudioEffectCtrl] SetSystemAudioLoopbackVolume:volume];
}

#pragma mark - ITMGDelegate

- (void)OnEvent:(ITMG_MAIN_EVENT_TYPE)type data:(NSDictionary *)data {
    if (type == ITMG_MAIN_EVENT_TYPE_SYSTEM_LOOPBACK_START_FAILED) {
        [self appendLog:[NSString stringWithFormat:@"Received ITMG_MAIN_EVENT_TYPE_SYSTEM_LOOPBACK_START_FAILED (1014). Data: %@", data]];
    }
    
    if (data) {
        for (NSString *key in data) {
            id value = data[key];
            if ([value isKindOfClass:[NSNumber class]]) {
                int intValue = [value intValue];
                if (intValue == AV_ERR_SYSTEM_LOOPBACK_START_FAILED) {
                    [self appendLog:[NSString stringWithFormat:@"Error: AV_ERR_SYSTEM_LOOPBACK_START_FAILED (4058) in event %ld", (long)type]];
                    [self appendLog:@"Solution: 1. Check Windows version (>= 10.0.19042). 2. Check parameters. 3. Check speaker device."];
                } else if (intValue == AV_ERR_SYSTEM_LOOPBACK_THIRD_PARTY_APP_EXIT) {
                    [self appendLog:[NSString stringWithFormat:@"Error: AV_ERR_SYSTEM_LOOPBACK_THIRD_PARTY_APP_EXIT (4059) in event %ld", (long)type]];
                    [self appendLog:@"Solution: Third-party app exited unexpectedly. Please restart the app and retry with new process ID."];
                }
            }
        }
    }
}

@end
