//
//  uploadFileManager.m
//  隐私保护
//
//  Created by xd h on 2023/11/15.
//

#import "uploadFileManager.h"
#import <AssetsLibrary/AssetsLibrary.h>

@implementation uploadFileManager
static uploadFileManager * cur_uploadFileShareInstance = nil;
+(uploadFileManager *)shareInstance;
{
    static dispatch_once_t onceToken;
    
    dispatch_once(&onceToken, ^{
        cur_uploadFileShareInstance = [[uploadFileManager alloc] init];
        
    });
    
    return cur_uploadFileShareInstance;
}

- (id)init
{
    self = [super init];
    
    if (self) {
        //[self initManager];
    }
    
    return self;
}

#pragma mark 读取数据库数据
- (void)getDataInDatabaseFun:(BOOL)isReGet complete:(custom_complete_Arr)complete
{
    if(_databaseArr && _databaseArr.count == 3 && !isReGet){
        complete(_databaseArr);
        return;
    }
    
    _databaseArr = [NSMutableArray new];
    
    KWeakSelf
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
        [uploadFileDataModel bg_findAsync:upLoadFile_image_tableName limit:0 orderBy:nil desc:YES complete:^(NSArray * _Nullable array) {
            NSMutableArray *failArr = [NSMutableArray new];
            NSMutableArray *doneArr = [NSMutableArray new];
            NSMutableArray *otherArr = [NSMutableArray new];
            
                for (uploadFileDataModel * curModel in array) {
                    
                    //图片 和视频 还原
                    if(curModel.curUploadFileType == uploadFileTypeImage){
                        NSString*pathStr = [cachesFileManager getFilePathWithName:curModel.filename type:uploadFileTypeImage];
                        curModel.imageData = [NSData dataWithContentsOfFile:pathStr];
                    }
                    else if(curModel.curUploadFileType == uploadFileTypeVideo){
                        NSString*pathStr = [cachesFileManager getFilePathWithName:curModel.videoFirstImageName type:uploadFileTypeImage];
                        curModel.imageData = [NSData dataWithContentsOfFile:pathStr];
                        
                        if(curModel.curUploadStateType != uploadStateDone){
                            NSString*videoPathStr = [cachesFileManager getFilePathWithName:curModel.filename type:uploadFileTypeVideo];
                            //curModel.videoData = [NSData dataWithContentsOfFile:videoPathStr];
                        }
                    }
                    
                    if(curModel.curUploadStateType == uploadStateFail){
                        [failArr addObject:curModel];
                    }
                    else if(curModel.curUploadStateType == uploadStateDone){
                        [doneArr addObject:curModel];
                    }
                    else{
                        [otherArr addObject:curModel];
                    }
                }
            
            [self->_databaseArr addObject:otherArr];
            [self->_databaseArr addObject:doneArr];
            [self->_databaseArr addObject:failArr];
            
            complete(self->_databaseArr);
        }];
    });

}

