//
//  ICRQuestionBaseViewController.m
//  XFFruit
//
//  Created by Xummer on 15/6/2.
//  Copyright (c) 2015年 Xummer. All rights reserved.
//

#import "ICRQuestionBaseViewController.h"

#import "ICRQuestionManager.h"
#import "IBTImagePicker.h"
#import "ICRAttachmentView.h"
#import "ICRStoreResult.h"
#import "IBTFileManager.h"
#import "JTRecordView.h"
#import "ICRTask.h"
#import "ICRPostTask.h"
#import "ICRAttachment.h"
#import "ICRPostAttachment.h"

#import "JTImagePreviewer.h"

#import "ICRQSingleSelectViewController.h"
#import "ICRQMutiSelectViewController.h"
#import "ICRQAViewController.h"
#import "ICRQScoreViewController.h"
#import "ICRQStoreStudyViewController.h"
#import "ICRQReseachViewController.h"
#import "ICRQStarViewController.h"

#import "ICRQResultViewController.h"
#import "ICRPatrolResultViewController.h"
#import "ICRTaskEditViewController.h"

#define F_GAP   (5)

const CGFloat m_fMaxAudioRecoderDuration = 58;
const CGFloat m_fMinAudioRecoderDuration = 1;

@interface ICRQuestionBaseViewController ()
<
    IBTImagePickerDelegate,
    ICRTaskEditViewDelegate,
    UITextFieldDelegate
>
{
    BOOL m_bIsLoaded;
}

@property (nonatomic, strong) JTRecordView *m_recordView;

@end

@implementation ICRQuestionBaseViewController

#pragma mark - Life Cycle

- (instancetype)initWithQuestion:(ICRQuestion *)question
                          answer:(ICRAnswer *)answer
{
    
    switch (question.type) {
        case kICRQestionTypeSingleSel:
            self = [[ICRQSingleSelectViewController alloc] init];
            break;
        case kICRQestionTypeMultipleSel:
            self = [[ICRQMutiSelectViewController alloc] init];
            break;
        case kICRQestionTypeReply:
            self = [[ICRQAViewController alloc] init];
            break;
        case kICRQestionTypeScore:
            self = [[ICRQScoreViewController alloc] init];
            break;
        case kICRQestionTypeStoreInv:
            self = [[ICRQStoreStudyViewController alloc] init];
            break;
        case kICRQestionTypeSpeciesInv:
            self = [[ICRQReseachViewController alloc] init];
            break;
        case kICRQestionTypeStarNum:
            self = [[ICRQStarViewController alloc] init];
            break;
        default:
            self = [super init];
            break;
    }
    
    if (!self) {
        return nil;
    }
    
    self.m_question = question;
    self.m_answer = answer;
    
    [self setupDefaultAnswer];
    
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"seq" ascending:YES];
//    self.m_arrOptions = [self.m_question.options sortedArrayUsingDescriptors:@[sort]];
    
    [self setupSubviews];
    
    [self registerForKVO];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    
    if (!m_bIsLoaded) {
        m_bIsLoaded = YES;
        if (_m_answer.photo) {
            ICRPostAttachment *pPic = [ICRPostAttachment DBObject];
            [pPic praseFromJsonDict:_m_answer.photo];
            
            NSData *imageData = [NSData dataFromBase64String:pPic.content];
            UIImage *image = [UIImage imageWithData:imageData];
            
            [self addAttachment:image];
        }
        
        if (_m_answer.task) {
            ICRPostTask *pTask = [ICRPostTask DBObject];
            [pTask praseFromLocalDict:_m_answer.task];
            
            [self addAttachment:pTask];
        }
        
        if (_m_answer.voice) {
            ICRPostAttachment *pVoice = [ICRPostAttachment DBObject];
            [pVoice praseFromJsonDict:_m_answer.voice];
            
            NSData *voiceData = [NSData dataFromBase64String:pVoice.content];
            
            [self addAttachment:voiceData];
        }

    }
}

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

