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

#import "MapViewController.h"
#import <MapKit/MapKit.h>
#import<CoreLocation/CoreLocation.h>
#import <CoreMotion/CoreMotion.h>
#import "NSDate+helper.h"
#import "Utilities.h"

@interface MapViewController ()<CLLocationManagerDelegate, MKMapViewDelegate>
{
    CLGeocoder *geocoder;
    CLPlacemark *placemark;
    CLLocation *previousLocation;
}
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@property (weak, nonatomic) IBOutlet UILabel *lblTime;
@property (weak, nonatomic) IBOutlet UISlider *slider;

@property (nonatomic, weak) IBOutlet UILabel *lblValueStep;
@property (nonatomic, weak) IBOutlet UILabel *lblUnitStep;
@property (weak, nonatomic) IBOutlet UIView *viewOther;

@property (strong, nonatomic) CLLocationManager *locationManager;

@property (nonatomic, strong) CMPedometer *pedometer;
@property (nonatomic, strong) CMMotionActivityManager *motionActivityManager;
@property (nonatomic, strong) NSOperationQueue *operationQueue;
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic) int countTime;
@property (nonatomic, assign) BOOL isRequesting;
@end

@implementation MapViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
//    self.title = NSLocalizedString(@"lifelog.tapbar.map", nil);
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.topLayoutGuide attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.mapView attribute:NSLayoutAttributeTop multiplier:1 constant:0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.bottomLayoutGuide attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.mapView attribute:NSLayoutAttributeBottom multiplier:1 constant:44]];
    geocoder = [[CLGeocoder alloc] init];
    [self setupLocation];
    [self setupMapView];
    previousLocation = nil;
    
    if ([CMPedometer isStepCountingAvailable]) {
        _pedometer = [[CMPedometer alloc] init];
    }
    if ([CMMotionActivityManager isActivityAvailable]) {
        _motionActivityManager = [[CMMotionActivityManager alloc] init];
    }
    self.isRequesting = NO;
    _countTime = 0;
    self.lblUnitStep.text = NSLocalizedString(@"lifelog.home.unit.step", nil);
}

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

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    _timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(countStep) userInfo:nil repeats:YES];
    [_timer fire];
}

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

#pragma mark - CLLocationManagerDelegate
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
    
    CLLocation *newLocation = [locations lastObject];
    if (previousLocation == nil) {
        [self addAnnotationsOnMap:newLocation];
    }
    else {
        CLLocationCoordinate2D area[2];
        area[0] = previousLocation.coordinate;
        area[1] = newLocation.coordinate;
        MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:area count:2];
        [_mapView addOverlay:polyLine];
    }
    
    previousLocation = newLocation;
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"Cannot find the location.");
}

#pragma mark - MKMapViewDelegate
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id <MKOverlay>)overlay
{
    if ([overlay isKindOfClass:[MKPolyline class]]) {
        MKPolylineRenderer *pr = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
        pr.strokeColor = [UIColor redColor];
        pr.lineWidth = 5;
        return pr;
    }
    return nil;
}

#pragma mark - Functions Private

- (void)addAnnotationsOnMap:(CLLocation *)locationToPoint {
    MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
    annotation.coordinate = locationToPoint.coordinate;
    [geocoder reverseGeocodeLocation:locationToPoint completionHandler:^(NSArray *placemarks, NSError *error) {
        if (error == nil && [placemarks count] >0) {
            placemark = [placemarks firstObject];
            NSDictionary *addressDict = placemark.addressDictionary;
            annotation.title = [NSString stringWithFormat:@"%@", addressDict[@"Name"]];
            [_mapView addAnnotation:annotation];
        }
    }];
}

- (void)setupLocation {
    _locationManager = [[CLLocationManager alloc] init];
    _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    _locationManager.delegate = self;
    CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
    if (status == kCLAuthorizationStatusNotDetermined || status == kCLAuthorizationStatusDenied || status == kCLAuthorizationStatusAuthorizedWhenInUse) {
        [_locationManager requestWhenInUseAuthorization];
        [_locationManager requestAlwaysAuthorization];
    }
    [_locationManager startUpdatingLocation];
    [_locationManager startUpdatingHeading];
}

- (void)setupMapView {
    _mapView.delegate = self;
    _mapView.showsUserLocation = YES;
    _mapView.mapType = MKMapTypeStandard;
    _mapView.userTrackingMode = MKUserTrackingModeFollowWithHeading;
}

#pragma mark - Functions Private
- (void)countStep
{
    _countTime++;
    _lblTime.text = [self convertTime:_countTime];
    _slider.value = _countTime;
    if (self.isRequesting == YES) {
        return;
    }
    if ([CMMotionActivityManager isActivityAvailable]) {
        self.isRequesting = YES;
        NSDate *endDate = [NSDate date];
        NSDate *startDate = [endDate beginningAtMidnightOfDay];
        MapViewController __weak *weakSelf = self;
        dispatch_queue_t myQueue = dispatch_queue_create("mobileworld.jp.lifelog", NULL);
        dispatch_async(myQueue, ^{
            if (weakSelf == nil) {
                return ;
            }
            [weakSelf.pedometer queryPedometerDataFromDate:startDate toDate:endDate withHandler:^(CMPedometerData * _Nullable pedometerData, NSError * _Nullable error) {
                NSInteger numberStep = [pedometerData.numberOfSteps integerValue];
                dispatch_async(dispatch_get_main_queue(), ^{
                    [weakSelf updateStepUI:numberStep];
                });
            }];
        });
    }
}

- (NSString *)convertTime:(int)time
{
    NSString *result = @"";
    int hour = time/3600;
    int minute = time/60;
    int second = time % 60;
    result = [NSString stringWithFormat:@"%02d:%02d:%02d", hour, minute, second];
    return result;
}

- (void)updateStepUI:(NSInteger)numberStep
{
    // NSLog(@"Number of step: %ld", numberStep);
    self.isRequesting = NO;
    self.lblValueStep.text = [Utilities addCommaFromNumber:numberStep];
}

@end