//把TZAssetModel 转成 我们需要上传的model
- (void)handlTZAssetModelToUploadFileDataFunBy:(NSMutableArray*)indexPathsForSelectedItems complete:(custom_complete_Arr)complete
{
    
    if(!indexPathsForSelectedItems && indexPathsForSelectedItems.count == 0){
        return;
    }
    
    if(!_fileModelDataArr){
        _fileModelDataArr = [NSMutableArray new];
    }
    
    self.curUploadModelNumbers = indexPathsForSelectedItems.count;
    
    for (TZAssetModel * model in indexPathsForSelectedItems) {
        uploadFileDataModel * curModel = [uploadFileDataModel new];
        curModel.asset = model.asset;
        curModel.localIdentifier = model.asset.localIdentifier;
        
        curModel.imageData = model.imageData;
        curModel.videoData = model.videoData;
        curModel.filename = [model.asset valueForKey:@"filename"];
        curModel.curUploadStateType = uploadStateWait;
        
        if(model.type == TZAssetModelMediaTypeVideo){
            curModel.curUploadFileType = uploadFileTypeVideo;
            [cachesFileManager getFileNameWithContent:curModel.videoData fileName:curModel.filename type:uploadFileTypeVideo];
            
            
            //curModel.totalBytes = [model.videoData length];
            curModel.totalBytes = model.totalBytes;
            curModel.videoData = [NSData new];//视频文件存储到文件后内存清空
            
            NSString *imgName1 = [curModel.filename stringByReplacingOccurrencesOfString:@"." withString:@"_"];
            curModel.videoFirstImageName = [[NSString alloc] initWithFormat:@"%@.png",imgName1];
           
            //第一帧图片
            [[PHImageManager defaultManager] requestImageDataForAsset:curModel.asset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
                    // 直接得到最终的 NSData 数据
                    if (imageData) {
                        curModel.imageData = imageData;
                        [cachesFileManager getFileNameWithContent:curModel.imageData fileName:curModel.videoFirstImageName type:uploadFileTypeImage];;
                    }
            }];

            //真正的视频数据
            PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
            options.version = PHVideoRequestOptionsVersionOriginal;
            [[PHImageManager defaultManager] requestAVAssetForVideo:curModel.asset options:options resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {
                if ([asset isKindOfClass:[AVURLAsset class]]) {
                    
                    AVURLAsset* urlAsset = (AVURLAsset*)asset;
                    NSData *videoData = [NSData dataWithContentsOfURL:urlAsset.URL];
               
                    if (videoData) {
                        curModel.videoData = videoData;
                        [cachesFileManager getFileNameWithContent:curModel.videoData fileName:curModel.filename type:uploadFileTypeVideo];
                        curModel.videoData = nil;
                    }
             }
            }];

        }
        else{
            curModel.curUploadFileType = uploadFileTypeImage;
            curModel.totalBytes = model.totalBytes;
            
            if(curModel.imageData)
            {
                [cachesFileManager getFileNameWithContent:curModel.imageData fileName:curModel.filename type:uploadFileTypeImage];
            }
            else{
                
                [[PHImageManager defaultManager] requestImageDataForAsset:curModel.asset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
                        // 直接得到最终的 NSData 数据
                        if (imageData) {
                            curModel.imageData = imageData;
                            [cachesFileManager getFileNameWithContent:curModel.imageData fileName:curModel.filename type:uploadFileTypeImage];;
                        }
                }];
            }
           
        }
        
        
        //[_fileModelDataArr addObject:curModel];
        
        //保存到数据库
        curModel.bg_tableName = upLoadFile_image_tableName;
        
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
            [curModel bg_saveOrUpdateAsync:^(BOOL isSuccess) {
                HLog(@"%@ 写入 %@", curModel.filename, isSuccess ? @"成功":@"失败");
            }];
        });
        
    }
    
    KWeakSelf
    //if(_fileModelDataArr.count > 0){
        
        [self getDataInDatabaseFun:YES complete:^(NSMutableArray * _Nonnull Arr) {
            complete(Arr);
            [weakSelf handleUploadFileModelBg_idFun:Arr];
        }];
        
        //骚操作 重新查出来 拿到bg_id
//        [uploadFileDataModel bg_findAsync:upLoadFile_image_tableName limit:_fileModelDataArr.count orderBy:nil desc:YES complete:^(NSArray * _Nullable array) {
//
//            for (int i=0; i<array.count; i++) {
//                uploadFileDataModel *bg_mod  = array[i];
//
//                for (uploadFileDataModel *data_mod in self->_fileModelDataArr) {
//                    if([data_mod.filename isEqualToString:bg_mod.filename]){
//                        data_mod.bg_id = bg_mod.bg_id;
//                        //HLog(@"bg_id:%@",data_mod.bg_id);
//                        break;
//                    }
//                }
//            }
//
//            [weakSelf beginUploadFileFun];
//        }];
        
    //}
}

