//
//  PlayContoller9.swift
//  tdvideo
//
//  Created by mac on 2024/2/21.
//

/*
 拍摄空间视频
 */
import UIKit
import AVFoundation
import Photos
import AVKit
import VideoToolbox

class PlayContoller9: UIViewController, AVCaptureFileOutputRecordingDelegate {

    //AVCaptureSession --- 单摄像头
    var session = AVCaptureMultiCamSession()//多摄像头
    var wideAngleCameraDeviceInput: AVCaptureDeviceInput?//广角摄像头 .builtInWideAngleCamera
    var ultraWideCameraDeviceInput: AVCaptureDeviceInput?//超广角 .builtInUltraWideCamera
    
    
    var wideAngleCameraVideoPreviewLayer: AVCaptureVideoPreviewLayer?//广角摄像头
    var ultraWideCameraVideoPreviewLayer: AVCaptureVideoPreviewLayer?//超广角
    
    var wideAngleCameraMovieOutput: AVCaptureMovieFileOutput?
    var ultraWideCameraMovieOutput: AVCaptureMovieFileOutput?
    
    
    
    var isRecording = false
    
    
    var startRecordingButton: UIButton?
    
    var leftEyeVideoURL:URL?
    var rightEyeVideoURL:URL?
    var outputVideoURL: URL?

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        outputVideoURL =  URL.documentsDirectory.appendingPathComponent("output.MOV")