- (void)disMissSelf {
    
    [IBTLoadingView showProgressLabel:@"正在保存..."];
    
    ICRQuestionManager *mgr = [ICRQuestionManager sharedManager];
    ICRStoreResult *storeR = [mgr getStoreResult];
    
    [storeR saveToDBWithHandleData:NULL
                          complete:^{
                              [IBTLoadingView hideHUDWithText:nil];
                              [super disMissSelf];
                              [ICRQuestionManager sharedManager].m_patrolPlan = nil;
                              
                          }
                              fail:^(NSError *error) {
                                  
                                  [IBTLoadingView hideHUDWithText:error.localizedDescription];
                              }];
    
}

- (void)dealloc {
    [self unregisterFromKVO];
}

#pragma mark - Private Method
- (void)setupSubviews {
    
    self.view.backgroundColor = [UIColor colorWithR:240 g:246 b:255 a:1];
    
    self.m_titleLabel = [[IBTUILabel alloc] init];
    _m_titleLabel.numberOfLines = 0;
    _m_titleLabel.font = [UIFont boldSystemFontOfSize:18];
    _m_titleLabel.textColor = [UIColor grayColor];

    _m_titleLabel.text = [NSString stringWithFormat:@"%@.%@",@(self.m_question.type+ 1),self.m_question.title];
    
    CGFloat fMargin = 15.0f;
    CGSize size = CGSizeMake(self.view.width - 2 * fMargin,CGFLOAT_MAX);
    size = [self.m_titleLabel widthLimitedSizeThatFits:size];
    _m_titleLabel.frame = (CGRect){
        .origin.x = fMargin,
        .origin.y = F_GAP,
        .size = size
    };
    
    CGFloat fHeight = 300;
    self.m_helperView = [[ICRQuestionHelperView alloc] initWithFrame:(CGRect){
        .origin.x = 0,
        .origin.y = self.view.height - fHeight,
        .size.width = self.view.width,
        .size.height = fHeight
    }];
    _m_helperView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
    [_m_helperView.m_photoAttachView.m_addButton addTarget:self
                                                    action:@selector(onShowImagePicker:)
                                          forControlEvents:UIControlEventTouchUpInside];
    
    [_m_helperView.m_taskAttachView.m_addButton addTarget:self
                                                   action:@selector(onAddTask:)
                                         forControlEvents:UIControlEventTouchUpInside];
    
    [_m_helperView.m_voiceAttachView.m_addButton addTarget:self
                                                    action:@selector(onStartRecord:)
                                          forControlEvents:UIControlEventTouchDown | UIControlEventTouchDownRepeat];
    [_m_helperView.m_voiceAttachView.m_addButton addTarget:self
                                                    action:@selector(onEndRecord:)
                                          forControlEvents:UIControlEventTouchUpInside|UIControlEventTouchDragOutside];
    
    _m_helperView.m_inputTxtF.delegate = self;
    
    [_m_helperView.m_nextBtn addTarget:self
                                action:@selector(onNextBtnAction:)
                      forControlEvents:UIControlEventTouchUpInside];
    
    [self initScrollViewWithRect:(CGRect){
        .origin.x = 0,
        .origin.y = _m_titleLabel.bottom + F_GAP,
        .size.width = self.view.width,
        .size.height = self.view.height - _m_titleLabel.bottom - F_GAP
    }];
    
    [self.m_contentScrollView autoresizingWithStrechFullSize];
    [self.m_contentScrollView setContentInsetTop:0 andBottom:_m_helperView.top];
    
    [self.view addSubview:_m_titleLabel];
    [self.view addSubview:_m_contentScrollView];
    [self.view addSubview:_m_helperView];
}

- (void)initScrollViewWithRect:(CGRect)rect {
    IBTUIScrollView *scrollV = [[IBTUIScrollView alloc] initWithFrame:rect];
    scrollV.bHandleKeyboard = YES;
    self.m_contentScrollView = scrollV;
}

- (void)openEditTaskView:(ICRTask *)task
{
    ICRQuestionManager *mgr = [ICRQuestionManager sharedManager];
    
    ICRTaskEditViewController *tVC =
    [[ICRTaskEditViewController alloc] initWithTask:task store:mgr.m_store];
    tVC.m_delegate = self;
    [self PushViewController:tVC animated:YES];
}