#pragma mark 处理当前的model 加上bg_id
- (void)handleUploadFileModelBg_idFun:(NSMutableArray*)totalArr
{
    if(!totalArr || totalArr.count != 3){
        return;
    }
    
    NSMutableArray *curArr = totalArr[0];
    
    for (int i=0; i<_curUploadModelNumbers; i++) {
       uploadFileDataModel *bg_mod  = curArr[i];
        [_fileModelDataArr addObject:bg_mod];
   }
    
//    for (int i=0; i<_fileModelDataArr.count; i++) {
//       uploadFileDataModel *bg_mod  = _fileModelDataArr[i];
//
//       for (uploadFileDataModel *data_mod in curArr) {
//           if([data_mod.filename isEqualToString:bg_mod.filename]){
//               bg_mod.bg_id = data_mod.bg_id;
//               //HLog(@"bg_id:%@",data_mod.bg_id);
//               break;
//           }
//       }
//   }
    
    [self beginUploadFileFun];
}

- (void)beginUploadFileFun
{
    if(_isUploadIngType){
        return;
    }
    
    _isSuspendType = NO;
    _isUploadIngType = YES;
    
    _curUploadFileDataModel = _fileModelDataArr.firstObject;
    
    if(!_curUploadFileDataModel){
        return;
    }
    
    
    if(_curUploadFileDataModel.curUploadFileType == uploadFileTypeImage){
        NSString*pathStr = [cachesFileManager getFilePathWithName:_curUploadFileDataModel.filename type:_curUploadFileDataModel.curUploadFileType];
        _curUploadFileDataModel.imageData = [NSData dataWithContentsOfFile:pathStr];
        
        if(_curUploadFileDataModel.imageData && _curUploadFileDataModel.imageData.length >0){
            
            [[NSNotificationCenter defaultCenter] postNotificationName:uploadFileBeginNotification object:_curUploadFileDataModel];
            return;
        }
        
    }
    else{
        NSString*pathStr = [cachesFileManager getFilePathWithName:_curUploadFileDataModel.filename type:uploadFileTypeVideo];
        NSData *curdata = [NSData dataWithContentsOfFile:pathStr];
        
        if(curdata && curdata.length >0){
            curdata = nil;
            
            [[NSNotificationCenter defaultCenter] postNotificationName:uploadFileBeginNotification object:_curUploadFileDataModel];
            return;
        }
    }
    
    
    if(!_curUploadFileDataModel.asset){
        NSString *curLocalIdentifier = _curUploadFileDataModel.localIdentifier;
        PHFetchResult *fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[curLocalIdentifier] options:nil];
        PHAsset *asset = fetchResult.firstObject;
        _curUploadFileDataModel.asset = asset;
    }
    
    if(!_curUploadFileDataModel.asset){
        [self getDataWrongToChangeFailFun];
        return;
    }
    
    KWeakSelf
    if(_curUploadFileDataModel.curUploadFileType == uploadFileTypeImage)
    {
        if(!_curUploadFileDataModel.imageData || _curUploadFileDataModel.imageData.length == 0){
            [[PHImageManager defaultManager] requestImageDataForAsset:_curUploadFileDataModel.asset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
                    // 直接得到最终的 NSData 数据
                    if (imageData) {
                        self->_curUploadFileDataModel.imageData = imageData;
                        [weakSelf  afterGetImageDataFun];
                    }
                    else{
                        [weakSelf getDataWrongToChangeFailFun];
                    }
            }];
        }
    }
    else if(_curUploadFileDataModel.curUploadFileType == uploadFileTypeVideo){
        
        //第一帧图片
        [[PHImageManager defaultManager] requestImageDataForAsset:_curUploadFileDataModel.asset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
                // 直接得到最终的 NSData 数据
                if (imageData) {
                    self->_curUploadFileDataModel.imageData = imageData;
                    [weakSelf  afterGetImageDataInVideoFun];
                }
        }];

        //真正的视频数据
        PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
        options.version = PHVideoRequestOptionsVersionOriginal;
        [[PHImageManager defaultManager] requestAVAssetForVideo:_curUploadFileDataModel.asset options:options resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {
            if ([asset isKindOfClass:[AVURLAsset class]]) {
                
                AVURLAsset* urlAsset = (AVURLAsset*)asset;
                NSData *videoData = [NSData dataWithContentsOfURL:urlAsset.URL];
           
                if (videoData) {
                    self->_curUploadFileDataModel.videoData = videoData;
                    [weakSelf  afterGetVideoDataFun];
                }
                else{
                    [weakSelf getDataWrongToChangeFailFun];
                }
         }
        }];

    }
}

