//
//  LNVideoCompressor.swift
//  Gami
//
//  Created by OneeChan on 2026/2/28.
//

import Foundation
import AVFoundation


class LNVideoCompressor {
    static func compressVideo(sourceURL: URL, completion: @escaping (URL?) -> Void) {
        DispatchQueue.global().async {
            // 检查源文件是否存在
            guard FileManager.default.fileExists(atPath: sourceURL.path) else {
                showToast(.init(key: "B00014"))
                completion(nil)
                return
            }
            
            // 获取视频资产
            let asset = AVAsset(url: sourceURL)
            
            // 计算目标码率（关键：码率决定文件大小）
            let videoDuration = CMTimeGetSeconds(asset.duration)
            guard videoDuration > 0, videoDuration <= 1 * 60 else {
                showToast(.init(key: "A00299"))
                completion(nil)
                return
            }
            
            guard let videoTrack = asset.tracks(withMediaType: .video).first else {
                showToast(.init(key: "A00298", 10001))
                completion(nil)
                return
            }
            
            do {
                // 创建写入器：指定输出格式为 MP4，并传入流媒体配置
                let outputUrl = getTempVideoURL()
                // 确保临时文件不存在（避免写入冲突）
                if FileManager.default.fileExists(atPath: outputUrl.path) {
                    try FileManager.default.removeItem(at: outputUrl)
                }
                let writer = try AVAssetWriter(outputURL: outputUrl, fileType: .mp4)
                
                // 关键配置：启用 interleaved 写入（确保 moov atom 前置）
                writer.shouldOptimizeForNetworkUse = true // 核心！开启网络优化（流式播放）
                
                // 配置视频编码参数（流媒体核心参数）
                let videoSettings = createCompressionSettings(asset: asset)
                
                // 创建视频输入
                let videoInput = AVAssetWriterInput(mediaType: .video, outputSettings: videoSettings)
                videoInput.expectsMediaDataInRealTime = false
                videoInput.transform = videoTrack.preferredTransform // 保持原视频方向
                guard writer.canAdd(videoInput) else {
                    showToast(.init(key: "A00298", 10002))
                    completion(nil)
                    return
                }
                writer.add(videoInput)
                
                // 创建音频输入
                var audioInput: AVAssetWriterInput?
                if asset.tracks(withMediaType: .audio).first != nil {
                    let audioSettings = [
                        AVFormatIDKey: kAudioFormatMPEG4AAC,
                        AVSampleRateKey: 44100,
                        AVNumberOfChannelsKey: 2,
                        AVEncoderBitRateKey: 128000 // 128Kbps 音频比特率
                    ]
                    let input = AVAssetWriterInput(mediaType: .audio, outputSettings: audioSettings)
                    input.expectsMediaDataInRealTime = false
                    if writer.canAdd(input) {
                        writer.add(input)
                        audioInput = input
                    }
                }
                
                // 创建 AVAssetReader
                let reader = try AVAssetReader(asset: asset)
                
                // 创建视频读取器
                let readerOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: [
                    kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA
                ])
                guard reader.canAdd(readerOutput) else {
                    showToast(.init(key: "A00298", 10003))
                    completion(nil)
                    return
                }
                reader.add(readerOutput)
                
                // 处理音频
                var audioOutput: AVAssetReaderTrackOutput?
                if let audioTrack = asset.tracks(withMediaType: .audio).first {
                    // 音频读取器输出
                    let output = AVAssetReaderTrackOutput(track: audioTrack, outputSettings: [
                        AVFormatIDKey: kAudioFormatLinearPCM
                    ])
                    if reader.canAdd(output) {
                        reader.add(output)
                        audioOutput = output
                    }
                }
                
                // 开始写入
                guard writer.startWriting() else {
                    showToast(.init(key: "A00298", 10004))
                    completion(nil)
                    return
                }
                writer.startSession(atSourceTime: .zero)
                guard reader.startReading() else {
                    showToast(.init(key: "A00298", 10005))
                    completion(nil)
                    return
                }
                
                let dispatchGroup = DispatchGroup()
                // 逐帧处理并写入
                dispatchGroup.enter()
                videoInput.requestMediaDataWhenReady(on: DispatchQueue(label: "com.jiehe.gami.video.compress")) {
                    while videoInput.isReadyForMoreMediaData {
                        if let sampleBuffer = readerOutput.copyNextSampleBuffer() {
                            videoInput.append(sampleBuffer)
                        } else {
                            videoInput.markAsFinished()
                            dispatchGroup.leave()
                            break
                        }
                    }
                }
                // 处理音频
                if let audioInput, let audioOutput {
                    dispatchGroup.enter()
                    audioInput.requestMediaDataWhenReady(on: DispatchQueue(label: "com.jiehe.gami.audio.compress")) {
                        while audioInput.isReadyForMoreMediaData {
                            if let sampleBuffer = audioOutput.copyNextSampleBuffer() {
                                audioInput.append(sampleBuffer)
                            } else {
                                audioInput.markAsFinished()
                                dispatchGroup.leave()
                                break
                            }
                        }
                    }
                }
                
                // 等待完成
                dispatchGroup.notify(queue: .global()) {
                    writer.finishWriting {
                        switch writer.status {
                        case .completed:
                            completion(outputUrl)
                        case .failed:
                            let err = reader.error ?? writer.error
                            showToast("\(err?.localizedDescription ?? "")")
                            completion(nil)
                        default:
                            break
                        }
                    }
                }
            } catch {
                showToast(error.localizedDescription)
                completion(nil)
            }
        }
    }
}

