//
//  EZMessagePlaybackViewController.m
//  EZOpenSDKDemo
//
//  Created by DeJohn Dong on 15/11/15.
//  Copyright © 2015年 Ezviz. All rights reserved.
//

#import "EZMessagePlaybackViewController.h"
#import "EZScreenOrientationTool.h"
#import "FCFileManager.h"
#import "UIViewController+EZBackPop.h"
#import "UIAlertController+DeviceVerifyCodeBySerial.h"

#import "EZPlayer.h"
#import "HIKLoadView.h"
#import "EZDeviceRecordFile.h"
#import "EZCloudRecordFile.h"

@interface EZMessagePlaybackViewController ()<EZPlayerDelegate> {
    BOOL _isOpenSound;
    BOOL _isPlaying;
    BOOL _isShowToolbox;
    
    NSTimer *_recordTimer;
    
    FILE *_localRecord;
    
    NSString *_filePath;
    
    NSTimeInterval _seconds;
    CALayer *_orangeLayer;
    
    NSTimeInterval _playSeconds; //播放秒数
    NSTimeInterval _duringSeconds; //录像时长
    
    EZDeviceRecordFile *_deviceRecord;
    EZCloudRecordFile *_cloudRecord;
}

@property (nonatomic, strong) NSMutableArray *records;
@property (nonatomic, strong) NSDate *beginTime;
@property (nonatomic, strong) NSDate *endTime;
@property (nonatomic, strong) EZPlayer *player;
@property (nonatomic, strong) HIKLoadView *loadingView;
@property (nonatomic) BOOL isSelectedDevice;
@property (nonatomic, weak) IBOutlet UIView *playerView;
@property (nonatomic, weak) IBOutlet UIView *playerToolbox;
@property (nonatomic, weak) IBOutlet UIButton *voiceButton;
@property (nonatomic, weak) IBOutlet UIButton *playButton;
@property (nonatomic, weak) IBOutlet UIButton *largeButton;
@property (nonatomic, weak) IBOutlet UILabel *playTimeLabel;
@property (nonatomic, weak) IBOutlet UILabel *duringTimeLabel;
@property (nonatomic, weak) IBOutlet UISlider *duringSlider;
@property (nonatomic, weak) IBOutlet UIButton *largeBackButton;
@property (nonatomic, weak) IBOutlet NSLayoutConstraint *playerToolboxConstraint;
@property (nonatomic, weak) IBOutlet UIButton *captureButton;
@property (nonatomic, weak) IBOutlet UIButton *localRecordButton;
@property (nonatomic, weak) IBOutlet UILabel *localRecordLabel;
@property (nonatomic, strong) NSTimer *playbackTimer;
@property (nonatomic, strong) NSMutableData *fileData;

@end

@implementation EZMessagePlaybackViewController

