//
//  CODownloadObject.m
//  classonline
//
//  Created by hyz on 2019/2/25.
//  Copyright © 2019 offcn. All rights reserved.
//

#import "CODownloadObject.h"
#import "BPFileManager.h"
#import "BPDownloadContent.h"
#import "BPNetWorkService.h"
#import "CODownloadCell.h"
#import "WXCOMacros.h"
#import "WXCOUtility.h"
#import "CODownloadManager.h"

@interface CODownloadObject ()

@end

@implementation CODownloadObject

#pragma mark - Init

- (instancetype)initWithDownloadObject:(CODownloadModel *)downloadModel {
    if (self = [super init]) {
        _downloadModel = downloadModel;
        _toastTip = YES;
        
        // 扩展下载类型时，记得在这里实现具体的【初始化下载对象时】处理逻辑
        if ([downloadModel checkInsideDownloaderCanDownloadLessonType]) {
            if (WXCOIsNilOrNull(downloadModel.file_name) == YES || downloadModel.file_name.length <= 0) {
                //pdf文件后缀和视频文件后缀区分
                downloadModel.file_name = [NSString stringWithFormat:@"%@.%@", [self getUUID],
                                           downloadModel.lesson_type == COLessonTypePdf ? @"pdf" : @"dat"];
            } else {
                downloadModel.current_size = (NSInteger)[BPFileManager getLengthForFilePath:[downloadModel
                                                                                             getLocalDownloadFullPath]];
            }
            [downloadModel updateModel2Database]; // 更新数据库数据
        } else if (downloadModel.lesson_type == COLessonTypePlayback) {
            // 以后有其他回放下载时，记得对downloadModel模型数据做扩展
            if (self.downloadModel.live_type == COLiveTypeOffcnLive) {
                [self addOffcnLiveDownloadDelegate];
                downloadModel.current_size = [self getOffcnLiveDownloadedSize];
                NSInteger totalSize = [self getOffcnLiveDownloadedTotalSize];
                if (totalSize > 0) {
                    self.downloadModel.total_size = totalSize;
                }
            }
        }
    }
    return self;
}

#pragma mark - Public Methods

- (NSURL *)getDownloadedFileUrl {
    return [NSURL fileURLWithPath:[self.downloadModel getLocalDownloadFullPath]];
}

- (void)downloadStart:(BOOL)now {
    DownloadState preState = self.downloadModel.down_state;
    if (now == YES) {
        // 如果已经下载完成，并且文件已经全部下载完成
        if ([self.downloadModel checkDownloadComplete] && self.downloadModel.current_size >= self.downloadModel.total_size) {
            self.downloadModel.down_state = stateCompleted;
            self.downloadModel.down_date = [WXCOUtility getTimeNow];
            [[CODownloadManager sharedInstance] co_syncDownRecordForDownloadModel:self.downloadModel];
            [[CODownloadManager sharedInstance] co_completeDownload:self];
        }
        else {
            self.downloadModel.down_state = stateDownloading;
        }
    }
    else {
        self.downloadModel.down_state = stateWaiting;
    }
    
    [self.downloadModel updateModel2Database]; // 更新数据库数据
    if (self.downloadModel.down_state == stateDownloading && preState != stateDownloading) {
        // 开启下载
        [self processDownloadUrl:self.downloadModel.down_url toLocal:[self.downloadModel getLocalDownloadFullPath]
                         inState:self.downloadModel.down_state];
    }
    
    [self willUpdateDownloadView];
}

- (void)downloadPause:(BOOL)force {
    [self downloadPause:force withChangeDownloadState:YES];
}

