//
//  HomeViewController.m
//  LifeLog
//
//  Created by Nguyen Van Phong on 7/25/17.
//  Copyright © 2017 PhongNV. All rights reserved.
//

#import "HomeViewController.h"
#import "NSDate+helper.h"
#import <CoreMotion/CoreMotion.h>
#import "CMMotionActivityExtra.h"
#import "TodayViewController.h"
#import "Utilities.h"
#import <MBProgressHUD/MBProgressHUD.h>
#import "ServerAPI.h"

static NSInteger maxRequest = 20;
static NSInteger numberTotal = 10000;

@interface HomeViewController ()
{
    MBProgressHUD *progressHud;
    NSInteger targetStep;
}
@property (nonatomic, weak) IBOutlet UILabel *lblTitle;
@property (nonatomic, weak) IBOutlet UIImageView *avatar;
@property (nonatomic, weak) IBOutlet UILabel *lblDateCurrent;
@property (nonatomic, weak) IBOutlet UILabel *lblValueStep;
@property (nonatomic, weak) IBOutlet UILabel *lblUnitStep;
@property (nonatomic, weak) IBOutlet UILabel *lblValueStepOther;
@property (nonatomic, weak) IBOutlet UILabel *lblPercent;
@property (nonatomic, weak) IBOutlet UILabel *lblNotice;
@property (weak, nonatomic) IBOutlet UISegmentedControl *segmentHome;
@property (weak, nonatomic) IBOutlet UITextView *tvNotice;

@property (nonatomic, strong) CMPedometer *pedometer;
@property (nonatomic, strong) CMMotionActivityManager *motionActivityManager;
@property (nonatomic, strong) NSOperationQueue *operationQueue;
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, assign) NSInteger bike;
@property (nonatomic, assign) NSInteger walking;
@property (nonatomic, assign) NSInteger running;
@property (nonatomic, strong) NSDate *dateCurrent;

@property (nonatomic, assign) int totalRequest;
@property (nonatomic, assign) int countComplete;
@property (nonatomic, assign) int currentIndex;

@end

@implementation HomeViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.lblTitle.text = NSLocalizedString(@"lifelog.home.title", nil);
  
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.topLayoutGuide attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.lblTitle attribute:NSLayoutAttributeTop multiplier:1 constant:0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.bottomLayoutGuide attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.segmentHome attribute:NSLayoutAttributeBottom multiplier:1 constant:20]];
  
    self.avatar.backgroundColor = [UIColor whiteColor];
    self.avatar.layer.borderWidth = 2.0f;
    self.avatar.layer.borderColor = [[UIColor whiteColor] CGColor];
    self.avatar.layer.cornerRadius = self.avatar.frame.size.width/2.0f;
    self.avatar.layer.masksToBounds = YES;
    NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:kUser];
    User *user = (User *)[NSKeyedUnarchiver unarchiveObjectWithData:data];
    if (user != nil) {
        NSString *linkImage = [NSString stringWithFormat:@"%@%@", kServerAddress, user.profile_image];
        NSURL *urlImage = [NSURL URLWithString:linkImage];
        NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
        sessionConfig.timeoutIntervalForRequest = 30.0;
        sessionConfig.timeoutIntervalForResource = 60.0;
        sessionConfig.HTTPMaximumConnectionsPerHost = 20;
        sessionConfig.allowsCellularAccess = YES;
        HomeViewController __weak *weakSelf = self;
        NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig];
        NSURLSessionDataTask *downloadPhotoTask = [session
                                                   dataTaskWithURL:urlImage completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                       if (weakSelf == nil)
                                                       {
                                                           return;
                                                       }
                                                       if (error == nil) {
                                                           UIImage *image = [[UIImage alloc] initWithData:data];
                                                           [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                                                               weakSelf.avatar.image = image;
                                                           }];
                                                       }
                                                   }];
        [downloadPhotoTask resume];
    }
    
    self.lblNotice.text = NSLocalizedString(@"lifelog.home.notice", nil);
    
    _dateCurrent = [NSDate date];
    self.lblDateCurrent.text = [NSString stringWithFormat:@"%ld%@%ld%@%ld%@", (long)[_dateCurrent getYear], NSLocalizedString(@"lifelog.common.year", nil), (long)[_dateCurrent getMonth], NSLocalizedString(@"lifelog.common.month", nil), (long)[_dateCurrent getDay], NSLocalizedString(@"lifelog.common.day", nil)];
    
    self.lblUnitStep.text = NSLocalizedString(@"lifelog.home.unit.step", nil);
  
    if ([CMPedometer isStepCountingAvailable]) {
        _pedometer = [[CMPedometer alloc] init];
    }
    if ([CMMotionActivityManager isActivityAvailable]) {
        _motionActivityManager = [[CMMotionActivityManager alloc] init];
    }
    _operationQueue = [[NSOperationQueue alloc] init];
    _bike = 0;
    _walking = 0;
    _running = 0;
    _segmentHome.selectedSegmentIndex = 1;
    _totalRequest = 0;
    _countComplete = 0;
    
    progressHud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    progressHud.mode = MBProgressHUDModeIndeterminate;
    progressHud.detailsLabel.text = NSLocalizedString(@"lifelog.home.progressHud.title", nil);
    // [self saveDataStep7LastDay];
    targetStep = numberTotal;
    [self requestNotice];
}

