/*
 Copyright (c) 2020 Swift Models Generated from JSON powered by http://www.json4swift.com

 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

 For support, please feel free to contact me at https://www.linkedin.com/in/syedabsar

 */

import Foundation
import AVFoundation
import ObjectMapper
import RealmSwift
import BFCommonKit

public class PQEditSectionModel: PQEditBaseModel {
    @objc dynamic public var addAutoEffect: Int = 0
    @objc dynamic public var sectionDuration: Float64 = 0 {
        didSet {
            BFLog(message: "sectionDuration == \(sectionDuration)")
        }
    }

    @objc dynamic public var projectTimelineIn: Float64 = 0
    @objc dynamic public var projectTimelineOut: Float64 = 0
    // 段落序号globle 全是0  nomoal 从1开始++ XXXXXX(已经通过TransformOf处理过，代码中使用时都是从0开始就 OK )
    @objc dynamic public var sectionIndex: Int = 0 {
        didSet {
            BFLog(message: "sectionIndex is \(sectionIndex)")
        }
    }

    @objc dynamic public var sectionText: String = "" {
        didSet {
          BFLog(message: "文字发生了改变")
  
        }
    }

    @objc dynamic public var sectionTimeline: PQEditSectionTimelineModel? {
        didSet {}
    }

    @objc dynamic public var sectionType: String = "normal"

    // pc
    @objc dynamic public var sectionExtData: PQEditSectionExtDataModel?

    // add by ak 业务逻辑层要使用的属性 -----------
    public var textIsChane: Bool = false

    // 是否为选中状态 选中状态有三种，0未选中状态 1 设置状态 2，播放状态
    public var isSelected: Int = 0
    // 是否为可设置状态
    public var enabledSetting: Bool = true
    // 是否可添加段
    public var enableAdd: Bool = true
    // 当前段选择的发音人数据
    public var selectVoice: PQVoiceModel?

    // 每一段的封面
    public var coverImage: UIImage?
    // 声音文件地址
    public var audioFilePath: String = "" {
        didSet {
            if (sectionTimeline?.visionTrack?.getEnableVisionTrackMaterials().count ?? 0) > 0 {
                sectionDuration = allStickerAptDuration()
            } else {
                if audioFilePath.count > 0 {
                    let audioAsset = AVURLAsset(url: URL(fileURLWithPath: documensDirectory + audioFilePath), options: nil)
                    sectionDuration = Float64(audioAsset.duration.seconds)
                }
            }
        }
    }

    // 谁长用谁功能，如果视觉长会拼接空音频文件，这个是拼接后的地址
    public var mixEmptyAuidoFilePath: String = ""

    public var subTitles = List<PQEditSubTitleModel>()

    // 背景音乐数据（可能每一段都会有背景音）
    public var bgmData: PQVoiceModel?

    // 录音人头像，在恢复项目时会有值
    public var audioAvatarUrl: String = ""

    // MARK: - 录音相关属性，不保存sadata 不入库

    // 保存每一个段落所有分段的录音记录
    public var cacheRecorderFiles: [URL] = Array()
    // 录制的小段数
    public var cacheRecorderCount: Int = 0
    // 合并后的地址 并已经转成 MP3  mp3 file path
    public var compliteMP3AudioFile: String = ""
    // 录音声音分贝值
    public var audioPowers: [Int] = Array()
    
    //是否正在文字转换中。。
    public var isConverding: Bool = false

    required convenience public init?(map _: Map) {
        self.init()
    }

    required public init() {
        super.init()

        sectionTimeline = PQEditSectionTimelineModel()
    }