- (void)downloadPause:(BOOL)force withChangeDownloadState:(BOOL)change {
    if (change == YES) {
        DownloadState preState = self.downloadModel.down_state;
        // 如果是被强制暂停的，则进入等待下载，否则认为是用户手动操作的暂停。不管是哪个状态都要让出下载通道
        self.downloadModel.down_state = force ? stateWaiting : statePaused;
        if (preState == stateDownloading) {
            // 暂停该对象的下载
            [self processDownloadUrl:self.downloadModel.down_url toLocal:[self.downloadModel getLocalDownloadFullPath]
                             inState:self.downloadModel.down_state];
        }
        
        [self willUpdateDownloadView];
        [self.downloadModel updateModel2Database]; // 更新数据库数据
    } else {
        // 扩展下载类型时，记得在这里实现具体的【暂停下载】处理逻辑，这里只做暂停下载操作，不改变下载状态
        if (self.downloadModel.down_state == stateDownloading) {
            if ([self.downloadModel checkInsideDownloaderCanDownloadLessonType]) {
                [[BPNetWorkService shared] cancelUrlString:self.downloadModel.down_url];
            } else if (self.downloadModel.lesson_type == COLessonTypePlayback) {
                // 以后有其他回放下载时，记得对downloadModel模型数据做扩展
                if (self.downloadModel.live_type == COLiveTypeOffcnLive) {
                    [self pauseOffcnLiveDownload];
                }
            }
        }
    }
}

- (void)downloadRemoveWithUserID:(NSString *)userID {
    // 扩展下载类型时，记得在这里实现具体的【移除下载】处理逻辑
    if ([self.downloadModel checkInsideDownloaderCanDownloadLessonType]) {
        // 可能文件仍在下载过程中，先中断
        [[BPNetWorkService shared] cancelUrlString:self.downloadModel.down_url];
        NSLog(@"准备删除\n源文件：%@", [self getDownloadedFileUrl]);
        NSError *error;
        NSFileManager *fileManager = [NSFileManager defaultManager];
        if ([fileManager fileExistsAtPath:[self.downloadModel getLocalDownloadFullPath]] == YES) { //如果本地缓存文件存在
            [fileManager removeItemAtURL:[self getDownloadedFileUrl] error:&error]; //移除本地存储文件
        }
        if (error != nil) {
            NSLog(@"删除出错 ：%@", error);
        }
    } else if (self.downloadModel.lesson_type == COLessonTypePlayback) {
        // 以后有其他回放下载时，记得对downloadModel模型数据做扩展
        if (self.downloadModel.live_type == COLiveTypeOffcnLive) {
            [self deleteOffcnLiveDownload];
        }
    }
    
    for (id<CODownloadObjectDelegate> delegate in self.allCellDelegates) {
        if ([delegate respondsToSelector:@selector(downloadWillBeRemoved)]) {
            [delegate downloadWillBeRemoved];
        }
    }

    // 抛出更新可下载的ViewController UI信息
    if (self.downloadVcDelegate != nil &&
        [self.downloadVcDelegate respondsToSelector:@selector(updateDownloadTipView)]) {
        [self.downloadVcDelegate downloadWillBeRemoved];
    }

    if (self.downloadDelegate != nil &&
        [self.downloadDelegate respondsToSelector:@selector(updateDownloadTipView)]) {
        [self.downloadDelegate downloadWillBeRemoved];
    }

    
    // 清除所有代理关系
    [self.allCellDelegates removeAllObjects];
    // 移除本地记录下载信息
    [self.downloadModel deleteModelFromDatabaseWithUserID:userID];
}

- (void)addDownloadCellDelegate:(CODownloadCell *)delegateCell {
    if (delegateCell == nil || [delegateCell isKindOfClass:[CODownloadCell class]] == NO) {
        return;
    }
    
    BOOL find = NO;
    
    if (self.allCellDelegates.count > 0) {
        if ([self.allCellDelegates containsObject:delegateCell] == YES) { // 数组中包含该cell
            find = YES;
        } else {
            NSMutableArray *cellArray = [NSMutableArray arrayWithCapacity:self.allCellDelegates.count];
            for (CODownloadCell *downloadCell in self.allCellDelegates) {
                if ([downloadCell.cellIdentify isEqualToString:delegateCell.cellIdentify] == YES) { // 查找cell标识相同的对象
                    [cellArray addObject:downloadCell];
                }
            }
            // 移除之前关联到的cell对象
            for (CODownloadCell *downloadCell in cellArray) {
                [self.allCellDelegates removeObject:downloadCell];
            }
        }
    }
    
    if (find == NO) {
        [self.allCellDelegates addObject:delegateCell];
    }
}