- (void)dealloc {
    NSLog(@"%@ dealloc", self.class);
    [EZOPENSDK releasePlayer:_player];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.title = self.info.alarmName;
    self.isAutorotate = YES;
    
    self.largeBackButton.hidden = YES;
    _isOpenSound = YES;
    
    if (!_records)
        _records = [NSMutableArray new];
    
    
    _player = [EZPlayer createPlayerWithDeviceSerial:self.info.deviceSerial cameraNo:self.info.cameraNo];
    _player.delegate = self;
    [_player setPlayerView:_playerView];
    //判断设备是否加密，加密就从demo的内存中获取设备验证码填入到播放器的验证码接口里，本demo只处理内存存储，本地持久化存储用户自行完成
    if (self.deviceInfo.isEncrypt) {
        NSString *verifyCode = [[GlobalKit shareKit].deviceVerifyCodeBySerial objectForKey:self.info.deviceSerial];
        [_player setPlayVerifyCode:verifyCode];
    }
    
    
    if(!_loadingView)
        _loadingView = [[HIKLoadView alloc] initWithHIKLoadViewStyle:HIKLoadViewStyleSqureClockWise];
    [self.view insertSubview:_loadingView aboveSubview:self.playerView];
    [_loadingView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.width.height.mas_equalTo(@14);
        make.centerX.mas_equalTo(self.playerView.mas_centerX);
        make.centerY.mas_equalTo(self.playerView.mas_centerY);
    }];
    [self.loadingView startSquareClcokwiseAnimation];
    
    [self.captureButton dd_centerImageAndTitle];
    [self.localRecordButton dd_centerImageAndTitle];
    
    [self.duringSlider setThumbImage:[UIImage imageNamed:@"slider"] forState:UIControlStateNormal];
    [self.duringSlider setThumbImage:[UIImage imageNamed:@"slider_sel"] forState:UIControlStateHighlighted];
    
    self.captureButton.enabled = NO;
    self.localRecordButton.enabled = NO;
    
    self.beginTime = [self.info.alarmStartTime dateByAddingTimeInterval:-(self.info.preTime)];
    self.endTime = [self.info.alarmStartTime dateByAddingTimeInterval:self.info.delayTime];
    __weak typeof (self) weakSelf = self;
    [EZOPENSDK searchRecordFileFromDevice:self.info.deviceSerial
                                 cameraNo:self.info.cameraNo
                                beginTime:self.beginTime
                                  endTime:self.endTime
                               completion:^(NSArray *deviceRecords, NSError *error) {
                                   [weakSelf.records removeAllObjects];
                                   if ([deviceRecords count] == 0) {
                                       [weakSelf doCloudSearch];
                                   } else {
                                       weakSelf.isSelectedDevice = YES;
                                       [weakSelf.records addObjectsFromArray:deviceRecords];
                                       [weakSelf doPlayFirst];
                                   }
                               }];
    
    self.localRecordLabel.layer.borderColor = [UIColor whiteColor].CGColor;
    self.localRecordLabel.layer.cornerRadius = 12.0f;
    self.localRecordLabel.layer.borderWidth = 1.0f;
    self.localRecordLabel.clipsToBounds = YES;

    _isShowToolbox = YES;
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.navigationController.navigationBar.barStyle = UIBarStyleDefault;
    self.navigationController.navigationBar.tintColor = UIBarStyleDefault;
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    if (self.playbackTimer) {
        [self.playbackTimer invalidate];
        self.playbackTimer = nil;
    }
    
    if (_recordTimer) {
        [_recordTimer invalidate];
        _recordTimer = nil;
    }
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(hiddenPlayerToolbox:) object:nil];
    [self.loadingView stopSquareClockwiseAnimation];
    [_player closeSound];
    [_player stopPlayback];
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
                                duration:(NSTimeInterval)duration {
    self.navigationController.navigationBarHidden = NO;
    self.largeBackButton.hidden = YES;
    self.playerToolboxConstraint.constant = 60.0f;
    self.largeButton.hidden = NO;
    self.voiceButton.hidden = NO;
    self.playButton.hidden = NO;
    if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
        toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
        self.playerToolboxConstraint.constant = 23.0f;
        self.playButton.hidden = YES;
        self.voiceButton.hidden = YES;
        self.largeButton.hidden = YES;
        self.largeBackButton.hidden = NO;
        self.navigationController.navigationBarHidden = YES;
    }
}

#pragma mark - PlayerDelegate Methods

- (void)player:(EZPlayer *)player didPlayFailed:(NSError *)error {
    NSLog(@"player: %@ didPlayFailed: %@", player, error);
    // 如果是需要验证码或者是验证码错误
    if (error.code == EZ_SDK_NEED_VALIDATECODE) {
        [self showSetPassword];
    } else if (error.code == EZ_SDK_VALIDATECODE_NOT_MATCH) {
        [self showRetry];
    } else {
        [UIView dd_showDetailMessage:[NSString stringWithFormat:@"%d", (int)error.code]];
    }
}