- (void)addAttachment:(id)oAtt {
    
    SEL selector = NULL;
    
    UIImage *iconImg;
    ICRAttachmentView *attachView = nil;
    
    if ([oAtt isKindOfClass:[ICRPostTask class]]) {
        iconImg = [UIImage imageNamed:@"icon_task_default"];
        selector = @selector(onTapTask:);
        attachView = self.m_helperView.m_taskAttachView;
    }
    else if ([oAtt isKindOfClass:[NSData class]]) {
        iconImg = [UIImage imageNamed:@"icon_voice"];
        selector = @selector(onAttVoicePlay:);
        attachView = self.m_helperView.m_voiceAttachView;
    }
    else if ([oAtt isKindOfClass:[UIImage class]]) {
        iconImg = oAtt;
        selector = @selector(onTapImage:);
        attachView = self.m_helperView.m_photoAttachView;
    }
    
    ICRAttachmentUnit *attV = [[ICRAttachmentUnit alloc] initWithFrame:(CGRect){
        .origin.x = 0,
        .origin.y = 0,
        .size.width = IBT_ATTACH_UNIT_DEFAULT_WIDTH,
        .size.height = IBT_ATTACH_UNIT_DEFAULT_WIDTH
    }];
    [attV updateWithType:kATTCloseBtn masker:nil placeHolder:nil
                   image:iconImg title:nil];
    attV.m_oAttachmentWrap = oAtt;
    
    [attV addTarget:self
             action:selector
   forControlEvents:UIControlEventTouchUpInside];
    
    [attachView addContentAttachmentView:attV];
}

#pragma mark - ICRTaskEditViewDelegate
- (void)taskEditViewCtrl:(ICRTaskEditViewController *)viewCtrl taskData:(id)taskData edit:(BOOL)bEdit
{
    if (bEdit) {
        [self.m_helperView.m_taskAttachView removeContentAttachmentViewAtIndex:0];
    }
    
    ICRPostTask *pTask = taskData;
//    pTask.questionAnswer = _m_answer.mobileId;
    
    self.m_answer.task = [pTask dictForLocalSave];
    
    [self addAttachment:pTask];
    
    [viewCtrl PopViewControllerAnimated:YES];
}

#pragma mark - Action
- (void)onShowImagePicker:(__unused id)sender {
    [[ICRQuestionManager sharedManager].m_imagePicker showImagePickerTitle:nil
                                                                 mediaType:kIBTMediaBImage
                                                                  editable:NO
                                                        fromViewController:self];
}

- (void)onAddTask:(__unused id)sender {
    [self openEditTaskView:nil];
}

- (void)onTapTask:(ICRAttachmentUnit *)unit {
    ICRPostTask *pTask = unit.m_oAttachmentWrap;
    [self openEditTaskView:[ICRTask taskFromPostTask:pTask]];
}

- (void)onTapImage:(ICRAttachmentUnit *)unit {
    
    CGRect rect = [self.view.window convertRect:unit.frame
                                       fromView:unit.superview];
    
    UIImage *img = unit.m_oAttachmentWrap;
    JTImagePreviewer *ipv =
    [[JTImagePreviewer alloc] initWithViewController:self
                                           tempImage:img
                                                 url:nil
                                           startRect:rect];
    [ipv show];
}


- (void)onNextBtnAction:(__unused id)sender {
    ICRQuestionManager *mgr = [ICRQuestionManager sharedManager];
    UIViewController *qVC = [mgr questionViewControlAtIndex:self.m_uiIndex + 1];
    if (qVC) {
        [self PushViewController:qVC animated:YES];
    }
    else {
        // TODO
    }
}

#pragma mark - Public Method

- (void)openResultView {
    [IBTLoadingView showProgressLabel:@"正在保存..."];
    
    ICRQuestionManager *mgr = [ICRQuestionManager sharedManager];
    ICRStoreResult *storeR = [mgr getStoreResult];
    
    __weak typeof(self)weakSelf = self;
    [storeR saveToDBWithHandleData:NULL
                          complete:^{
                              __strong __typeof(weakSelf)strongSelf = weakSelf;
                              [IBTLoadingView hideHUDWithText:nil];
                              ICRQResultViewController *rVC = [[ICRQResultViewController alloc] initWithPatrolPlan:mgr.m_patrolPlan andStoreResult:storeR];
                              [strongSelf PushViewController:rVC animated:YES];
                          }
                              fail:^(NSError *error) {
                                  
                                  [IBTLoadingView hideHUDWithText:error.localizedDescription];
                              }];
}