- (void)removeDownloadCellDelegate:(CODownloadCell *)delegateCell {
    if ([self.allCellDelegates containsObject:delegateCell] == YES) {
        [self.allCellDelegates removeObject:delegateCell];
    } else {
        NSMutableArray *cellArray = [NSMutableArray arrayWithCapacity:self.allCellDelegates.count];
        for (CODownloadCell *downloadCell in self.allCellDelegates) {
            if ([downloadCell.cellIdentify isEqualToString:delegateCell.cellIdentify] == YES) { // 查找cell标识相同的对象
                [cellArray addObject:downloadCell];
            }
        }
        // 移除之前关联到的cell对象
        for (CODownloadCell *downloadCell in cellArray) {
            [self.allCellDelegates removeObject:downloadCell];
        }
    }
}

- (void)removeDownloadCellDelegateByCellIdentify:(NSString *)cellIdentify {
    if (WXCOIsNilOrNull(cellIdentify) == YES || cellIdentify.length <= 0) {
        return;
    }

    if (self.allCellDelegates.count > 0) {
        NSMutableArray *cellArray = [NSMutableArray arrayWithCapacity:self.allCellDelegates.count];
        for (CODownloadCell *downloadCell in self.allCellDelegates) {
            if ([downloadCell.cellIdentify isEqualToString:cellIdentify] == YES) {
                [cellArray addObject:downloadCell];
                break;
            }
        }
        
        // 移除之前关联到的cell对象
        for (CODownloadCell *downloadCell in cellArray) {
            [self.allCellDelegates removeObject:downloadCell];
        }
    }
}

- (void)againDownloadForFileLose {
    // 扩展下载类型时，记得在这里实现具体的【文件是否丢失】处理逻辑
    if (self.downloadModel.down_state == stateCompleted) {
        BOOL fileExists = YES;
        if ([self.downloadModel checkInsideDownloaderCanDownloadLessonType]) {
            NSFileManager *fileManager = [NSFileManager defaultManager];
            if ([fileManager fileExistsAtPath:[self.downloadModel getLocalDownloadFullPath]] == NO) {
                fileExists = NO;
            }
        } else if (self.downloadModel.lesson_type == COLessonTypePlayback) {
            // 以后有其他回放下载时，记得对downloadModel模型数据做扩展
            if (self.downloadModel.live_type == COLiveTypeOffcnLive) {
                if ([self checkOffcnLiveCompleteDownload] == NO) {
                    fileExists = NO;
                }
            }
        }
        
        // 文件丢失
        if (fileExists == NO) {
            self.downloadModel.down_state = stateInterupt;
            [self.downloadModel updateModel2Database];
            [self willUpdateDownloadView];
        }
    }
}

- (BOOL)downloadInteruptRemoveLocalFile {
    if ([self.downloadModel checkInsideDownloaderCanDownloadLessonType] == YES) {
        NSError *error;
        NSFileManager *fileManager = [NSFileManager defaultManager];
        if ([fileManager fileExistsAtPath:[self.downloadModel getLocalDownloadFullPath]] == YES) { //如果本地缓存文件存在
            [fileManager removeItemAtURL:[self getDownloadedFileUrl] error:&error]; //移除本地存储文件
        }
        if (error != nil) {
            NSLog(@"删除出错 ：%@", error);
            return NO;
        }
    }
    
    return YES;
}

#pragma mark - Private Methods