    public override func mapping(map: Map) {
        addAutoEffect <- map["addAutoEffect"]
        sectionDuration <- (map["duration"], timeTransform)
        projectTimelineIn <- (map["projectTimelineIn"], timeTransform)
        projectTimelineOut <- (map["projectTimelineOut"], timeTransform)

        sectionText <- map["sectionText"]
        sectionTimeline <- map["sectionTimeline"]
        sectionType <- map["sectionType"]

        if sectionType != "global" {
            sectionIndex <- (map["sectionIndex"], sectionIndexTransform)
        } else {
            sectionIndex <- map["sectionIndex"]
        }

        sectionExtData <- map["sectionExtData"]

        // 业务逻辑属性
        audioFilePath <- map["audioFilePath"]
        mixEmptyAuidoFilePath <- map["mixEmptyAuidoFilePath"]
        subTitles <- (map["subTitles"], PQListTransform<PQEditSubTitleModel>())
        uniqueId <- map["uniqueId"]
    }

    // 计算所有贴纸的时间 aptDuration 已经是根据有无配音计算好的 可直接使用
   public  func allStickerAptDuration() -> Float64 {
        var stickerAptDuration: Float64 = 0
        if sectionTimeline?.visionTrack?.getEnableVisionTrackMaterials().count ?? 0 > 0 {
            for sticker in (sectionTimeline!.visionTrack?.getEnableVisionTrackMaterials())! {
                stickerAptDuration = stickerAptDuration + Double(lround(sticker.aptDuration))
            }
        }
        return stickerAptDuration
    }

    // 所有内贴纸的时长未4舍5入的
   public  func allStickerAptDurationNoRound() -> Float64 {
        var stickerAptDuration: Float64 = 0
        if sectionTimeline?.visionTrack?.getEnableVisionTrackMaterials().count ?? 0 > 0 {
            for sticker in (sectionTimeline!.visionTrack?.getEnableVisionTrackMaterials())! {
                stickerAptDuration = stickerAptDuration + Double(sticker.aptDuration)
            }
        }
        return stickerAptDuration
    }

    /// 是否已经设置过一个发音人，voice 会在选择时给值，取消选择时清空 init
   public  func haveSelectVoice() -> Bool {
        BFLog(message: "voice?.avatarUrl \(String(describing: selectVoice?.avatarUrl))")
        return selectVoice?.avatarUrl.count ?? 0 > 0
    }

    /// 判断素材是否下载完成，如果本地址没有，就应该是有问题或没有下载完成
    /// - Returns: <#description#>
   public  func matrialIsDownloaded() -> Bool {
        var isDownloaded: Bool = true // 素材是否下载完成
        for sticker in (sectionTimeline!.visionTrack?.getEnableVisionTrackMaterials())! {
            if sticker.locationPath.count == 0 {
                isDownloaded = false
                break
            }
        }
        return isDownloaded
    }

    //  添加字幕信息
   public  func addSubtitleMatraislInfo(subtitls: List<PQEditVisionTrackMaterialsModel>) {
        deleteSubtitleMatraislInfo()

        // 2，添加新的一组字幕
        sectionTimeline!.visionTrack?.visionTrackMaterials.append(objectsIn: subtitls)
    }

    // 删除字幕
   public  func deleteSubtitleMatraislInfo() {
        // 1,确保每一个段落只有一组字幕 先移除老的一组字幕如果有, 只设置有效的素材
        let otherEnableVision = sectionTimeline!.visionTrack?.getEnableVisionTrackMaterials()
        sectionTimeline!.visionTrack?.visionTrackMaterials = otherEnableVision ?? List<PQEditVisionTrackMaterialsModel>.init()
    }

    // 判断当前段落是否有有效素材,1, 有视觉素材，2，有声音数据1）录音2)配音-- audioFilePath (如果是空的声音不算) 3，字幕 1)输入的的 2)录音转的
   public  func haveRes() -> Bool {
        var have: Bool = false
        if subTitles.count > 0 || (sectionTimeline?.visionTrack?.getEnableVisionTrackMaterials().count ?? 0) > 0 || (audioFilePath.count > 0 && !audioFilePath.contains("empty")) || sectionTimeline?.visionTrack?.getSubtitleMatraislInfo().count ?? 0 > 0 || sectionText.count > 0 {
            have = true
        }

        return have
    }

