//
//  RecordingPresenter.swift
//  ylgamehall
//
//  录音 UI 呈现器：组装 VoiceRecorder + RecordingOverlay + RecordingAwareWindow
//  三方协作，对外暴露单一 `start` 入口。
//
//  内部职责：
//   1. 创建 VoiceRecorder 启动录音
//   2. 把 RecordingOverlay 挂载到 hostVC.view 全屏覆盖
//   3. 注册 RecordingAwareWindow.touchObserver 监听松手
//   4. 触发松手 / 60s 自动停 → recorder.stop → onFinish → 清理 overlay +
//      observer
//
//  调用方（Phase 3.E prepareaudio handler）：
//   ```swift
//   let fileName = VoiceRecorder.currentTimeString()
//   try RecordingPresenter.start(on: hostVC, fileName: fileName) { wavURL, _ in
//       // 录音完成；调用方负责后续转码 / 上传 / 反向 callback
//   }
//   ```
//

import UIKit
import SwiftUI

public enum RecordingPresenter {

    /// 当前进行中会话；同时只能有一个录音
    private static var active: ActiveSession?

    /// 启动录音 + 显示浮层 + 注册触摸监听。
    ///
    /// 若已有进行中会话，会先 `cancel()` 旧的再开新的（防御性，正常流程下
    /// 不应发生——H5 prepareaudio 不会在录音中再次调用）。
    ///
    /// - Throws: VoiceRecorder.RecorderError，调用方应捕获并向用户提示
    public static func start(
        on hostVC: UIViewController,
        fileName: String,
        onFinish: @escaping (URL, TimeInterval) -> Void
    ) throws {
        // 防御：清理任何遗留会话
        cancelActive()

        let recorder = VoiceRecorder()

        try recorder.start(fileName: fileName) { wavURL, duration in
            // 完成回调：清理 UI + observer，转发给业务
            Self.teardown()
            onFinish(wavURL, duration)
        }

        // 挂载 overlay 到 hostVC.view 全屏覆盖
        let overlayHost = UIHostingController(rootView: RecordingOverlay(recorder: recorder))
        overlayHost.view.backgroundColor = .clear
        hostVC.addChild(overlayHost)
        overlayHost.view.translatesAutoresizingMaskIntoConstraints = false
        hostVC.view.addSubview(overlayHost.view)
        NSLayoutConstraint.activate([
            overlayHost.view.topAnchor.constraint(equalTo: hostVC.view.topAnchor),
            overlayHost.view.bottomAnchor.constraint(equalTo: hostVC.view.bottomAnchor),
            overlayHost.view.leadingAnchor.constraint(equalTo: hostVC.view.leadingAnchor),
            overlayHost.view.trailingAnchor.constraint(equalTo: hostVC.view.trailingAnchor),
        ])
        overlayHost.didMove(toParent: hostVC)

        active = ActiveSession(recorder: recorder, overlayHost: overlayHost)

        // 注册触摸观察：任一 touch ended/cancelled → 停止录音
        RecordingAwareWindow.touchObserver = { [weak recorder] event in
            guard let recorder, let touches = event.allTouches else { return }
            let anyEnded = touches.contains {
                $0.phase == .ended || $0.phase == .cancelled
            }
            if anyEnded {
                recorder.stop()
            }
        }
    }

    /// 外部强制取消（如 H5 业务退出 / 应用切到后台）。
    public static func cancelActive() {
        active?.recorder.cancel()
        teardown()
    }

    private static func teardown() {
        active?.removeOverlay()
        active = nil
        RecordingAwareWindow.touchObserver = nil
    }

    private struct ActiveSession {
        let recorder: VoiceRecorder
        let overlayHost: UIHostingController<RecordingOverlay>

        func removeOverlay() {
            overlayHost.willMove(toParent: nil)
            overlayHost.view.removeFromSuperview()
            overlayHost.removeFromParent()
        }
    }
}