- (void)requestNotice
{
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd"];
    NSString *dateString = [dateFormatter stringFromDate:_dateCurrent];
    HomeViewController __weak *weakSelf = self;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //Do background work
        [[ServerAPI server] getNoticeByDate:dateString CompletionHandler:^(NSArray *arrResults, NSError *error) {
            if(weakSelf == nil) {
                return ;
            }
            if (error == nil) {
                // NSLog(@"List Notices: %@", arrResults);
                dispatch_async(dispatch_get_main_queue(), ^{
                    NSString *stringNotice = @"";
                    for (NSString *noticeInfor in arrResults) {
                        NSString *noticeString = [NSString stringWithFormat:@"%@\n", noticeInfor];
                        stringNotice = [stringNotice stringByAppendingString:noticeString];
                    }
                    weakSelf.tvNotice.text = stringNotice;
                });
            }
            else {
                dispatch_async(dispatch_get_main_queue(), ^{
                    weakSelf.tvNotice.text = @"";
                    /*
                    NSString *message = [error.userInfo objectForKey:@"message"];
                    [Utilities showErrorMessage:message withViewController:weakSelf];
                    */
                });
            }
        }];
    });
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    NSDate *dateNow = [NSDate date];
    [self saveStepForDay:dateNow];
}

- (void)requestTopByDate:(NSDate *)date {
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd"];
    NSString *dateString = [dateFormatter stringFromDate:date];
    [progressHud showAnimated:YES];
    [progressHud setHidden:NO];
    HomeViewController __weak *weakSelf = self;
    int mode = 1;
    switch (_segmentHome.selectedSegmentIndex) {
        case 0:
            mode = 3;
            break;
            
        case 1:
            mode = 1;
            break;
            
        case 2:
            mode = 2;
            break;
            
        default:
            break;
    }
    [[ServerAPI server] requestTopWithMode:mode andDate:dateString CompletionHandler:^(TopObject *topObject, NSError *error) {
        if(weakSelf == nil) {
            return ;
        }
        if (error == nil) {
            NSLog(@"TopObject: %@", topObject);
            dispatch_async(dispatch_get_main_queue(), ^{
                [weakSelf updateStepUI:topObject.targetInfor];
            });
        }
        else {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSString *message = [error.userInfo objectForKey:@"message"];
                [Utilities showErrorMessage:message withViewController:weakSelf];
            });
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            [progressHud setHidden:YES];
        });
    }];
    /*
    [[ServerAPI server] requestHomeWithMode:mode andDate:dateString CompletionHandler:^(HomeObject *homeObject, NSError *error) {
        if(weakSelf == nil) {
            return ;
        }
        if (error == nil) {
            NSLog(@"List Notices: %@", homeObject.listNotice);
            for (NoticeInfor *noticeInfor in homeObject.listNotice) {
                NSLog(@"noticeInfor: %@", noticeInfor.notice_content);
            }
            dispatch_async(dispatch_get_main_queue(), ^{
                [weakSelf updateNoticeUI:homeObject];
            });
        }
        else {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSString *message = [error.userInfo objectForKey:@"message"];
                [Utilities showErrorMessage:message withViewController:weakSelf];
            });
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            [progressHud setHidden:YES];
        });
    }];
    */
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - IBAction
- (IBAction)menuButtonTouchUpInside:(id)sender
{
    
}

