//
//  QRCodeViewController.m
//  kneet
//
//  Created by Jason Lee on 5/18/15.
//  Copyright (c) 2015 ntels. All rights reserved.
//
@import AVFoundation;
#import "JDObject.h"
#import "RequestHandler.h"

#import "CustomTextField.h"
#import "QRCodeInputPopupView.h"
#import "UIDeviceUtil.h"

#import "QRCodeViewController.h"
#import "HomeHubInitViewController.h"
#import "HomeHubChangeViewController.h"


@interface QRCodeViewController () <AVCaptureMetadataOutputObjectsDelegate> {
    CGRect _captureRect;
    QRCodeInputPopupView *_inputPopup;
    AVAuthorizationStatus _avAuthrizationStatus;
}


@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;
@property (nonatomic, strong) CALayer *targetLayer;
@property (nonatomic, strong) CAShapeLayer *guideLayer;

@property (nonatomic, strong) AVCaptureSession *captureSession;
@property (nonatomic, strong) NSMutableArray *codeObjects;
@end


#pragma mark - Class Definition

@implementation QRCodeViewController


- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    [self initUI];
    [self prepareViewDidLoad];
}


- (void)initUI {

}

- (void)prepareViewDidLoad {

}


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

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(applicationDidEnterBackground:)
                                                 name:UIApplicationDidEnterBackgroundNotification
                                               object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(applicationWillEnterForeground:)
                                                 name:UIApplicationWillEnterForegroundNotification
                                               object:nil];
    [self startRunning];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [self stopRunning];
}

- (void)applicationDidEnterBackground:(NSNotification *)notification
{
    [self stopRunning];
}

- (void)applicationWillEnterForeground:(NSNotification *)notification
{
    [self startRunning];
}


#pragma mark - Main Logic
- (NSMutableArray *)codeObjects
{
    if (!_codeObjects)
    {
        _codeObjects = [NSMutableArray new];
    }
    return _codeObjects;
}

- (void)requestQRAuthrize:(NSString *)activationCode password:(NSString *)password {
    //parameters
    NSDictionary *parameter = @{@"activation_code": activationCode,
                                @"activation_password": password};
    
    NSString *path = [NSString stringWithFormat:API_GET_PARTNER_QR];
    
    [[RequestHandler handler] sendAsyncGetRequestAPIPath:path parameters:parameter modelClass:[QRAuthModel class] completion:^(id responseObject) {
        if (!responseObject) {//응답결과가 잘못되었거나 없을 경우,
            return;
        }
        
        QRAuthModel *qauth = (QRAuthModel *) responseObject;
        
        if (qauth) {//API 성공 ,
            
            UIViewController *vc = nil;
            if (![qauth.ownerYn boolValue]) {//N : 장치의 소유자가 없음.(새 비밀번호 지정 필요)
                HomeHubInitViewController *tvc = (HomeHubInitViewController *)[CommonUtil instantiateViewControllerWithIdentifier:@"HomeHubInitViewController" storyboardName:@"HomeHub"];
                
                tvc.activationCode = activationCode;
                tvc.activationPassword = password;
                
                vc = tvc;
            } else {//Y : 장치의 소유자가 있음.(이전 비밀번호 확인 필요)
                
                HomeHubChangeViewController *cvc = (HomeHubChangeViewController *)[CommonUtil instantiateViewControllerWithIdentifier:@"HomeHubChangeViewController" storyboardName:@"HomeHub"];
                
                cvc.activationCode = activationCode;
                cvc.activationPassword = password;

                vc = cvc;
            }
            
            [self presentViewController:vc animated:YES completion:nil];
        }
    } failure:^(id errorObject) {
        JDErrorModel *error = (JDErrorModel *)errorObject;
        [[JDFacade facade] alert:error.errorMessage];
    }];
    
}


#pragma mark - Main Logic

