//
//  GizPickRegionViewController.m
//  GizwitsGeofence
//
//  Created by Gizwits on 2018/8/22.
//  Copyright © 2018年 Gizwits. All rights reserved.
//

#import "GizPickRegionViewController.h"

#import "GizPinView.h"

#import "GizCoordinateTransform.h"

#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>


@interface GizPickRegionViewController () <CLLocationManagerDelegate, MKMapViewDelegate>

@property (nonatomic, strong) IBOutlet MKMapView *mapView;

@property (nonatomic, strong) IBOutlet UIView *locateBackgroundView;
@property (nonatomic, strong) IBOutlet UIButton *locateButton;

@property (nonatomic, strong) UIBarButtonItem *backBarButtonItem;
@property (nonatomic, strong) UIBarButtonItem *rightBarButtonItem;

@property (nonatomic, assign) BOOL hasInitializedMapView;

@property (nonatomic, strong) CLLocationManager *locationManager;

@property (nonatomic, strong) GizPinView *pinView;

@property (nonatomic, strong) NSDictionary *regionDict;

// 默认区域半径
@property (nonatomic, assign) CGFloat radius;
@property (nonatomic, assign) BOOL hidesRadius;

// 操作结果回调
@property (nonatomic, copy) GizPickRegionCompletionHandler completionHandler;

@end

@implementation GizPickRegionViewController

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    
    if (self) {
        _themeColor = [UIColor orangeColor];
        _rightButtonTitle = @"确定";
        self.title = @"选取位置";
    }
    
    return self;
}

+ (instancetype)pickRegionViewController {
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"GizGeofence" bundle:nil];
    
    GizPickRegionViewController *pickRegionViewController = [storyboard instantiateViewControllerWithIdentifier:@"GizPickRegionViewController"];
    
    return pickRegionViewController;
}

+ (instancetype)pickRegionWithRegionDict:(NSDictionary *)regionDict completionHandler:(GizPickRegionCompletionHandler)completionHandler {
    
    GizPickRegionViewController *pickRegionViewController = [GizPickRegionViewController pickRegionViewController];
    
    if (regionDict) {
        pickRegionViewController.regionDict = regionDict;
    }
    
    pickRegionViewController.completionHandler = completionHandler;
    
    return pickRegionViewController;
}

+ (instancetype)pickAddressWithRegionDict:(NSDictionary *)addressDict completionHandler:(GizPickRegionCompletionHandler)completionHandler {
    
    GizPickRegionViewController *pickRegionViewController = [GizPickRegionViewController pickRegionViewController];
    
    if (addressDict) {
        pickRegionViewController.regionDict = addressDict;
    }
    
    pickRegionViewController.hidesRadius = YES;
    
    pickRegionViewController.completionHandler = completionHandler;
    
    return pickRegionViewController;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    // 返回
    self.backBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"GizRegionResource.bundle/navigation_btn_back_normal"] style:UIBarButtonItemStylePlain target:self action:@selector(actionBack:)];
    self.navigationItem.leftBarButtonItem = self.backBarButtonItem;
    
    // 确定
    self.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:self.rightButtonTitle style:UIBarButtonItemStylePlain target:self action:@selector(actionRightBarButtonClicked:)];
    self.navigationItem.rightBarButtonItem = self.rightBarButtonItem;
    
    // 地图
    [self initMapView];
    
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    
    CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
    
    switch (status) {
        case kCLAuthorizationStatusNotDetermined: {
            [self.locationManager requestAlwaysAuthorization];
        }
            break;
            
        case kCLAuthorizationStatusDenied:
            break;
            
        case kCLAuthorizationStatusAuthorizedWhenInUse:
            self.mapView.showsUserLocation = YES;
            break;
            
        case kCLAuthorizationStatusAuthorizedAlways:
            self.mapView.showsUserLocation = YES;
            break;
            
        default:
            break;
    }
}

- (void)initMapView {
    
    self.locateBackgroundView.layer.cornerRadius = 10;
    self.locateBackgroundView.layer.shadowColor = [UIColor lightGrayColor].CGColor;
    self.locateBackgroundView.layer.shadowOpacity = 0.8;
    self.locateBackgroundView.layer.shadowOffset = CGSizeMake(0, 1);
    
    [self.locateButton setImage:[UIImage imageNamed:@"GizRegionResource.bundle/location_icon"] forState:UIControlStateNormal];
    
    // 选中的区域
    if (self.hidesRadius) {
        self.pinView = [GizPinView pinView];
    } else {
        self.pinView = [GizRegionPinView pinView];
    }
    
    self.pinView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:self.pinView];
    
    NSLayoutConstraint *regionCenterX = [NSLayoutConstraint constraintWithItem:self.pinView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.mapView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0];
    NSLayoutConstraint *regionCenterY = [NSLayoutConstraint constraintWithItem:self.pinView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.mapView attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0];
    [self.view addConstraints:@[regionCenterX, regionCenterY]];
    
    NSLayoutConstraint *regionViewWidth = [NSLayoutConstraint constraintWithItem:self.pinView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:CGRectGetWidth(self.pinView.frame)];
    NSLayoutConstraint *regionViewHeight = [NSLayoutConstraint constraintWithItem:self.pinView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:CGRectGetWidth(self.pinView.frame)];
    [self.pinView addConstraints:@[regionViewWidth, regionViewHeight]];
}

