//
//  ScanCodeViewController.m
//  GotoBus
//
//  Created by Vae on 2018/6/21.
//

#import "ScanCodeViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "Lang.h"
#import "SDK.h"
#import "CocoaUtils.h"
#import <BlocksKit/BlocksKit.h>
#import <BlocksKit/BlocksKit+UIKit.h>
#import <libextobjc/EXTScope.h>
#import "Utility.h"
#import "BeanUtils.h"
#import "PurchaseRecordResponseJsonMapper.h"
#import "QuickScanTicketResponseJsonMapper.h"
#import "PerlWS.h"
#import "CheckInActionHandler.h"
#import "CheckInResultViewController.h"
#import "Vars.h"
#import "TicketStatusApi.h"
#import "ScanCodeJsonMapper.h"
#import "ScanResultViewController.h"
@interface ScanCodeViewController ()<AVCaptureMetadataOutputObjectsDelegate>

@property (nonatomic, weak) IBOutlet UILabel *tooltipLabel;
@property (nonatomic, weak) IBOutlet UIView *scanRectView;


@property (nonatomic, strong) AVCaptureSession *captureSession;
@property (nonatomic, strong) dispatch_queue_t sessionQueue;

@property (nonatomic, strong) NSMutableArray *stocks;
@property (nonatomic, strong) NSString *qrCode;


@end

@implementation ScanCodeViewController

- (instancetype)init {
    if (self = [super init]) {
        // Custom initialization
        self.edgesForExtendedLayout = UIRectEdgeNone;
        self.title = @"Check-In";
        self.hidesBottomBarWhenPushed = YES;
        [[Vars appDelegate] applyDefaultConfigurationForViewController:self];
    }
    return self;
}

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.stocks = [NSMutableArray array];
    
    self.tooltipLabel.text = [NSString stringWithFormat:@"Place a %@ inside the viewfinder rectangle to scan it", [[Vars appDelegate].loginUser.availableMetadataObjectType isEqualToString:AVMetadataObjectTypeQRCode] ? @"QR code" : @"barcode"];
    
    [self createReading];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
    [self beginReading];
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    
    [self stopReading];
}

#pragma mark - Network

-(void)uploadQrCode{
    ScanTicketBarcode *scanTicketBarCode = [[ScanTicketBarcode alloc] init];
    scanTicketBarCode.barcode = self.qrCode;
    scanTicketBarCode.scheduleStopId = self.scheduleStopId;
    scanTicketBarCode.serviceDate = self.serviceDate;
    
    NSDictionary *requestDict = [BeanUtils describeAccessible:scanTicketBarCode];
    [Utility performRESTRequestWithMethod:@"POST" url:scanTicketBarCode.address parameters:requestDict success:^(id object) {
        NSLog(@"%@",object);
        ScanCodeJsonMapper *mapper = [[ScanCodeJsonMapper alloc] init];
        if (![mapper parseWithJSONObject:object]) {
            ScanTicketBarcodeResponse *response = mapper.response;
            [self performSegueScanResultViewController:response];
        }
        
    } error:^(NSError *error) {
        NSLog(@"%@",error);
    }];
}

-(void)performSegueScanResultViewController:(ScanTicketBarcodeResponse *)response{
    ScanResultViewController *viewController = [[ScanResultViewController alloc] init];
    viewController.service_date = self.serviceDate;
    viewController.stock = response.soldStock;
    viewController.message = response.message;
    viewController.status = response.status;
    [self.navigationController pushViewController:viewController animated:YES];
}

#pragma mark - Private

