//
//  LEANMenuViewController.m
//  GoNativeIOS
//
//  Created by Weiyin He on 2/7/14.
//  Copyright (c) 2014 GoNative.io LLC. All rights reserved.
//

#import "LEANMenuViewController.h"
#import "LEANNavigationController.h"
#import "LEANWebViewController.h"
#import "LEANRootViewController.h"
#import "LEANLoginManager.h"
#import "LEANUrlInspector.h"
#import "LEANTabManager.h"
#import "LEANProfilePicker.h"
#import "LEANUtilities.h"
#import "GonativeIO-Swift.h"
@import MedianIcons;

@interface LEANMenuViewController ()

@property id menuItems;
@property NSMutableArray *groupExpanded;

@property LEANWebViewController *wvc;
@property LEANProfilePicker *profilePicker;

@property UIImage *collapsedIndicator;
@property UIImage *expandedIndicator;
@property UIButton *settingsButton;

@property UIView *headerView;
@property UISegmentedControl *segmentedControl;
@property NSArray *segmentedControlItems;

@property BOOL groupsHaveIcons;
@property BOOL childrenHaveIcons;
@property NSString *lastUpdatedStatus;

@end

@implementation LEANMenuViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    self.tableView.backgroundColor = [UIColor clearColor];
    self.tableView.opaque = NO;
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    self.tableView.sectionHeaderHeight = 0;
    self.tableView.sectionFooterHeight = 0;
    
    NSArray *arr = [[NSBundle mainBundle] loadNibNamed:@"SidebarHeaderView" owner:nil options:nil];

    UIView *headerView = arr[0];
    self.headerView = headerView;
    headerView.autoresizingMask = UIViewAutoresizingNone;
    UIButton *headerButton = (UIButton*)[headerView viewWithTag:1];
    [headerButton addTarget:self action:@selector(picturePressed:) forControlEvents:UIControlEventTouchUpInside];
    if ([GoNativeAppConfig sharedAppConfig].sidebarIcon) {
        [headerButton setImage:[GoNativeAppConfig sharedAppConfig].sidebarIcon forState:UIControlStateNormal];
    }
    else if ([GoNativeAppConfig sharedAppConfig].appIcon) {
        [headerButton setImage:[GoNativeAppConfig sharedAppConfig].appIcon forState:UIControlStateNormal];
    }
        
    self.segmentedControl = (UISegmentedControl*)[headerView viewWithTag:3];
    [self setupSegmentedControl];
    
    self.tableView.tableHeaderView = headerView;
    self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
    
    // actually update the menus
    [self updateMenuWithStatus:@"default"];

    if ([GoNativeAppConfig sharedAppConfig].loginDetectionURL) {
        // subscribe to login notifications
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveLoginNotification:) name:kLEANLoginManagerNotificationName object:nil];
        [[LEANLoginManager sharedManager] checkIfNotAlreadyChecking];
    }

    // pre-load images. Color them too.
    self.collapsedIndicator = [[UIImage imageNamed:@"chevronDown"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    self.expandedIndicator = [[UIImage imageNamed:@"chevronUp"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveNotification:) name:kLEANAppConfigNotificationProcessedMenu object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveNotification:) name:kLEANAppConfigNotificationProcessedSegmented object:nil];

    // profile picker
    self.profilePicker = [[LEANProfilePicker alloc] init];
}

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

- (void)didReceiveNotification:(NSNotification*)notification
{
    // dynamic menu update
    if ([[notification name] isEqualToString:kLEANAppConfigNotificationProcessedMenu]) {
        [self updateMenuWithStatus:self.lastUpdatedStatus];
    }
    else if ([[notification name] isEqualToString:kLEANAppConfigNotificationProcessedSegmented]) {
        [self updateSegmentedControl];
    }
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    
    // webviewcontroller reference
    LEANNavigationController* nav = (LEANNavigationController*)self.frostedViewController.contentViewController;
    self.wvc = (LEANWebViewController*)nav.viewControllers[0];
}

- (void)didReceiveLoginNotification:(NSNotification*)notification
{
    LEANLoginManager *loginManager = [notification object];
    [self updateMenuWithStatus:loginManager.loginStatus];
}

- (void)updateMenuWithStatus:(NSString *)status
{
    if (!status) status = @"default";
    
    self.lastUpdatedStatus = status;
    
    self.menuItems = [GoNativeAppConfig sharedAppConfig].menus[status];
    
    // see if any menu items have icons. Used for layout indentation.
    self.groupsHaveIcons = NO;
    self.childrenHaveIcons = NO;
    for (id item in self.menuItems) {
        if (item[@"icon"] && item[@"icon"] != [NSNull null]) {
            self.groupsHaveIcons = YES;
        }
        
        if ([item[@"isGrouping"] boolValue]) {
            for (id sublink in item[@"subLinks"]) {
                if (sublink[@"icon"] && sublink[@"icon"] != [NSNull null]) {
                    self.childrenHaveIcons = YES;
                    break;
                }
            }
        }
    }
    
    // groups are initially collapsed
    self.groupExpanded = [[NSMutableArray alloc] initWithCapacity:[self.menuItems count]];
    for (int i = 0; i < [self.menuItems count]; i++) {
        self.groupExpanded[i] = [NSNumber numberWithBool:NO];
    }
    
    [self.tableView reloadData];
}

