//
//  PathSuggester.m
//  Preferences
//
//  Created by Christopher Snowhill on 6/21/22.
//

#import "PathSuggester.h"

#import "PlaylistController.h"

#import "SandboxBroker.h"

@interface AudioContainer : NSObject {
}

+ (NSArray *)urlsForContainerURL:(NSURL *)url;
+ (NSArray *)dependencyUrlsForContainerURL:(NSURL *)url;

@end

// Sync, only declare items we need
@interface PlaylistEntry
@property(nonatomic) NSURL *_Nullable url;
@end

@interface PathItem : NSObject
@property(nonatomic, strong) NSString *path;
@property(nonatomic) BOOL enabled;

- (IBAction)clickEnable:(id)sender;
@end

@implementation PathItem
@synthesize path;
@synthesize enabled;

- (IBAction)clickEnable:(id)sender {
	self.enabled = !self.enabled;
}
@end

@interface PathSuggester ()

@end

@implementation PathSuggester

- (id)init {
	return [super initWithWindowNibName:@"PathSuggester"];
}

- (IBAction)beginSuggestion:(id)sender {
	[self showWindow:self];

	[pathsList removeObjects:[pathsList arrangedObjects]];

	NSPersistentContainer *pc = [NSClassFromString(@"PlaylistController") sharedPersistentContainer];

	NSPredicate *hasUrlPredicate = [NSPredicate predicateWithFormat:@"urlString != nil && urlString != %@", @""];
	NSPredicate *deletedPredicate = [NSPredicate predicateWithFormat:@"deLeted == NO || deLeted == nil"];

	NSCompoundPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[deletedPredicate, hasUrlPredicate]];

	NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"PlaylistEntry"];
	request.predicate = predicate;

	NSError *error = nil;
	NSArray *results = [pc.viewContext executeFetchRequest:request error:&error];

	if(!results || [results count] < 1) return;

	id sandboxBrokerClass = NSClassFromString(@"SandboxBroker");

	NSMutableArray *items = [[NSMutableArray alloc] init];
	NSMutableArray *itemPaths = [[NSMutableArray alloc] init];

	NSArray *originalArray = [results valueForKey:@"url"];
	NSMutableArray *array = [originalArray mutableCopy];

	for(NSURL *url in originalArray) {
		if(![url isFileURL]) {
			[array removeObject:url];
		}
	}

	originalArray = [array copy];

	id audioContainerClass = NSClassFromString(@"AudioContainer");

	for(NSURL *url in originalArray) {
		NSArray *containedUrls = [audioContainerClass dependencyUrlsForContainerURL:url];
		if(containedUrls && [containedUrls count] > 0) {
			[array addObjectsFromArray:containedUrls];
		}
	}

	// Add other system paths to this setting
	NSString *fileTreePath = [[NSUserDefaults standardUserDefaults] stringForKey:@"fileTreeRootURL"];
	if(fileTreePath && [fileTreePath length]) {
		// Append false name to dodge the directory/fragment trimmer
		[array addObject:[NSURL URLWithString:[fileTreePath stringByAppendingPathComponent:@"moo.mp3"]]];
	}

	NSString *soundFontPath = [[NSUserDefaults standardUserDefaults] stringForKey:@"soundFontPath"];
	if(soundFontPath && [soundFontPath length]) {
		[array addObject:[NSURL fileURLWithPath:soundFontPath]];
	}

	for(NSURL *fileUrl in array) {
		NSURL *url = [sandboxBrokerClass urlWithoutFragment:fileUrl];
		if([sandboxPathBehaviorController matchesPath:url])
			continue;

		NSArray *pathComponents = [url pathComponents];
		for(size_t i = 2; i < [pathComponents count]; ++i) {
			NSURL *subUrl = [NSURL fileURLWithPathComponents:[pathComponents subarrayWithRange:NSMakeRange(0, i)]];
			if(![itemPaths containsObject:subUrl]) {
				[itemPaths addObject:subUrl];
				PathItem *item = [[PathItem alloc] init];
				item.path = [subUrl path];
				item.enabled = NO;
				[items addObject:item];
			}
		}
	}

	NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"path.length" ascending:YES];
	[pathsList setSortDescriptors:@[sortDescriptor]];

	[items sortUsingDescriptors:@[sortDescriptor]];

	[pathsList addObjects:items];

	[pathsList setSelectedObjects:@[]];
}

- (void)windowDidLoad {
	[super windowDidLoad];
}

- (NSView *_Nullable)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *_Nullable)tableColumn row:(NSInteger)row {
	NSString *cellIdentifier = @"";
	NSTextAlignment cellTextAlignment = NSTextAlignmentLeft;

	PathItem *pi = [[pathsList arrangedObjects] objectAtIndex:row];

	float fontSize = [[[NSUserDefaultsController sharedUserDefaultsController] defaults] floatForKey:@"fontSize"];

	NSButton *cellButton = nil;
	NSString *cellText = @"";

	if(pi) {
		cellIdentifier = [tableColumn identifier];
		if([cellIdentifier isEqualToString:@"enabled"]) {
			cellButton = [NSButton checkboxWithTitle:@"" target:pi action:@selector(clickEnable:)];
			cellButton.state = pi.enabled ? NSControlStateValueOn : NSControlStateValueOff;
		} else if([cellIdentifier isEqualToString:@"path"]) {
			cellText = pi.path;
		}
	}

	NSView *view = [tableView makeViewWithIdentifier:cellIdentifier owner:nil];
	if(view && [view isKindOfClass:[NSTableCellView class]]) {
		NSTableCellView *cellView = (NSTableCellView *)view;

		if(cellView.textField) {
			cellView.textField.allowsDefaultTighteningForTruncation = YES;

			NSFont *font = [NSFont monospacedDigitSystemFontOfSize:fontSize weight:NSFontWeightRegular];

			cellView.textField.font = font;
			cellView.textField.stringValue = cellText;
			cellView.textField.alignment = cellTextAlignment;

			if(cellView.textField.intrinsicContentSize.width > cellView.textField.frame.size.width - 4) {
				cellView.textField.toolTip = cellText;
			}
		}
		if(cellButton) {
			[cellView setSubviews:@[cellButton]];
		}
	}

	return view;
}

- (IBAction)applyPaths:(id)sender {
	for(PathItem *pi in [pathsList arrangedObjects]) {
		if(pi.enabled) {
			NSOpenPanel *panel = [NSOpenPanel openPanel];
			[panel setAllowsMultipleSelection:NO];
			[panel setCanChooseDirectories:YES];
			[panel setCanChooseFiles:NO];
			[panel setFloatingPanel:YES];
			[panel setDirectoryURL:[NSURL fileURLWithPath:pi.path]];
			[panel setTitle:@"Open to add path"];
			NSInteger result = [panel runModal];
			if(result == NSModalResponseOK) {
				[sandboxPathBehaviorController addUrl:[panel URL]];
			}
		}
	}
	[[self window] orderOut:self];
}

@end