- (IBAction)todayButtonTouchUpInside:(id)sender
{
    TodayViewController *todayVC = [[TodayViewController alloc] initWithNibName:@"TodayViewController" bundle:nil];
    todayVC.targetStep = targetStep;
    [self.navigationController pushViewController:todayVC animated:YES];
}

- (IBAction)leftButtonTouchUpInside:(id)sender
{
    self.dateCurrent = [self.dateCurrent dateByAddingTimeInterval:-(24*60*60)];
    self.lblDateCurrent.text = [NSString stringWithFormat:@"%ld%@%ld%@%ld%@", (long)[_dateCurrent getYear], NSLocalizedString(@"lifelog.common.year", nil), (long)[_dateCurrent getMonth], NSLocalizedString(@"lifelog.common.month", nil), (long)[_dateCurrent getDay], NSLocalizedString(@"lifelog.common.day", nil)];
    [self resetStepUI];
    [self saveStepForDay:self.dateCurrent];
    [self requestNotice];
}

- (IBAction)rightButtonTouchUpInside:(id)sender
{
    self.dateCurrent = [self.dateCurrent dateByAddingTimeInterval:24*60*60];
    self.lblDateCurrent.text = [NSString stringWithFormat:@"%ld%@%ld%@%ld%@", (long)[_dateCurrent getYear], NSLocalizedString(@"lifelog.common.year", nil), (long)[_dateCurrent getMonth], NSLocalizedString(@"lifelog.common.month", nil), (long)[_dateCurrent getDay], NSLocalizedString(@"lifelog.common.day", nil)];
    [self resetStepUI];
    //[self saveStepForDay:self.dateCurrent];
    [self requestTopByDate:self.dateCurrent];
    [self requestNotice];
}

- (IBAction)segmentValueChange:(id)sender {
    [self resetStepUI];
    [self requestTopByDate:self.dateCurrent];
}

#pragma mark - Functions Private
- (void)saveStepForDay:(NSDate *)date
{
    if ([CMMotionActivityManager isActivityAvailable] == YES) {
        [progressHud showAnimated:YES];
        [progressHud setHidden:NO];
        self.bike = 0;
        self.walking = 0;
        self.running = 0;
        NSDate *startDate = [date beginningAtMidnightOfDay];
        NSDate *endDate = [startDate dateByAddingTimeInterval:(24*60*60 - 1)];
    
        HomeViewController __weak *weakSelf = self;
        dispatch_queue_t myQueue = dispatch_queue_create("mobileworld.jp.lifelog.forDay", NULL);
        dispatch_async(myQueue, ^{
            if (weakSelf == nil) {
                return ;
            }
            
            [weakSelf.motionActivityManager queryActivityStartingFromDate:startDate toDate:endDate toQueue:_operationQueue withHandler:^(NSArray<CMMotionActivity *> * _Nullable activities, NSError * _Nullable error) {
                if (error || activities.count <= 0) {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [weakSelf updateStepUI];
                    });
                    return ;
                }
                // set EndDate
                NSMutableArray *arrayActivities = [[NSMutableArray alloc] init];
                for (int i = 0; i < activities.count; i++) {
                    CMMotionActivity *activity = [activities objectAtIndex:i];
                    CMMotionActivityExtra *activityExtra = [[CMMotionActivityExtra alloc] init];
                    activityExtra.activity = activity;
                    if (i == activities.count - 1) {
                        activityExtra.endDate = endDate;
                    }
                    else {
                        CMMotionActivity *activityNext = [activities objectAtIndex:i+1];
                        // activityExtra.endDate = [activityNext.startDate dateByAddingTimeInterval:-1];
                        activityExtra.endDate = activityNext.startDate;
                    }
                    [arrayActivities addObject:activityExtra];
                }
                // PhongNV
                weakSelf.currentIndex = 0;
                [weakSelf save20objectOfActivityExtras:arrayActivities];
            }];
        });
    }
    else {
        [self updateStepUI];
    }
}