- (AVCaptureSession *)captureSession
{
    if (!_captureSession)
    {
        NSError *error = nil;
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        if (device.isAutoFocusRangeRestrictionSupported)
        {
            if ([device lockForConfiguration:&error])
            {
                [device setAutoFocusRangeRestriction:AVCaptureAutoFocusRangeRestrictionNear];
                [device unlockForConfiguration];
            }
        }

        // The first time AVCaptureDeviceInput creation will present a dialog to the user
        // requesting camera access. If the user refuses the creation fails.
        // See WWDC 2013 session #610 for details, but note this behaviour does not seem to
        // be enforced on iOS 7 where as it is with iOS 8.

        AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
        if (deviceInput)
        {
            _captureSession = [[AVCaptureSession alloc] init];
            if ([_captureSession canAddInput:deviceInput])
            {
                [_captureSession addInput:deviceInput];
            }

            AVCaptureMetadataOutput *metadataOutput = [[AVCaptureMetadataOutput alloc] init];
            if ([_captureSession canAddOutput:metadataOutput])
            {
                [_captureSession addOutput:metadataOutput];
                [metadataOutput setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
                [metadataOutput setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
            }

            //카메라 프리뷰 레이어
            self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
            self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
            self.previewLayer.frame = self.view.bounds;

            [self.view.layer addSublayer:self.previewLayer];

            //가이드 레이어 작성
            UIImage *imgGuide = [UIImage imageNamed:@"tp_01_img_thingsadd_reg_02_QR_areapoint"];

            CGFloat orix = (IPHONE_WIDTH - imgGuide.size.width) / 2;
            CGFloat oriy = (IPHONE_HEIGHT - _conainerView.frame.size.height - imgGuide.size.height) / 2;
            _captureRect = CGRectMake(orix, oriy, imgGuide.size.width, imgGuide.size.height);

            self.guideLayer = [CAShapeLayer layer];
            self.guideLayer.contents = (id)[imgGuide CGImage];
            self.guideLayer.frame = _captureRect;
//            self.guideLayer.fillColor = nil;
//            self.guideLayer.strokeColor = [UIColor grayColor].CGColor;
//            self.guideLayer.lineWidth = 10.0f;
            [self.view.layer addSublayer:self.guideLayer];

            [self.view addSubview:_conainerView];


            CGFloat width = [CommonUtil hardware] == IPHONE_6 ? 375 : 320;
            width = [CommonUtil hardware] == IPHONE_6_PLUS ? 414 : width;

            [_conainerView mas_makeConstraints:^(MASConstraintMaker *make) {
                make.size.width.mas_equalTo(self.view.frame.size.width);
                make.bottom.equalTo(self.view.mas_baseline);
            }];
        }
        else
        {
            NSLog(@"Input Device error: %@",[error localizedDescription]);
            [self showAlertForCameraError:error];
        }
    }
    return _captureSession;
}

#pragma mark - AVCaptureMetadataOutputObjectsDelegate

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
    self.codeObjects = nil;

    for (AVMetadataObject *metadataObject in metadataObjects)
    {
        AVMetadataMachineReadableCodeObject *transformed = (AVMetadataMachineReadableCodeObject *)[self.previewLayer transformedMetadataObjectForMetadataObject:metadataObject];

        if ([transformed.type isEqualToString:AVMetadataObjectTypeQRCode]) {
            // Update the frame on the _boundingBox view, and show it
            CGRect mr = transformed.bounds;
            if (CGRectContainsRect(_captureRect, mr)) {
                NSLog(@"%@", transformed.stringValue);
                [self stopRunning];
                [self gotoSetSecurityOfDevice:transformed.stringValue];
            }
        }
    }
}


- (void)showAlertForCameraError:(NSError *)error
{
    NSString *message = error.localizedFailureReason ? error.localizedFailureReason : error.localizedDescription;
    [[JDFacade facade] alert:message];
}


- (void)startRunning
{

#if TARGET_IPHONE_SIMULATOR
    [self btnInsertTouched:nil];
    return;
#endif
    
    _avAuthrizationStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    if (_avAuthrizationStatus != AVAuthorizationStatusAuthorized) {//카메라 권한이 없을 경우,
        NSString *message = MSG_CAMERA_DISABLE;
        
        CustomAlertView *alert = [[CustomAlertView alloc] initWithTitle:NSLocalizedString(@"알림", @"알림") delegate:nil OKButtonTitle:NSLocalizedString(@"설정", @"설정") cancelButtonTitle:NSLocalizedString(@"취소", @"취소") message:message, nil];
        [alert showWithCompletion:^(CustomAlertView *alertView, NSInteger buttonIndex) {
            if (buttonIndex == 0) {//OK - 이전화면으로
                
                NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                [[UIApplication sharedApplication] openURL:settingsURL];
                return;
            } else {
                [self btnInsertTouched:nil]; //직접 입력창을 띄움.
            }
        }];
    } else {//권한이 있을 경우,
        self.codeObjects = nil;
        [self.captureSession startRunning];
//        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
//            if (granted) {
//            }
//        }];
    }
}

- (void)stopRunning
{
#if TARGET_IPHONE_SIMULATOR
    return;
#endif

    [self.captureSession stopRunning];
    self.captureSession = nil;
}

- (void)clearTargetLayer
{
//    NSArray *sublayers = [[self.targetLayer sublayers] copy];
//    for (CALayer *sublayer in sublayers)
//    {
//        [sublayer removeFromSuperlayer];
//    }
}

- (void)showDetectedObjects
{
    for (AVMetadataObject *metadata in self.codeObjects)
    {

        if ([metadata.type isEqualToString:AVMetadataObjectTypeQRCode]) {
            AVMetadataMachineReadableCodeObject *transformed = (AVMetadataMachineReadableCodeObject *)[self.previewLayer transformedMetadataObjectForMetadataObject:metadata];
            // Update the frame on the _boundingBox view, and show it
            CGRect mr = transformed.bounds;

            if (CGRectContainsRect(self.guideLayer.frame, mr)) {

                CAShapeLayer *shapeLayer = [CAShapeLayer layer];
                //            shapeLayer.strokeColor = [UIColor redColor].CGColor;
                //            shapeLayer.fillColor = [UIColor clearColor].CGColor;
                //            shapeLayer.lineWidth = 2.0;
                //            shapeLayer.lineJoin = kCALineJoinRound;
                CGPathRef path = createPathForPoints([(AVMetadataMachineReadableCodeObject *)metadata corners]);
                shapeLayer.path = path;

                CGRect *pr = nil;
                if (CGPathIsRect(path, pr)) {
                    NSLog(@"%@", NSStringFromCGRect(*pr));


                    //            if (CGPathEqualToPath(self.guideLayer.path, path)) {
                    NSLog(@"same");
                } else {
                    NSLog(@"not");
                }
                //            CFRelease(path);
                //            [self.targetLayer addSublayer:shapeLayer];
            } else {

            }
        }
    }
}

CGMutablePathRef createPathForPoints(NSArray* points)
{
    CGMutablePathRef path = CGPathCreateMutable();
    CGPoint point;

    if ([points count] > 0)
    {
        CGPointMakeWithDictionaryRepresentation((CFDictionaryRef)[points objectAtIndex:0], &point);
        CGPathMoveToPoint(path, nil, point.x, point.y);

        int i = 1;
        while (i < [points count])
        {
            CGPointMakeWithDictionaryRepresentation((CFDictionaryRef)[points objectAtIndex:i], &point);
            CGPathAddLineToPoint(path, nil, point.x, point.y);
            i++;
        }

        CGPathCloseSubpath(path);
    }

    return path;
}


- (void)gotoSetSecurityOfDevice:(NSString *)QRCode {

    NSArray *qrs = [QRCode componentsSeparatedByString:@"|"];
    if (!qrs || qrs.count < 3 || ![qrs[1] isEqualToString:@"*_AC_*"]) {//니트 디바이스
        [[JDFacade facade] alert:NSLocalizedString(@"서비스 지원장치가 아닙니다", @"서비스 지원장치가 아닙니다")];
        return;
    }

    [self requestQRAuthrize:qrs[0] password:qrs[2]];
}

#pragma mark - UI Events
- (void)btnInsertTouched:(id)sender {
    if (!_inputPopup) {
        _inputPopup = [[QRCodeInputPopupView alloc] initFromNib];
    }
    
    _inputPopup.qrcodeType = _qrcodeType;
    _inputPopup.txtActivationCode.text = ksEmptyString;
    [_inputPopup showWithCompletion:^(CustomAlertView *alertView, NSInteger buttonIndex) {
        if (buttonIndex == 0) {//OK
            [self requestQRAuthrize:_inputPopup.txtActivationCode.text password:_inputPopup.txtPasswd.text];
        } else {
            if (_avAuthrizationStatus != AVAuthorizationStatusAuthorized) {//카메라 권한이 없을 경우, 리턴,
                [self btnCancelTouched:nil];
            }
        }
    }];
}

- (void)btnCancelTouched:(id)sender {
    [[JDFacade facade] dismissModalStack:YES completion:nil];
}


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

@end