- (void)player:(EZPlayer *)player didReceivedMessage:(NSInteger)messageCode {
    NSLog(@"player: %@, didReceivedMessage: %d", player, (int)messageCode);
    if (messageCode == PLAYER_PLAYBACK_START) {
        _isPlaying = YES;
        [self.playButton setImage:[UIImage systemImageNamed:@"pause.fill"] forState:UIControlStateNormal];
        [self.loadingView stopSquareClockwiseAnimation];
        
        if (!_isOpenSound) {
            [_player closeSound];
        }
        
        if (self.playbackTimer) {
            [self.playbackTimer invalidate];
            self.playbackTimer = nil;
        }
        
        self.playbackTimer = [NSTimer scheduledTimerWithTimeInterval:1
                                                              target:self
                                                            selector:@selector(messagePlaybackRefresh:)
                                                            userInfo:nil
                                                             repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:self.playbackTimer forMode:NSRunLoopCommonModes];
        
        self.localRecordButton.enabled = YES;
        self.captureButton.enabled = YES;
        
        [self performSelector:@selector(hiddenPlayerToolbox:) withObject:nil afterDelay:5.0f];
    } else if (messageCode == PLAYER_PLAYBACK_STOP) {
        if (self.playbackTimer) {
            [self.playbackTimer invalidate];
            self.playbackTimer = nil;
        }
    }
}


#pragma mark - Actions

- (IBAction)large:(id)sender {
    [EZScreenOrientationTool landscape:self];
}

- (IBAction)largeBack:(id)sender {
    [EZScreenOrientationTool portrait:self];
}

- (IBAction)voiceButtonClicked:(id)sender {
    if (_isOpenSound) {
        [_player closeSound];
        [self.voiceButton setImage:[UIImage systemImageNamed:@"speaker.slash"] forState:UIControlStateNormal];
    } else {
        [_player openSound];
        [self.voiceButton setImage:[UIImage systemImageNamed:@"speaker.wave.2"] forState:UIControlStateNormal];
    }
    _isOpenSound = !_isOpenSound;
}

- (IBAction)duringValueChange:(id)sender {
    NSDate *offsetTime = nil;
    if (_isSelectedDevice) {
        offsetTime = [_deviceRecord.startTime dateByAddingTimeInterval:_duringSeconds * self.duringSlider.value];
    } else {
        offsetTime = [_cloudRecord.startTime dateByAddingTimeInterval:_duringSeconds * self.duringSlider.value];
    }
    if(self.playbackTimer) {
        [self.playbackTimer invalidate];
        self.playbackTimer = nil;
    }
    [_player seekPlayback:offsetTime];
    [self.loadingView startSquareClcokwiseAnimation];
}

- (IBAction)playButtonClicked:(id)sender {
    if (_isPlaying) {
        [_player pausePlayback];
        [self.playButton setImage:[UIImage systemImageNamed:@"play"] forState:UIControlStateNormal];
        self.localRecordButton.enabled = NO;
        self.captureButton.enabled = NO;
        if (_playbackTimer && _cloudRecord) {
            [_playbackTimer invalidate];
            _playbackTimer = nil;
        }
    } else {
        [_player resumePlayback];
        [self.playButton setImage:[UIImage systemImageNamed:@"pause.fill"] forState:UIControlStateNormal];
        self.localRecordButton.enabled = YES;
        self.captureButton.enabled = YES;
        if (_cloudRecord)
           [self.loadingView startSquareClcokwiseAnimation];
    }
    _isPlaying = !_isPlaying;
}