- (void)complete20Request:(NSArray *)activities {
    if (self.totalRequest == self.countComplete) {
        self.totalRequest = 0;
        self.countComplete = 0;
        self.currentIndex++;
        [self save20objectOfActivityExtras:activities];
    }
}
- (void)save20objectOfActivityExtras:(NSArray *)activities
{
    int result = floor(activities.count / maxRequest);
    if (activities.count <= 0 || self.currentIndex > result) {
        self.totalRequest = 0;
        self.countComplete = 0;
        self.currentIndex = 0;
        dispatch_async(dispatch_get_main_queue(), ^{
            [self updateStepUI];
        });
        return;
    }
    
    HomeViewController __weak *weakSelf = self;
    for (NSInteger index = self.currentIndex*maxRequest; index < self.currentIndex*maxRequest + maxRequest; index++) {
        if ((self.currentIndex*maxRequest + maxRequest) >= activities.count) {
            self.totalRequest = (int)(activities.count - self.currentIndex*maxRequest);
            if (self.totalRequest <= 0) {
                [weakSelf complete20Request:activities];
            }
        }
        else {
            self.totalRequest = (int)maxRequest;
        }
        if (index < activities.count) {
            CMMotionActivityExtra *activityExtra = [activities objectAtIndex:index];
            [self.pedometer queryPedometerDataFromDate:activityExtra.activity.startDate toDate:activityExtra.endDate withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) {
                if (weakSelf == nil) {
                    return ;
                }
                NSInteger numberStep = [pedometerData.numberOfSteps integerValue];
                int mode = 1;
                if (activityExtra.activity.cycling) {
                    mode = 3;
                }
                else if (activityExtra.activity.walking) {
                    mode = 1;
                }
                else if (activityExtra.activity.running) {
                    mode = 2;
                }
                else {
                    // unknown
                }
                // save step to server
                if (numberStep > 0) {
                    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
                    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
                    NSString *dateBegin = [dateFormatter stringFromDate:activityExtra.activity.startDate];
                    NSString *dateEnd = [dateFormatter stringFromDate:activityExtra.endDate];
                    // NSLog(@"dateBegin: %@ | dateEnd: %@ | numberStep: %li", dateBegin, dateEnd, numberStep);
                    [[ServerAPI server] requestCreateLog:mode withStep:(int)numberStep startDate:dateBegin endDate:dateEnd CompletionHandler:^(NSError *error) {
                        if (error) {
                            NSLog(@"Error: %@", error);
                        }
                        weakSelf.countComplete++;
                        [weakSelf complete20Request:activities];
                    }];
                }
                else {
                    weakSelf.countComplete++;
                    [weakSelf complete20Request:activities];
                }
            }];
        }
    }
}

- (void)updateStepUI
{
    [self requestTopByDate:self.dateCurrent];
}

- (void)saveDataStep7LastDay
{
    NSDate *dateNow = [NSDate date];
    for (int index = 0; index < 7; index++) {
        dateNow = [dateNow dateByAddingTimeInterval:-(24*60*60)];
        [self saveStepByDate:dateNow];
    }
}