// 将 mapView 移到到手机当前的位置
- (void)updateMapView {
    CLLocation *location = self.mapView.userLocation.location;
    
    if (!location) {
        return;
    }
    
    CGFloat mapDistance;
    
    if (self.hidesRadius) {
        mapDistance = 500.0 / 320.0 * CGRectGetWidth(self.view.frame);
    } else {
        self.radius = 200.0;
        mapDistance = self.radius * 2 / CGRectGetWidth(self.pinView.frame) * CGRectGetWidth(self.view.frame);
    }
    
    CLLocationCoordinate2D coordinate = location.coordinate;
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(coordinate, mapDistance, mapDistance);
    
    [self.mapView setRegion:region animated:YES];
}

// 将 mapView 移到到指定位置
- (void)updateMapViewWithRegionDict:(NSDictionary *)regionDict {
    if (!regionDict || regionDict.count == 0) {
        [self updateMapView];
        return;
    }
    
    CGFloat mapDistance;
    
    if (self.hidesRadius) {
        mapDistance = 500.0 / 320.0 * CGRectGetWidth(self.view.frame);
    } else {
        self.radius = [regionDict[@"radius"] floatValue];
        mapDistance = self.radius * 2 / CGRectGetWidth(self.pinView.frame) * CGRectGetWidth(self.view.frame);
    }
    
    CGFloat latitude = [regionDict[@"latitude"] floatValue];
    CGFloat longitude = [regionDict[@"longitude"] floatValue];
    CLLocationCoordinate2D gpsCoordinate = {latitude, longitude};
    // 将 GPS 坐标转换为 高德地图 坐标
    CLLocationCoordinate2D coordinate = [GizCoordinateTransform transformFromWGSToGCJ:gpsCoordinate];
    MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(coordinate, mapDistance, mapDistance);
    
    [self.mapView setRegion:region animated:YES];
}

// 计算 mapView 中两个点之间的距离
- (CLLocationDistance)distanceBetweenPoint1:(CGPoint)point1 point2:(CGPoint)point2 {
    CLLocationCoordinate2D leftCoordinate = [self.mapView convertPoint:point1 toCoordinateFromView:nil];
    CLLocationCoordinate2D rightCoordinate = [self.mapView convertPoint:point2 toCoordinateFromView:nil];
    
    MKMapPoint leftMapPoint = MKMapPointForCoordinate(leftCoordinate);
    MKMapPoint rightMapPoint = MKMapPointForCoordinate(rightCoordinate);
    return MKMetersBetweenMapPoints(leftMapPoint, rightMapPoint);
}

#pragma mark - Setters

- (void)setThemeColor:(UIColor *)themeColor {
    _themeColor = themeColor;
    
    if (self.pinView) {
        self.pinView.themeColor = themeColor;
    }
}

- (void)setRightButtonTitle:(NSString *)rightButtonTitle {
    _rightButtonTitle = rightButtonTitle;
    
    if (self.rightBarButtonItem) {
        self.rightBarButtonItem.title = rightButtonTitle;
    }
}

#pragma mark - Actions

// 返回
- (void)actionBack:(id)sender {
    
    if (self.completionHandler) {
        self.completionHandler(nil, YES);
    }
    
    [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}

// 确定
- (void)actionRightBarButtonClicked:(id)sender {
    
    NSMutableDictionary *regionDict;
    
    if (self.regionDict) {
        regionDict = [[NSMutableDictionary alloc] initWithDictionary:self.regionDict];
    } else {
        regionDict = [[NSMutableDictionary alloc] init];
    }
    
    CLLocationCoordinate2D coordinate = self.mapView.centerCoordinate;
    
    // 将 高德地图 坐标转换为 GPS 坐标
    CLLocationCoordinate2D gpsCoordinate = [GizCoordinateTransform transformFromGCJToWGS:coordinate];
    
    [regionDict setObject:@(gpsCoordinate.latitude) forKey:@"latitude"];
    [regionDict setObject:@(gpsCoordinate.longitude) forKey:@"longitude"];
    
    if (self.hidesRadius) {
        
    } else {
        GizRegionPinView *regionView = (GizRegionPinView *)self.pinView;
        [regionDict setObject:@(regionView.radius) forKey:@"radius"];
    }
    
    if (self.completionHandler) {
        self.completionHandler(regionDict, NO);
    }
    
    [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}

// 跳转到手机当前的位置
- (IBAction)actionLocate:(id)sender {
    [self updateMapView];
}

#pragma mark - CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
    
    switch (status) {
        case kCLAuthorizationStatusAuthorizedWhenInUse:
        case kCLAuthorizationStatusAuthorizedAlways:
            self.mapView.showsUserLocation = YES;
            break;
            
        default:
            break;
    }
}

#pragma mark - MKMapViewDelegate

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
    
    if (self.hasInitializedMapView) {
        return;
    }
    
    self.hasInitializedMapView = YES;
    
    if (!self.regionDict) {
        [self updateMapView];
    } else {
        [self updateMapViewWithRegionDict:self.regionDict];
    }
}

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    
    if (self.hidesRadius) {
        return;
    }
    
    GizRegionPinView *regionView = (GizRegionPinView *)self.pinView;
    
    CGPoint mapCenter = mapView.center;
    CGFloat width = CGRectGetWidth(self.pinView.frame);
    CGFloat half = width / 2.0;
    CGPoint leftPoint = CGPointMake(mapCenter.x - half, mapCenter.y);
    CGPoint rightPoint = CGPointMake(mapCenter.x + half, mapCenter.y);
    
    CLLocationDistance distance = [self distanceBetweenPoint1:leftPoint point2:rightPoint];
    
    // mapView setRegion 的时候，实际计算出来的半径 会比 self.radius 小一点，
    // 因此用线性拟合补上误差，使实际值看起来更接近 self.radius
    regionView.radius = distance / 2.0 + 0.001799669678803586 * self.radius + 0.0026730136303125818;
}

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
    MKAnnotationView *view = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"emptyAnnotation"];
    return view;
}

@end