- (void)doPlayFirst {
    id record = [_records dd_objectAtIndex:0];
    if (record && [record isKindOfClass:[EZDeviceRecordFile class]]) {
        EZDeviceRecordFile *alarmRecrod = record;
        alarmRecrod.startTime = self.beginTime;
        alarmRecrod.stopTime = self.endTime;
        [_player startPlaybackFromDevice:alarmRecrod];
        _deviceRecord = alarmRecrod;
    } else if (record && [record isKindOfClass:[EZCloudRecordFile class]]) {
        EZCloudRecordFile *alarmRecrod = record;
        alarmRecrod.startTime = self.beginTime;
        alarmRecrod.stopTime = self.endTime;
        [_player startPlaybackFromCloud:alarmRecrod];
        _cloudRecord = alarmRecrod;
    } else {
        return;
    }
    
    [self duringTimeShow];
    [self.loadingView startSquareClcokwiseAnimation];
    
    _isPlaying = YES;
}

- (void)duringTimeShow {
    if (_isSelectedDevice) {
        _duringSeconds = [_deviceRecord.stopTime timeIntervalSinceDate:_deviceRecord.startTime];
    } else {
        _duringSeconds = [_cloudRecord.stopTime timeIntervalSinceDate:_cloudRecord.startTime];
    }
    
    if (_duringSeconds >= 3600) {
        int hour = (int)_duringSeconds / 3600;
        int minute =  ((int)_duringSeconds % 3600) / 60;
        int seconds = (int)_duringSeconds % 60;
        self.duringTimeLabel.text = [NSString stringWithFormat:@"%02d:%02d:%02d", hour, minute, seconds];
        self.playTimeLabel.text = @"00:00:00";
    } else {
        int minute =  (int)_duringSeconds / 60;
        int seconds = (int)_duringSeconds % 60;
        self.duringTimeLabel.text = [NSString stringWithFormat:@"%02d:%02d", minute, seconds];
        self.playTimeLabel.text = @"00:00";
    }
}

- (void)messagePlaybackRefresh:(NSTimer *)timer {
    NSDate *currentTime = [_player getOSDTime];
    if (_isSelectedDevice) {
        _playSeconds = [currentTime timeIntervalSinceDate:_deviceRecord.startTime];
    } else {
        _playSeconds = [currentTime timeIntervalSinceDate:_cloudRecord.startTime];
    }
    
    if (_playSeconds < 0) {
        _playSeconds = 0;
    }
    
    if (_duringSeconds >= 3600) {
        int hour = (int)_playSeconds / 3600;
        int minute =  ((int)_playSeconds % 3600) / 60;
        int seconds = (int)_playSeconds % 60;
        self.playTimeLabel.text = [NSString stringWithFormat:@"%02d:%02d:%02d", hour, minute, seconds];
    } else {
        int minute =  (int)_playSeconds / 60;
        int seconds = (int)_playSeconds % 60;
        self.playTimeLabel.text = [NSString stringWithFormat:@"%02d:%02d", minute, seconds];
    }
    
    self.duringSlider.value = _playSeconds/_duringSeconds;
}

- (IBAction)capture:(id)sender {
    UIImage *image = [_player capturePicture:100];
    [self saveImageToPhotosAlbum:image];
}

- (IBAction)localButtonClicked:(id)sender {
    // 结束本地录像
    if (self.localRecordButton.selected) {
        [_player stopLocalRecordExt:^(BOOL ret) {
            
            NSLog(@"%d", ret);
            
            [_recordTimer invalidate];
            _recordTimer = nil;
            self.localRecordLabel.hidden = YES;
            [self saveRecordToPhotosAlbum:_filePath];
            _filePath = nil;
        }];
    } else {
        //开始本地录像
        _filePath = [NSString stringWithFormat:@"%@/ezopensdk/EzvizLocalRecord/%@.mp4", kPathDocument, [[NSDate date] formattedDateWithFormat:@"yyyyMMddHHmmss"]];
        [FCFileManager createFileAtPath:_filePath overwrite:YES];
        
        self.localRecordLabel.text = @"  00:00";
        
        if (!_recordTimer) {
            _recordTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerStart:) userInfo:nil repeats:YES];
        }
        
        [_player startLocalRecordWithPathExt:_filePath];
        
        self.localRecordLabel.hidden = NO;
        _seconds = 0;
    }
    self.localRecordButton.selected = !self.localRecordButton.selected;
}