- (void)saveStepByDate:(NSDate *)date
{
    if ([CMMotionActivityManager isActivityAvailable]) {
        NSDate *startDate = [date beginningAtMidnightOfDay];
        NSDate *endDate = [startDate dateByAddingTimeInterval:(24*60*60 - 1)];
        
        HomeViewController __weak *weakSelf = self;
        dispatch_queue_t myQueue = dispatch_queue_create("mobileworld.jp.lifelog.7lastday", NULL);
        dispatch_async(myQueue, ^{
            if (weakSelf == nil) {
                return ;
            }
            
            [weakSelf.motionActivityManager queryActivityStartingFromDate:startDate toDate:endDate toQueue:_operationQueue withHandler:^(NSArray<CMMotionActivity *> * _Nullable activities, NSError * _Nullable error) {
                if (error || activities.count <= 0) {
                    return ;
                }
                // set EndDate
                NSMutableArray *arrayActivities = [[NSMutableArray alloc] init];
                for (int i = 0; i < activities.count; i++) {
                    CMMotionActivity *activity = [activities objectAtIndex:i];
                    CMMotionActivityExtra *activityExtra = [[CMMotionActivityExtra alloc] init];
                    activityExtra.activity = activity;
                    if (i == activities.count - 1) {
                        activityExtra.endDate = endDate;
                    }
                    else {
                        CMMotionActivity *activityNext = [activities objectAtIndex:i+1];
                        activityExtra.endDate = [activityNext.startDate dateByAddingTimeInterval:-1];
                    }
                    [arrayActivities addObject:activityExtra];
                }
                
                for (CMMotionActivityExtra *activityExtra in arrayActivities) {
                    [weakSelf.pedometer queryPedometerDataFromDate:activityExtra.activity.startDate toDate:activityExtra.endDate withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) {
                        NSInteger numberStep = [pedometerData.numberOfSteps integerValue];
                        int mode = 1;
                        if (activityExtra.activity.cycling) {
                            mode = 3;
                        }
                        else if (activityExtra.activity.walking) {
                            mode = 1;
                        }
                        else if (activityExtra.activity.running) {
                            mode = 2;
                        }
                        else {
                            // unknown
                        }
                        
                        // save step to server
                        if (numberStep > 0) {
                            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
                            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
                            NSString *dateBegin = [dateFormatter stringFromDate:activityExtra.activity.startDate];
                            NSString *dateEnd = [dateFormatter stringFromDate:activityExtra.endDate];
                            [[ServerAPI server] requestCreateLog:mode withStep:(int)numberStep startDate:dateBegin endDate:dateEnd CompletionHandler:^(NSError *error) {
                                if (error) {
                                    NSLog(@"Error: %@", error);
                                }
                            }];
                        }
                    }];
                }
            }];
        });
    }
}

- (void)updateStepUI:(TargetInfor *)targetInfor
{
    NSString *stringTargetStep = [targetInfor.target_step stringByReplacingOccurrencesOfString:@"," withString:@""];
    targetStep = [stringTargetStep integerValue];
    self.lblValueStep.text = targetInfor.num_step;
    self.lblValueStepOther.text = [NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"lifelog.today.remaining.other", nil), targetInfor.remaining_step];
    self.lblPercent.text = [NSString stringWithFormat:@"%@ %i%@", NSLocalizedString(@"lifelog.today.text.percent", nil), [targetInfor.complete_percent intValue], NSLocalizedString(@"lifelog.today.percent", nil)];
}

- (void)updateNoticeUI:(HomeObject *)homeObject
{
    NSString *stringNotice = @"";
    for (NoticeInfor *notice in homeObject.listNotice) {
        NSString *noticeString = [NSString stringWithFormat:@"%@\n", notice.notice_content];
        stringNotice = [stringNotice stringByAppendingString:noticeString];
    }
    _tvNotice.text = stringNotice;
}

- (void)resetStepUI
{
    self.lblValueStep.text = @"";
    self.lblValueStepOther.text = @"";
    self.lblPercent.text = @"";
}

@end