#pragma mark 获取数据失败 报错
- (void)getDataWrongToChangeFailFun
{
    [self changeUploadFileState:uploadStateFail withDidUploadBytes:_curUploadFileDataModel.didUploadBytes withModel:_curUploadFileDataModel complete:^(BOOL isSuccess) {
    }];
}

#pragma mark 根据 asset 获取到图片数据
- (void)afterGetImageDataFun
{
    [cachesFileManager getFileNameWithContent:_curUploadFileDataModel.imageData fileName:_curUploadFileDataModel.filename type:uploadFileTypeImage];
    
    [[NSNotificationCenter defaultCenter] postNotificationName:uploadFileBeginNotification object:_curUploadFileDataModel];
}

- (void)afterGetImageDataInVideoFun
{
    [cachesFileManager getFileNameWithContent:_curUploadFileDataModel.imageData fileName:_curUploadFileDataModel.videoFirstImageName type:uploadFileTypeImage];
}

- (void)afterGetVideoDataFun
{
    [cachesFileManager getFileNameWithContent:_curUploadFileDataModel.videoData fileName:_curUploadFileDataModel.filename type:uploadFileTypeVideo];
    
    _curUploadFileDataModel.videoData = nil;
    
    [[NSNotificationCenter defaultCenter] postNotificationName:uploadFileBeginNotification object:_curUploadFileDataModel];
}

//修改文件上传的状态
- (void)changeUploadFileState:(uploadStateType)curUploadStateType withDidUploadBytes:(long)didUpLoadBytes withModel:(uploadFileDataModel*)model  complete:(custom_complete_B)complete
{
    if(model.bg_id.integerValue == _curUploadFileDataModel.bg_id.integerValue){
        _curUploadFileDataModel.curUploadStateType = curUploadStateType;
        _curUploadFileDataModel.didUploadBytes = didUpLoadBytes;
    }
    model.curUploadStateType = curUploadStateType;
    model.didUploadBytes = didUpLoadBytes;
    
    
    if(!_isSuspendType || curUploadStateType == uploadStateSuspend){
        [[NSNotificationCenter defaultCenter] postNotificationName:uploadFileRefreshNotification object:model];
    }
    
    if(curUploadStateType == uploadStateUploading){
        return;
    }
   
    
    //NSNumber * numberUploadState = nil;
    NSString* where = nil;
    
//    if(curUploadStateType == uploadStateDone)
//    {//只有上传中的才可能是完成的
//        numberUploadState =  [NSNumber numberWithInt:uploadStateUploading];
//        where = [NSString stringWithFormat:@"where %@=%@ and %@=%@ ",bg_sqlKey(@"filename"),bg_sqlValue(_curUploadFileDataModel.filename),bg_sqlKey(@"curUploadStateType"),bg_sqlValue(numberUploadState)];
//    }
//    else
//    {//查找非上传完成的
//        numberUploadState =  [NSNumber numberWithInt:uploadStateDone];
//        where = [NSString stringWithFormat:@"where %@=%@ and %@!=%@ ",bg_sqlKey(@"filename"),bg_sqlValue(_curUploadFileDataModel.filename),bg_sqlKey(@"curUploadStateType"),bg_sqlValue(numberUploadState)];
//    }
    
    where = [NSString stringWithFormat:@"where %@=%@ ",bg_sqlKey(@"bg_id"),bg_sqlValue(model.bg_id)];
    //HLog(@"ffff:%@",_curUploadFileDataModel.bg_id);
    
    [uploadFileDataModel bg_findAsync:upLoadFile_image_tableName where:where complete:^(NSArray * _Nullable array) {
        for (uploadFileDataModel * curModel in array) {
            curModel.curUploadStateType = curUploadStateType;
            curModel.didUploadBytes = didUpLoadBytes;
            
            if(curUploadStateType == uploadStateDone){
                curModel.videoData = [NSData new];
                
                if(curModel.curUploadFileType == uploadFileTypeVideo){
                    [cachesFileManager removeItemAtPath:curModel.filename type:uploadFileTypeVideo error:nil];
                }
                
            }
            else if(curUploadStateType == uploadStateFail){
                
            }
            
            [curModel bg_saveOrUpdateAsync:^(BOOL isSuccess) {
                HLog(@"%@ 写入 %@", model.filename, isSuccess ? @"成功":@"失败");
            }];
            
        }
        
        complete(YES);
    }];
    

}