    /* 有一个特殊场景 根据当前段的视觉素材生成空声音文件
     1）所有段没有文字
     2）p1有视觉 p2 有
     3）p1没有预览 ，P2直接点了全览
     这个情况 P1 还没有生成空的文件会导致所有时长不对，贴纸在选择加入的时候已经处理，这里只处理这种 PART 的空声音文件

     */
   public  func generateEmptyAuido() {
        var stickerTotalDuration: Float64 = 0
        // 没有选择发声音人,只有纯视觉的情况
        if sectionText.count == 0, audioFilePath.count == 0, mixEmptyAuidoFilePath.count == 0 {
            BFLog(message: "section index is \(sectionIndex)")
            if !isEmptyObject(object: sectionTimeline?.visionTrack?.getEnableVisionTrackMaterials()) {
                for sticker in sectionTimeline!.visionTrack!.getEnableVisionTrackMaterials() {
                    if sticker.timelineOut == 0, sticker.timelineIn == 0 {
                        stickerTotalDuration = stickerTotalDuration + (sticker.out - sticker.model_in)
                    } else {
                        stickerTotalDuration = stickerTotalDuration + (sticker.timelineOut - sticker.timelineIn)
                    }
                }
            }

            // 创建空的数据
            let tool = PQCreateEmptyWAV(sampleRate: 44100,
                                        channel: 1,
                                        duration: stickerTotalDuration,
                                        bit: 16)
            let timeInterval: TimeInterval = Date().timeIntervalSince1970
            var documentPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! as String
            documentPath.append("/\(timeInterval).wav")
            tool.createEmptyWAVFile(url: URL(fileURLWithPath: documentPath))
           
             audioFilePath = documentPath
             sectionDuration = CMTimeGetSeconds(AVURLAsset(url: URL(fileURLWithPath: documentPath), options: nil).duration)
            BFLog(message: " 生成的空声音 \(String(describing: documentPath))  时长 \(String(describing: sectionDuration))")
            
        }
    }

    // 生成输入状态的可使用的文字信息
   public  func getInputSubtitle() -> String {
        var text: String = ""
        if sectionTimeline?.visionTrack?.getSubtitleMatraislInfo() != nil {
            for subTitleModel in sectionTimeline!.visionTrack!.getSubtitleMatraislInfo() {
                if subTitleModel.subtitleInfo?.text.count ?? 0 > 0 {
                    text = text + (subTitleModel.subtitleInfo?.text ?? "") + "\n"
                }
            }
        }
        return text
    }

    /// 删除录音的缓存 文件，在删除段落时调用
   public  func deleteCacheAudioFiles(isDeleteMergeFile: Bool = false) {
        let fileManger = FileManager.default
        // 删除临时音频文件数据
        // file:///var/mobile/Containers/Data/Application/176BE83D-F514-49EA-8710-8A077CFCFA72/Documents/Resource/ExportAudios/recorder_1614170151.815164_noise.wav
        for url in cacheRecorderFiles {
            if fileManger.fileExists(atPath: url.relativePath) {
                do {
                    try fileManger.removeItem(atPath: url.relativePath)
                    print("\(url.relativePath)Success to remove file.")
                } catch {
                    print("Failed to remove file.")
                }
            }
        }
        cacheRecorderFiles.removeAll()
        // 2 删除合并后的文件
        if isDeleteMergeFile {
            if fileManger.fileExists(atPath: compliteMP3AudioFile) {
                do {
                    try fileManger.removeItem(atPath: compliteMP3AudioFile)
                    print("\(compliteMP3AudioFile)Success to remove file.")
                } catch {
                    print("Failed to remove file.")
                }
            }
        }
        compliteMP3AudioFile = ""
        audioPowers = []
    }
}