- (void)logOut
{
    [self.wvc logout];
    [self updateMenuWithStatus:@"default"];
}

- (void)showSettings:(BOOL)showSettings
{
    [self.settingsButton setUserInteractionEnabled:showSettings];
    [UIView animateWithDuration:0.3 animations:^(void){
        self.settingsButton.alpha = showSettings ? 1.0 : 0.0;
    }];
}

- (IBAction)picturePressed:(id)sender {
    [self.wvc loadUrl:[GoNativeAppConfig sharedAppConfig].initialURL];
    [self.frostedViewController hideMenuViewController];
}

- (void)parseProfilePickerJSON:(NSString *)json
{
    [self.profilePicker parseJson:json];
    [self showSettings:self.profilePicker.hasProfiles];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [self.menuItems count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if ([self.groupExpanded[section] boolValue]) {
        return 1 + [self.menuItems[section][@"subLinks"] count];
    }
    else
        return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellNib;
    UITableViewCell *cell;
    UIImageView *imageView;
    UILabel *label;
    if (indexPath.row == 0) {
        if (self.groupsHaveIcons) cellNib = @"MenuGroupIcon";
        else cellNib = @"MenuGroupNoIcon";
    } else {
        if (self.groupsHaveIcons || self.childrenHaveIcons) cellNib = @"MenuChildIcon";
        else cellNib = @"MenuChildNoIcon";
    }
    
    cell = [tableView dequeueReusableCellWithIdentifier:cellNib];
    if (nil == cell) {
        cell = [[NSBundle mainBundle] loadNibNamed:cellNib owner:nil options:nil][0];
        cell.backgroundColor = [UIColor clearColor]; // shouldn't need this, but background is white on ipad if I don't do this.
        UIView* separatorLineView = [[UIView alloc] initWithFrame:CGRectMake(15, 0, 240, 1)];
        separatorLineView.backgroundColor = [UIColor colorWithHue:0 saturation:0 brightness:.7 alpha:.5];
        separatorLineView.tag = 99;
        [cell addSubview:separatorLineView];
    }
    
    label = (UILabel*)[cell.contentView viewWithTag:1];
    imageView = (UIImageView*)[cell.contentView viewWithTag:2];
    
    // get data
    id menuItem;
    if (indexPath.row == 0) {
        menuItem = self.menuItems[indexPath.section];
    } else {
        menuItem = self.menuItems[indexPath.section][@"subLinks"][indexPath.row - 1];
    }
    
    // text
    label.text = [menuItem[@"label"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    if ([GoNativeAppConfig sharedAppConfig].iosSidebarFont) {
        label.font = [GoNativeAppConfig sharedAppConfig].iosSidebarFont;
    }
    
    // expand/collapse indicator
    if ([menuItem[@"isGrouping"] boolValue]) {
        if ([self.groupExpanded[indexPath.section] boolValue]) {
            cell.accessoryView = [[UIImageView alloc] initWithImage:self.expandedIndicator];
        } else {
            cell.accessoryView = [[UIImageView alloc] initWithImage:self.collapsedIndicator];
        }
    } else
        cell.accessoryView = nil;
    
    // icon
    UILabel *icon;
    NSString *iconName = menuItem[@"icon"];
    if (iconName && [iconName isKindOfClass:[NSString class]]) {
        if ([iconName hasPrefix:@"gonative-"]) {
            UIImage *image = [UIImage imageNamed:iconName];
            imageView.image = image;
        } else {
            // add fontawesome/material/custom icon to imageView
            icon = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, imageView.bounds.size.width, imageView.bounds.size.height)];
            icon.textAlignment = NSTextAlignmentCenter;
            icon.attributedText = [[NSAttributedString alloc] initWithIconName:iconName color:[UIColor colorNamed:@"sidebarTextColor"] size:[UIFont systemFontSize]];
            [imageView addSubview:icon];
        }
    } else {
        imageView.image = nil;
        [[imageView subviews]
         makeObjectsPerformSelector:@selector(removeFromSuperview)];
    }
                           
    // configure background color
    self.view.backgroundColor = [UIColor colorNamed:@"sidebarBackgroundColor"];
    
    // configure text color
    UIColor *sidebarTextColor = [UIColor colorNamed:@"sidebarTextColor"];
    label.textColor = sidebarTextColor;
    cell.tintColor = sidebarTextColor;
    
    // hide separator line from first cell
    if (indexPath.section == 0 && indexPath.row == 0) {
        [cell viewWithTag:99].hidden = YES;
    } else {
        [cell viewWithTag:99].hidden = NO;
    }
    
    return cell;
}

#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    
    NSString *url = nil;
    NSString *javascript = nil;
    BOOL isLogout;
    
    // if is first row, then check if it is grouped.
    if (indexPath.row == 0) {
        if ([self.menuItems[indexPath.section][@"isGrouping"] boolValue]) {
            self.groupExpanded[indexPath.section] = [NSNumber numberWithBool:![self.groupExpanded[indexPath.section] boolValue]];
            [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];
        } else {
            NSDictionary *item = self.menuItems[indexPath.section];
            url = item[@"url"];
            javascript = item[@"javascript"];
            isLogout = [item[@"isLogout"] boolValue];
        }
    } else {
        // regular child
        NSDictionary *item = self.menuItems[indexPath.section][@"subLinks"][indexPath.row - 1];
        url = item[@"url"];
        javascript = item[@"javascript"];
        isLogout = [item[@"isLogout"] boolValue];
    }
    
    if (url != nil) {
        // check for GONATIVE_USERID string.
        url = [url stringByReplacingOccurrencesOfString:@"GONATIVE_USERID" withString:[LEANUrlInspector sharedInspector].userId];
        
        if ([url hasPrefix:@"javascript:"]) {
            NSString *js = [url substringFromIndex: [@"javascript:" length]];
            [self.wvc runJavascript:js];
        } else {
            // try selecting the corresponding tab (if exists);
            if (self.wvc.tabManager) {
                [self.wvc.tabManager selectTabWithUrl:url javascript:javascript];
            }
            
            if ([javascript length] > 0) {
                [self.wvc loadUrl:[LEANUtilities urlWithString:url] andJavascript:javascript];
            } else {
                
                if(UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad){
                    [self.wvc setSharePopOverRect:[tableView rectForRowAtIndexPath:indexPath]]; // save touch location
                }
                [self.wvc loadUrlAfterFilter:[LEANUtilities urlWithString:url]];
            }
        }
        [self.frostedViewController hideMenuViewController];
        
        if (isLogout) {
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [self.wvc logout];
            });
        }
    }
}