- (void)timerStart:(NSTimer *)timer {
    NSInteger currentTime = ++_seconds;
    self.localRecordLabel.text = [NSString stringWithFormat:@"  %02d:%02d", (int)currentTime/60, (int)currentTime % 60];
    if (!_orangeLayer) {
        _orangeLayer = [CALayer layer];
        _orangeLayer.frame = CGRectMake(10.0, 8.0, 8.0, 8.0);
        _orangeLayer.backgroundColor = [UIColor dd_hexStringToColor:@"0xff6000"].CGColor;
        _orangeLayer.cornerRadius = 4.0f;
    }
    if (currentTime % 2 == 0) {
        [_orangeLayer removeFromSuperlayer];
    } else {
        [self.localRecordLabel.layer addSublayer:_orangeLayer];
    }
}

- (IBAction)showToolBar:(id)sender {
    if (!_isShowToolbox) {
        _isShowToolbox = YES;
        [UIView animateWithDuration:0.3 animations:^{
            self.playerToolbox.alpha = 1.0f;
        }];
        [self performSelector:@selector(hiddenPlayerToolbox:) withObject:nil afterDelay:5.0f];
    } else {
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(hiddenPlayerToolbox:) object:nil];
        [self hiddenPlayerToolbox:nil];
    }
}

- (IBAction)hiddenPlayerToolbox:(id)sender {
    [UIView animateWithDuration:0.3
                     animations:^{
                         self.playerToolbox.alpha = 0.0f;
                     }
                     completion:^(BOOL finished) {
                         _isShowToolbox = NO;
                     }];
}

- (void)doCloudSearch {
    __weak typeof(self) weakSelf = self;
    [EZOPENSDK searchRecordFileFromCloud:self.info.deviceSerial
                                cameraNo:self.info.cameraNo
                               beginTime:self.beginTime
                                 endTime:self.endTime
                              completion:^(NSArray *cloudRecords, NSError *error) {
                                  
                                  [weakSelf.records removeAllObjects];
                                  weakSelf.isSelectedDevice = NO;
                                  
                                  if (!cloudRecords || cloudRecords.count == 0) {
                                      [weakSelf.loadingView stopSquareClockwiseAnimation];
                                      [EZToast show:NSLocalizedString(@"message_file_search_fail", @"文件查询失败")];
                                  }
                                  
                                  [weakSelf.records addObjectsFromArray:cloudRecords];
                                  [weakSelf doPlayFirst];
                              }];
}

#pragma mark - Private Methods 其他私有方法

/** 将图片保存到相册 */
- (void)saveImageToPhotosAlbum:(UIImage *)savedImage {
    UIImageWriteToSavedPhotosAlbum(savedImage, self, @selector(imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:), NULL);
}

/** 将录像保存到相册 */
- (void)saveRecordToPhotosAlbum:(NSString *)path {
    UISaveVideoAtPathToSavedPhotosAlbum(path, self, @selector(imageSavedToPhotosAlbum:didFinishSavingWithError:contextInfo:), NULL);
}

// 指定回调方法
- (void)imageSavedToPhotosAlbum:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
    NSString *message = nil;
    if (!error) {
        message = NSLocalizedString(@"device_save_gallery", @"已保存至手机相册");
    } else {
        message = [error description];
    }
    [EZToast show:message];
}

#pragma mark - ValidateCode Methods

- (void)showSetPassword {
    [UIAlertController showAlertWithDeviceSerial:self.deviceInfo.deviceSerial confirmBlock:^(NSString * _Nonnull code) {
        [self.player setPlayVerifyCode:code];
        [self doPlayFirst];
    }];
}

- (void)showRetry {
    [UIAlertController showDeviceSerialRetryAlert:^{
        [self showSetPassword];
    }];
}

@end