extension LNVideoCompressor {
    /// 创建压缩设置（视频码率、分辨率）
    private static func createCompressionSettings(asset: AVAsset) -> [String: Any] {
        var settings = [String: Any]()
        
        // 获取视频轨道
        guard let videoTrack = asset.tracks(withMediaType: .video).first else {
            return settings
        }
        
        // 视频编码类型
        settings[AVVideoCodecKey] = AVVideoCodecType.h264 // H.264编码（兼容性好）
        
        // 分辨率设置（保持原比例，避免拉伸）
        let naturalSize = videoTrack.naturalSize
        let transform = videoTrack.preferredTransform
        var videoSize = naturalSize
        
//        // 处理旋转
//        if transform.a == 0 && transform.b == 1.0 && transform.c == -1.0 && transform.d == 0 ||
//            transform.a == 0 && transform.b == -1.0 && transform.c == 1.0 && transform.d == 0 {
//            videoSize = CGSize(width: naturalSize.height, height: naturalSize.width)
//        }
        
        // 限制最大分辨率（限制为720P）
        let maxDimension: CGFloat = 720
        let scaleFactor = min(maxDimension / videoSize.width, maxDimension / videoSize.height, 1.0)
        
        let finalWidth = floor(videoSize.width * scaleFactor)
        let finalHeight = floor(videoSize.height * scaleFactor)
        
        // 确保宽高为偶数（H.264要求）
        let outputWidth = finalWidth.truncatingRemainder(dividingBy: 2) == 0 ? finalWidth : finalWidth - 1
        let outputHeight = finalHeight.truncatingRemainder(dividingBy: 2) == 0 ? finalHeight : finalHeight - 1
        
        settings[AVVideoWidthKey] = outputWidth
        settings[AVVideoHeightKey] = outputHeight
        
        // 流媒体关键配置
        settings[AVVideoCompressionPropertiesKey] = [
            // 2. 比特率模式：恒定比特率（CBR），适合流媒体
            AVVideoAverageBitRateKey: 1000000, // 1Mbps
            
            // 3. H.264 配置：兼容流媒体
            AVVideoProfileLevelKey: AVVideoProfileLevelH264Baseline31, // Baseline 级别兼容性更好
            AVVideoAllowFrameReorderingKey: false // 禁止帧重排序，便于流媒体解析
        ]
        
        return settings
    }
    
    /// 获取临时视频文件URL
    private static func getTempVideoURL() -> URL {
        let tempDir = NSTemporaryDirectory()
        let fileName = UUID().uuidString + ".mp4"
        return URL(fileURLWithPath: tempDir).appendingPathComponent(fileName)
    }
}