#pragma mark - Segmented control
-(void)setupSegmentedControl
{
    [self.segmentedControl addTarget:self action:@selector(segmentedControlChanged:) forControlEvents:UIControlEventValueChanged];
    [self updateSegmentedControl];
    
}

-(void)updateSegmentedControl
{
    self.segmentedControlItems = [GoNativeAppConfig sharedAppConfig].segmentedControlItems;
    BOOL showSegmentedControl = self.segmentedControlItems && [self.segmentedControlItems count] > 0;
    if (showSegmentedControl) {
        if (self.segmentedControl.hidden) {
            // expand header view
            self.segmentedControl.hidden = NO;
            CGRect oldFrame = self.headerView.frame;
            oldFrame.size.height += 50;
            self.headerView.frame = oldFrame;
            [self.tableView setTableHeaderView:self.headerView];
        }
        
        [self.segmentedControl removeAllSegments];
        for (NSInteger i = 0; i < [self.segmentedControlItems count]; i++) {
            NSDictionary *item = self.segmentedControlItems[i];
            
            NSString *label = nil;
            BOOL selected = NO;
            
            if ([item isKindOfClass:[NSDictionary class]]) {
                label = item[@"label"];
                selected = [item[@"selected"] boolValue];
            }
            
            if (![label isKindOfClass:[NSString class]]) {
                label = @"Invalid";
            }
            
            [self.segmentedControl insertSegmentWithTitle:label atIndex:i animated:NO];
            if (selected) {
                self.segmentedControl.selectedSegmentIndex = i;
            }
        }
        
    }
    else {
        if (!self.segmentedControl.hidden) {
            self.segmentedControl.hidden = YES;
            
            // shrink the header view
            CGRect oldFrame = self.headerView.frame;
            oldFrame.size.height -= 50;
            self.headerView.frame = oldFrame;
            [self.tableView setTableHeaderView:self.headerView];
        }
    }
}

-(IBAction)segmentedControlChanged:(id)sender
{
    UISegmentedControl *control = sender;
    NSInteger selectedIndex = control.selectedSegmentIndex;
    if (selectedIndex < 0 || selectedIndex >= [self.segmentedControlItems count]) return;
    
    NSDictionary *item = self.segmentedControlItems[selectedIndex];
    if (![item isKindOfClass:[NSDictionary class]]) return;

    NSString *url = item[@"url"];
    NSString *javascript = item[@"javascript"];
    
    if ([url isKindOfClass:[NSString class]]) {
        if ([url hasPrefix:@"javascript:"]) {
            NSString *js = [url substringFromIndex: [@"javascript:" length]];
            [self.wvc runJavascript:js];
        } else {
            if ([javascript isKindOfClass:[NSString class]] && [javascript length] > 0) {
                [self.wvc loadUrl:[NSURL URLWithString:url] andJavascript:javascript];
            } else {
                [self.wvc loadUrlAfterFilter:[NSURL URLWithString:url]];
            }
        }
    }
    
    [self.frostedViewController hideMenuViewController];
}
@end