- (void)setupDefaultAnswer {
    if (!self.m_answer) {
        self.m_answer = [ICRAnswer DBObject];
        self.m_answer.content = @"";
    }
    
    ICRUserUtil *userUtil = [ICRUserUtil sharedInstance];
    self.m_answer.uuid = [userUtil mobileID];
    self.m_answer.questionUuid = self.m_question.qID;
}

#pragma mark - UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    return YES;
}

#pragma mark - IBTImagePickerDelegate
- (void)imagePicker:(IBTImagePickerController *)picker
     didImagePicked:(UIImage *)image referenceURL:(NSURL *)imageUrl {
    IBTFileData *imgFile = [IBTCommon saveImageToLocal:image];
    
//    ICRPostAttachment *attE = [[ICRPostAttachment alloc] init];
//    attE.type = @"answer";
//    attE.objectId = _m_answer.mobileId;
//    attE.filename = imgFile.fileName;
//    attE.content = [imgFile.fileData base64EncodedString];
//    attE.seq = @(1);
//    attE.attachmentType = @"answer";
    
//    self.m_answer.photo = [attE dictForCommit];
    
    [self addAttachment:image];
}

- (void)imagePicker:(IBTImagePickerController *)picker
didVideoPickedWithURL:(NSURL *)videoUrl {
    
}

#pragma mark - KVO

- (void)registerForKVO {
    for (NSString *keyPath in [self observableKeypaths]) {
        [_m_helperView addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:NULL];
    }
}

- (void)unregisterFromKVO {
    for (NSString *keyPath in [self observableKeypaths]) {
        [_m_helperView removeObserver:self forKeyPath:keyPath];
    }
}

- (NSArray *)observableKeypaths {
    return @[ @"frame" ];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    [self.m_contentScrollView setContentInsetTop:0 andBottom:self.view.height - _m_helperView.y];
}