//暂停上传完成
- (void)suspendUploadFileFun:(BOOL)isSuspendAll
{
//    if(isSuspendAll){
//
//    }
    
    if(!_fileModelDataArr || !_curUploadFileDataModel){
        return;
    }
    
    _isSuspendType = YES;
    _isUploadIngType = NO;
    
    [[NSNotificationCenter defaultCenter] postNotificationName:uploadFileSuspendNotification object:nil];
    
    NSEnumerator *curArr = [_fileModelDataArr reverseObjectEnumerator];
    for (uploadFileDataModel*model in curArr) {
        HLog(@"111hxd 2 %@ ",_fileModelDataArr)

        [self changeUploadFileState:uploadStateSuspend withDidUploadBytes:model.didUploadBytes withModel:model complete:^(BOOL isSuccess) {
            
        }];
    }
    
}

//某个文件重新上传
- (void)reUploadFileFunBy:(NSMutableArray*)Arr
{
    if(!_fileModelDataArr){
        _fileModelDataArr = [NSMutableArray new];
    }
    [_fileModelDataArr addObjectsFromArray:Arr];
    [self beginUploadFileFun];
}

- (void)uploadFileDoneFun
{
    long totalSizeByte = _curUploadFileDataModel.totalBytes;
    
    [self changeUploadFileState:uploadStateDone withDidUploadBytes:totalSizeByte withModel:_curUploadFileDataModel complete:^(BOOL isSuccess) {
        [self->_fileModelDataArr removeObject:self->_curUploadFileDataModel];
         
        self->_isUploadIngType = NO;
        if(self->_fileModelDataArr.count > 0){
            [self beginUploadFileFun];
        }
    }];
}

//文件上传失败
- (void)uploadFileFailFun
{
    [self changeUploadFileState:uploadStateFail withDidUploadBytes:_curUploadFileDataModel.didUploadBytes withModel:_curUploadFileDataModel complete:^(BOOL isSuccess) {
        [self->_fileModelDataArr removeObject:self->_curUploadFileDataModel];
         
        if(self->_fileModelDataArr.count > 0){
            [self beginUploadFileFun];
        }
        else{
            self->_isUploadIngType = NO;
        }
    }];
    
    mainBlock(^{
        [[iToast makeText:NSLocalizedString(@"File_upload_fail",nil)] show];
    });
}

//删除本地数据库记录
- (void)deleteUploadFileRecordBy:(NSMutableArray *)delArr complete:(custom_complete_B)complete
{
    //逻辑待优化
    BOOL isSuc = false;
    for (uploadFileDataModel *uploadFileDataMod in delArr) {
        
        NSMutableString* where = [[NSMutableString alloc] initWithString:@"where "];
        
        NSString *curStr =  [NSString stringWithFormat:@"%@=%@ ",bg_sqlKey(@"bg_id"),bg_sqlValue(uploadFileDataMod.bg_id)];
        [where appendString:curStr];
        isSuc = [uploadFileDataModel bg_delete:upLoadFile_image_tableName where:where];
        
        //删除本地图片
        if(isSuc){
            if(uploadFileDataMod.curUploadFileType == uploadFileTypeVideo){
                [cachesFileManager removeItemAtPath:uploadFileDataMod.videoFirstImageName type:uploadFileTypeImage error:nil];
                
                [cachesFileManager removeItemAtPath:uploadFileDataMod.filename type:uploadFileTypeVideo error:nil];
            }
            else{
                [cachesFileManager removeItemAtPath:uploadFileDataMod.filename type:uploadFileTypeImage error:nil];
            }
            
        }
    }
    
    complete(isSuc);
    
    //继续下一个
    if(_fileModelDataArr){
        [_fileModelDataArr removeObject:_curUploadFileDataModel];
        _isUploadIngType = NO;
        if(_fileModelDataArr.count >=1){
            [self beginUploadFileFun];
        }
    }
    
}

@end