/// 根据下载状态处理下载操作
/// @param url 下载地址
/// @param localPath 本地缓存路径
/// @param state 下载对象所处于的下载状态
- (void)processDownloadUrl:(NSString *)url toLocal:(NSString *)localPath inState:(DownloadState)state {
    switch (state) {
        case stateDownloading:
        {
            // 扩展下载类型时，记得在这里实现具体的【下载】处理逻辑
            if ([self.downloadModel checkInsideDownloaderCanDownloadLessonType] == YES) {
                [self startBreakPointDownloadURL:url toLocal:localPath];
            } else if (self.downloadModel.lesson_type == COLessonTypePlayback) {
                // 以后有其他回放下载时，记得对downloadModel模型数据做扩展
                if (self.downloadModel.live_type == COLiveTypeOffcnLive) {
                    [self startOffcnLiveDownload];
                }
            }
        }
            break;
        case stateWaiting:
        case statePaused:
        {
            // 扩展下载类型时，记得在这里实现具体的【暂停下载】处理逻辑
            if ([self.downloadModel checkInsideDownloaderCanDownloadLessonType] == YES) {
                if (WXCOIsNilOrNull(url) == NO && url.length > 0) {
                    [[BPNetWorkService shared] cancelUrlString:url];
                }
            } else if (self.downloadModel.lesson_type == COLessonTypePlayback) {
                // 以后有其他回放下载时，记得对downloadModel模型数据做扩展
                if (self.downloadModel.live_type == COLiveTypeOffcnLive) {
                    [self pauseOffcnLiveDownload];
                }
            }
        }
            break;
        case stateCompleted:
            [[NSNotificationCenter defaultCenter] postNotificationName:NotiUpdateDownloadInfo object:nil];
            break;
            // 以下状态暂不需要处理
        case stateNoDownload:
        case stateInterupt:
        default:
            break;
    }
}

/// 开启断点续传下载
/// @param url 下载地址
/// @param localPath 本地缓存路径
- (void)startBreakPointDownloadURL:(NSString *)url toLocal:(NSString *)localPath {
    if (WXCOIsNilOrNull(url) == YES || WXCOIsNilOrNull(localPath) == YES || url.length <= 0 || localPath.length <= 0) {
        return;
    }
    
    dispatch_async(dispatch_get_main_queue(), ^{
        [[UIApplication sharedApplication] setIdleTimerDisabled:YES]; //屏幕保持常亮
    });
    @try {
        __weak typeof(self) weakSelf = self;
        BPDownloadContent *aContent = [[BPDownloadContent alloc] init];
        aContent.urlString = url;
        aContent.cacheFilePath = localPath;
        [[BPNetWorkService shared] downloadContent:aContent onProgress:^(int64_t completeBytes, int64_t totalBytes) {
            weakSelf.downloadModel.current_size = (NSInteger)completeBytes;
            if (weakSelf.downloadModel.total_size <= 0 && totalBytes > 0) { // 第一次接收到数据时保存数据到数据库
                weakSelf.downloadModel.total_size = (NSInteger)totalBytes;
                [weakSelf.downloadModel updateModel2Database]; // 更新数据库数据
            } else {
                weakSelf.downloadModel.total_size = (NSInteger)totalBytes;
            }

            dispatch_async(dispatch_get_main_queue(), ^{
                [weakSelf willUpdateDownloadView];
            });
        } onComplete:^(BPDownloadContent* aContent, NSError *error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [[UIApplication sharedApplication] setIdleTimerDisabled:NO]; //自动锁屏
            });
            
            if (error == nil && weakSelf.downloadModel.total_size > 0) {
                NSLog(@"操作完成\n已存储：%@", aContent.cacheFilePath);
                weakSelf.downloadModel.down_state = stateCompleted;
                weakSelf.downloadModel.down_date = [WXCOUtility getTimeNow];
                [[CODownloadManager sharedInstance] co_syncDownRecordForDownloadModel:weakSelf.downloadModel];
            }
            else if (error.code == -999) { }  // 取消或暂停
            else if (error.code == -1005) { } // 网络连接已中断 在网络切换时发生
            else if (error.code == -1009) { } // 似乎已断开与互联网的连接 在断网时发生
            else {
                weakSelf.downloadModel.down_state = stateInterupt;
                NSLog(@"Download Error: %@", error);
            }
            [[CODownloadManager sharedInstance] co_completeDownload:weakSelf];
            [weakSelf.downloadModel updateModel2Database]; // 更新数据库数据
            // 下载完成更新下载中的列表
            if (weakSelf.downloadModel.down_state == stateCompleted) {
                [[NSNotificationCenter defaultCenter] postNotificationName:NotiUpdateDownloadInfo object:nil];
            }
            dispatch_async(dispatch_get_main_queue(), ^{
                [weakSelf willUpdateDownloadView];
            });
        }];
    } @catch (NSException *exception) { }
}