        configureSession()
        setupUI()
    }

    private func configureSession() {
        session.beginConfiguration()
        defer {
            session.commitConfiguration()
        }

        // 配置后置摄像头  .builtInWideAngleCamera 广角摄像头(默认设备 --- 主摄，28mm左右焦段)   .back 后置摄像头
        guard let backCamera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) else {
            print("Could not find the back camera")
            return
        }

        do {
            wideAngleCameraDeviceInput = try AVCaptureDeviceInput(device: backCamera)

            guard let wideAngleCameraDeviceInput = wideAngleCameraDeviceInput,
                  session.canAddInput(wideAngleCameraDeviceInput) else {
                print("Could not add back camera input")
                return
            }
            session.addInput(wideAngleCameraDeviceInput)
        } catch {
            print("Could not create back camera device input: \(error)")
            return
        }

        //   .builtInUltraWideCamera  超广角(默认设备的0.5x，只能使用AVCaptureDeviceDiscoverySession获取)    .back 后置摄像头
        guard let frontCamera = AVCaptureDevice.default(.builtInUltraWideCamera, for: .video, position: .back) else {
            print("Could not find the front camera")
            return
        }

        do {
            ultraWideCameraDeviceInput = try AVCaptureDeviceInput(device: frontCamera)

            guard let ultraWideCameraDeviceInput = ultraWideCameraDeviceInput,
                  session.canAddInput(ultraWideCameraDeviceInput) else {
                print("Could not add front camera input")
                return
            }
            session.addInput(ultraWideCameraDeviceInput)
        } catch {
            print("Could not create front camera device input: \(error)")
            return
        }
        
        // 配置音频输入设备
        guard let audioDevice = AVCaptureDevice.default(for: .audio) else {
            print("Could not find audio device")
            return
        }

        do {
            let audioDeviceInput = try AVCaptureDeviceInput(device: audioDevice)

            guard session.canAddInput(audioDeviceInput) else {
                print("Could not add audio input")
                return
            }

            session.addInput(audioDeviceInput)
        } catch {
            print("Could not create audio device input: \(error)")
            return
        }

        // 配置后置摄像头输出
        wideAngleCameraMovieOutput = AVCaptureMovieFileOutput()
        guard let wideAngleCameraMovieOutput = wideAngleCameraMovieOutput,
              session.canAddOutput(wideAngleCameraMovieOutput) else {
            print("Could not add the back camera movie output")
            return
        }
        session.addOutput(wideAngleCameraMovieOutput)

        // 配置前置摄像头输出
        ultraWideCameraMovieOutput = AVCaptureMovieFileOutput()
        guard let ultraWideCameraMovieOutput = ultraWideCameraMovieOutput,
              session.canAddOutput(ultraWideCameraMovieOutput) else {
            print("Could not add the front camera movie output")
            return
        }
        session.addOutput(ultraWideCameraMovieOutput)

        // 配置预览图层
        wideAngleCameraVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
        wideAngleCameraVideoPreviewLayer?.frame = CGRect(x: 0, y: 0, width: view.frame.size.width / 2, height: view.frame.size.height / 2)
        if let wideAngleCameraVideoPreviewLayer = wideAngleCameraVideoPreviewLayer {
            view.layer.addSublayer(wideAngleCameraVideoPreviewLayer)
        }

        ultraWideCameraVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: session)
        ultraWideCameraVideoPreviewLayer?.frame = CGRect(x: view.frame.size.width / 2, y: 0, width: view.frame.size.width / 2, height: view.frame.size.height / 2)
        if let ultraWideCameraVideoPreviewLayer = ultraWideCameraVideoPreviewLayer {
            view.layer.addSublayer(ultraWideCameraVideoPreviewLayer)
        }

        DispatchQueue.global().async {
            self.session.startRunning()
        }
    }

    private func setupUI() {
        startRecordingButton = UIButton(type: .system)
        startRecordingButton?.setTitle("Start Recording", for: .normal)
        startRecordingButton?.setTitleColor(UIColor.brown, for: UIControl.State.normal)
        startRecordingButton?.addTarget(self, action: #selector(toggleRecording(_:)), for: .touchUpInside)
        startRecordingButton?.frame = CGRect(x: 0, y: view.frame.size.height - 250, width: view.frame.size.width, height: 50)
        view.addSubview(startRecordingButton!)
    }

    @objc private func toggleRecording(_ sender: UIButton) {
        if isRecording {
            stopRecording()
        } else {
            startRecording()
        }
    }

    private func startRecording() {
        guard let wideAngleCameraMovieOutput = wideAngleCameraMovieOutput,
              let ultraWideCameraMovieOutput = ultraWideCameraMovieOutput else {
            print("Movie output not configured")
            return
        }

        let time = Date().timeIntervalSince1970
        let name1 = "back" + String(time) + ".mov"
        let name2 = "front" + String(time) + ".mov"
        let backCameraOutputURL = URL.documentsDirectory.appending(path:name1)
        let frontCameraOutputURL = URL.documentsDirectory.appending(path:name2)

        wideAngleCameraMovieOutput.startRecording(to: backCameraOutputURL, recordingDelegate: self)
        ultraWideCameraMovieOutput.startRecording(to: frontCameraOutputURL, recordingDelegate: self)

        isRecording = true
        startRecordingButton?.setTitle("Stop Recording", for: .normal)
    }

    private func stopRecording() {
        guard let wideAngleCameraMovieOutput = wideAngleCameraMovieOutput,
              let ultraWideCameraMovieOutput = ultraWideCameraMovieOutput else {
            print("Movie output not configured")
            return
        }

        wideAngleCameraMovieOutput.stopRecording()
        ultraWideCameraMovieOutput.stopRecording()

        isRecording = false
        startRecordingButton?.setTitle("Start Recording", for: .normal)
    }

    func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
        if let error = error {
            print("Video recording finished with error: \(error.localizedDescription)")
        } else {
            if output == wideAngleCameraMovieOutput {
                print("Back camera video recorded: \(outputFileURL)")
                leftEyeVideoURL = outputFileURL
            } else if output == ultraWideCameraMovieOutput {
                print("Front camera video recorded: \(outputFileURL)")
                rightEyeVideoURL = outputFileURL
            }
            createSpVideo()
        }
    }

    func createSpVideo(){
        
        if(rightEyeVideoURL != nil && leftEyeVideoURL != nil){
            let spatialVideoWriter = SpatialVideoWriter()
            Task {
                spatialVideoWriter.writeSpatialVideo(leftEyeVideoURL: leftEyeVideoURL!, rightEyeVideoURL: rightEyeVideoURL!, outputVideoURL: outputVideoURL!) { success, error in
                    if success {
                        print("空间视频生成成功")
                    } else if let error = error {
                        print("生成空间视频失败：\(error.localizedDescription)")
                    }
                }
            }
        }
    }
}