- (void)createReading {
    if (TARGET_IPHONE_SIMULATOR) {
        return;
    }
    self.sessionQueue = dispatch_queue_create("session queue", DISPATCH_QUEUE_SERIAL);
    @weakify(self)
    dispatch_async(self.sessionQueue, ^{
        // NSLog(@"create %@ %@", [NSThread currentThread], [NSOperationQueue currentQueue]);
        @strongify(self)
        AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        if (captureDevice.isAutoFocusRangeRestrictionSupported) {
            if ([captureDevice lockForConfiguration:NULL]) {
                captureDevice.autoFocusRangeRestriction = AVCaptureAutoFocusRangeRestrictionNear;
                [captureDevice unlockForConfiguration];
            }
        }
        AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:NULL];
        if (!input) {
            return;
        }
        self.captureSession = [[AVCaptureSession alloc] init];
        if (![self.captureSession canAddInput:input]) {
            return;
        }
        [self.captureSession addInput:input];
        
        AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
        [captureMetadataOutput setMetadataObjectsDelegate:self queue:self.sessionQueue];
        if (![self.captureSession canAddOutput:captureMetadataOutput]) {
            return;
        }
        [self.captureSession addOutput:captureMetadataOutput];
        captureMetadataOutput.metadataObjectTypes = @[[Vars appDelegate].loginUser.availableMetadataObjectType];
    });
}

- (void)beginReading {
    self.qrCode = nil;
    for (SoldStock *stock in self.stocks) {
        stock.checked = NO;
    }
    if (TARGET_IPHONE_SIMULATOR) {
        [CocoaUtils showPlainInputBoxWithTitle:@"QR Code" message:nil configurationHandler:nil dismissalHandler:^(UITextField *textField) {
            self.qrCode = textField.text;
        }];
        return;
    }
    @weakify(self)
    dispatch_async(self.sessionQueue, ^{
        // NSLog(@"start %@ %@", [NSThread currentThread], [NSOperationQueue currentQueue]);
        @strongify(self)
        if (![self.captureSession isRunning]) {
            [self.captureSession startRunning];
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            // NSLog(@"add layer %@ %@", [NSThread currentThread], [NSOperationQueue currentQueue]);
            AVCaptureVideoPreviewLayer *videoPreviewLayer = [CocoaUtils sublayerWithName:NSStringFromClass([AVCaptureVideoPreviewLayer class]) fromSuperlayer:self.scanRectView.layer];
            if (!videoPreviewLayer) {
                videoPreviewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
                videoPreviewLayer.name = NSStringFromClass([AVCaptureVideoPreviewLayer class]);
                [self.scanRectView.layer addSublayer:videoPreviewLayer];
            }
            videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
            videoPreviewLayer.frame = self.scanRectView.bounds;
        });
    });
}

- (void)stopReading {
    if (TARGET_IPHONE_SIMULATOR) {
        return;
    }
    @weakify(self)
    dispatch_async(self.sessionQueue, ^{
        // NSLog(@"stop %@ %@", [NSThread currentThread], [NSOperationQueue currentQueue]);
        @strongify(self)
        if ([self.captureSession isRunning]) {
            [self.captureSession stopRunning];
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            // NSLog(@"remove layer %@ %@", [NSThread currentThread], [NSOperationQueue currentQueue]);
            AVCaptureVideoPreviewLayer *videoPreviewLayer = [CocoaUtils sublayerWithName:NSStringFromClass([AVCaptureVideoPreviewLayer class]) fromSuperlayer:self.scanRectView.layer];
            if (videoPreviewLayer) {
                [videoPreviewLayer removeFromSuperlayer];
            }
        });
    });
}

#pragma mark - Capture output delegate

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    // NSLog(@"capture output %@ %@", [NSThread currentThread], [NSOperationQueue currentQueue]);
    AVMetadataMachineReadableCodeObject *codeObject = [metadataObjects bk_match:^BOOL (AVMetadataMachineReadableCodeObject *obj) {
        return [obj.type isEqualToString:[Vars appDelegate].loginUser.availableMetadataObjectType];
    }];
    if (!codeObject.stringValue || [self.qrCode isEqualToString:codeObject.stringValue]) {
        return;
    }
    self.qrCode = codeObject.stringValue;
    // NSLog(@"qrCode = %@", self.qrCode);
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
    [self performSelectorOnMainThread:@selector(stopReading) withObject:nil waitUntilDone:NO];
    dispatch_async(dispatch_get_main_queue(), ^{
        [self uploadQrCode];
      
    });
}

@end