#pragma mark - Keyboard
- (void)keyboardWillShow:(NSNotification *)note {
    // get keyboard size and loctaion
    CGRect keyboardBounds;
    [[note.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue: &keyboardBounds];
    NSNumber *duration = [note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    NSNumber *curve = [note.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey];
    
    // Need to translate the bounds to account for rotation.
    keyboardBounds = [self.view convertRect:keyboardBounds toView:nil];
    
    // animations settings
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:[duration doubleValue]];
    [UIView setAnimationCurve:[curve intValue]];
    
    // set views with new info
    
    if ([_m_helperView.m_inputTxtF isFirstResponder]) {
        _m_helperView.y = self.view.height - CGRectGetHeight(keyboardBounds) - 75;
    }
    
    // commit animations
    [UIView commitAnimations];
}

- (void)keyboardWillHide:(NSNotification *)note {
    NSNumber *duration = [note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    NSNumber *curve = [note.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey];
    
    // animations settings
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:[duration doubleValue]];
    [UIView setAnimationCurve:[curve intValue]];
    
    // set views with new info
    _m_helperView.y = self.view.height - _m_helperView.height;
    
    // commit animations
    [UIView commitAnimations];
}

#pragma mark - Audio

- (void)StartRecording {
    
    ICRQuestionManager *qMgr = [ICRQuestionManager sharedManager];
    if(qMgr.m_oAudioRecorder == nil){
        
        qMgr.m_oAudioRecorder = [[IBTAudioRecorder alloc] init];
        __weak typeof(qMgr)weakMgr = qMgr;
        
        [qMgr.m_oAudioRecorder setFinishRecordingBlock:(^(IBTAudioRecorder* recorder,BOOL success){
            __strong __typeof(weakMgr)strongMgr = weakMgr;
            
            NSString *filePath = [recorder recorderingPath];
            if(strongMgr.m_fRecoderTime >= m_fMinAudioRecoderDuration){
                
                NSData *audioData = [[NSData alloc] initWithContentsOfFile:filePath];
                
                NSString *fileName = [NSString stringWithFormat:@"ICRAUDIO-%@.mp4", [[NSDate date] YMDHMSFormatterString]];
                ICRPostAttachment *attE = [[ICRPostAttachment alloc] init];
//                attE.type = @"answer";
//                attE.objectId = _m_answer.mobileId;
//                attE.filename = fileName;
//                attE.content = [audioData base64EncodedString];
//                attE.seq = @(2);
//                attE.attachmentType = @"answer";
//                
                self.m_answer.voice = [attE dictForCommit];
                
                [self addAttachment:audioData];
            }
            else{
                [IBTCommon runOnMainThreadWithoutDeadlocking:^{
                    [IBTLoadingView showTips:@"录音时间太短"];
                }];
                [self OnAudioEndRecord];
                [IBTFileManager removeFileAtPath:filePath];
            }
        })];
        [qMgr.m_oAudioRecorder setEncodeErrorRecordingBlock:^(IBTAudioRecorder *recorder,NSError *error){
            
            [IBTCommon runOnMainThreadWithoutDeadlocking:^{
                [IBTLoadingView showTips:@"编码错误"];
            }];
            [self OnAudioEndRecord];
        }];
        
        [qMgr.m_oAudioRecorder setReceivedRecordingBlock:^(IBTAudioRecorder *recorder,float peakPower,float averagePower,float currentTime){
            __strong __typeof(weakMgr)strongMgr = weakMgr;
            CLog(@"recording, peakPower = %f,averagePower = %f,currentTime = %f",peakPower,averagePower,currentTime);
            [self UpdateRecordPower:peakPower];
            if (currentTime > 0) {
                strongMgr.m_fRecoderTime = currentTime;
            }
        }];
    }
    
    qMgr.m_fRecoderTime = 0;
    [qMgr.m_oAudioRecorder startRecordForDuration:m_fMaxAudioRecoderDuration];
}

- (void)StopRecording {
    ICRQuestionManager *qMgr = [ICRQuestionManager sharedManager];
    [qMgr.m_oAudioRecorder performSelector:@selector(stopRecord) withObject:nil afterDelay:.2f];
}

- (void)onAttVoicePlay:(id)sender {
    NSData *audioData = [sender valueForKey:@"m_oAttachmentWrap"];
    
    ICRQuestionManager *qMgr = [ICRQuestionManager sharedManager];

    if (!qMgr.m_oAudioPlayer) {
        qMgr.m_oAudioPlayer = [[IBTAVAudioPlayWrapper alloc] init];
    }
    
    __weak typeof(qMgr)weakMgr = qMgr;
    [qMgr.m_oAudioPlayer playWithData:audioData
                         complete:^(BOOL finished, NSError *error) {
                             __strong __typeof(weakMgr)strongMgr = weakMgr;
                             [strongMgr.m_oAudioPlayer stopPlay];
                         }];
}

#pragma mark - Audio Actions
- (void)onStartRecord:(id)sender {
    
    __weak typeof(self)weakSelf = self;
    void(^recordAction)(void) = ^(void) {
        __strong __typeof(weakSelf)strongSelf = weakSelf;
        
        UIButton *btn = strongSelf.m_helperView.m_voiceAttachView.m_addButton;
        if (btn.tracking && btn.touchInside) {
            strongSelf.m_recordView.hidden = NO;
            [strongSelf StartRecording];

        }
    };
    
    [IBTAudioRecorder checkMicrophonePermissionAndRunAction:recordAction];
}

- (void)onEndRecord:(id)sender {
    _m_recordView.hidden = YES;
    [self StopRecording];
}

- (void)OnAudioEndRecord {
    _m_recordView.hidden = YES;
}

- (void)UpdateRecordPower:(float)power {
    
    if (_m_recordView.hidden) {
        return;
    }
    
    // 10^-160  ~  10^0
    NSUInteger waveLevel = 1;
    if (power < (1.0f/4.0f)) {
        waveLevel = 1;
    }
    else if (power < (2.0f/4.0f)) {
        waveLevel = 2;
    }
    else if (power < (3.0f/4.0f)) {
        waveLevel = 3;
    }
    else {
        waveLevel = 4;
    }
    
    [_m_recordView updateWithWavePower:waveLevel];
}

@end