/// 获取UUID
/// @return 返回一个唯一识别码
- (NSString *)getUUID {
    CFUUIDRef uuid_ref = CFUUIDCreate(NULL);
    CFStringRef uuid_string_ref= CFUUIDCreateString(NULL, uuid_ref);
    CFRelease(uuid_ref);
    
    NSString *uuid = [NSString stringWithString:(NSString*)CFBridgingRelease(uuid_string_ref)];
    return uuid;
}

/// 将要更新有关下载的视图
- (void)willUpdateDownloadView {
    // 抛出更新下载cell的UI信息
    for (id<CODownloadObjectDelegate> delegate in self.allCellDelegates) {
        if ([delegate respondsToSelector:@selector(updateCells)]) {
            [delegate updateCells];
        }
    }
    
    // 抛出更新可下载的ViewController UI信息
    if (self.downloadVcDelegate != nil &&
        [self.downloadVcDelegate respondsToSelector:@selector(updateDownloadTipView)]) {
        [self.downloadVcDelegate updateDownloadTipView];
    }

    // 抛出更新可下载的view UI信息
    if (self.downloadDelegate != nil &&
        [self.downloadDelegate respondsToSelector:@selector(updateDownloadTipView)]) {
        [self.downloadDelegate updateDownloadTipView];
    }


}

#pragma mark - getter setter

- (NSMutableArray <CODownloadCell *> *)allCellDelegates {
    if (_allCellDelegates == nil) {
        _allCellDelegates = [NSMutableArray arrayWithCapacity:10];
    }
    return _allCellDelegates;
}

//- (VodDownLoader *)vodDownloader {
//    if (_vodDownloader == nil) {
//        _vodDownloader = [[VodDownLoader alloc] init];
//        _vodDownloader.delegate = self;
//    }
//    return _vodDownloader;
//}


////////////////////////////////////////////////////////////////////////////////////
/// framework add
/// implement in category
- (void)addOffcnLiveDownloadDelegate {
    
}

/// 获取回放已下载的文件大小
/// @return 已下载的大小
- (NSInteger)getOffcnLiveDownloadedSize {
    return 0;
}

/// 获取回放的文件总大小
/// @return 回放文件总大小
- (NSInteger)getOffcnLiveDownloadedTotalSize {
    return 0;
}

/// 开启中公直播回放下载
- (void)startOffcnLiveDownload {
    
}

/// 暂停中公直播回放下载
- (void)pauseOffcnLiveDownload {
    
}

/// 删除中公直播回放下载
- (void)deleteOffcnLiveDownload {
    
}

/// 检测中公直播回放是否下载完成
/// @return 是否已下载完成
- (BOOL)checkOffcnLiveCompleteDownload {
    return YES;
}

/// new add
+ (void)removeAllOffcnLiveDownloadDelegate {
    
}

/// 检测中公直播回放是否下载完成
/// @param passwordStr 回放口令码
/// @return 是否已下载完成
+ (BOOL)checkOffcnLiveCompleteDownload:(NSString *)passwordStr {
    return YES;
}

@end
