//
//  Heise Vision Pro
//  Copyright © 2024 Gero Gerber. All rights reserved.
//

import ARKit
import RealityKit
import SwiftUI

enum CoordinateConversionState {
    case insideVolume
    case fromVolume
    case toImmersive
    case insideImmersiveSpace
    case fromImmersiveSpace
    case toVolume
}

/// Maintains app-wide state
@MainActor
@Observable
class AppModel {
    static let objectTrackingSpaceID = "ObjectTrackingSpace"
    static let directionalLightWindowId = "DirectionalLightAndShadow"
    static let spotLightWindowId = "SpotLightAndShadow"
    static let coordinateConversionSpaceId = "CoordinateConversionSpace"
    static let coordinateConversionWindowId = "CoordinateConversionWindow"
    static let lowLevelMeshWindowId = "LowLevelMeshWindow"

    static let robotScale: SIMD3<Float> = .init(x: 0.018, y: 0.018, z: 0.018)

    var assetsLoaded = false
    var currentImmersiveSpaceID: String?
    var immersiveSpaceIsLoading = false

    var referenceObjects: [UUID: ReferenceObject] = .init()
    var referenceObjectModels: [UUID: Entity] = .init()

    var worldSensingAuthorizationStatus = ARKitSession.AuthorizationStatus.notDetermined

    let volumeRoot = Entity()
    let immersiveRoot = Entity()
    let robot = try! Entity.load(named: "drummer")

    let initialRobotTransform: Transform
    var immersiveSpaceFromRobot = AffineTransform3D()
    var coordianteConverstionState: CoordinateConversionState = .insideVolume

    init() {
        initialRobotTransform = Transform(scale: Self.robotScale, rotation: .init(), translation: .zero)
    }

    func loadAssets() async {
        if ObjectTrackingProvider.isSupported {
            do {
                let referenceObject = try await ReferenceObject(named: "ps5-controller")
                referenceObjects[referenceObject.id] = referenceObject

                if let usdzUrl = referenceObject.usdzFile {
                    let entity = try await Entity(contentsOf: usdzUrl)
                    referenceObjectModels[referenceObject.id] = entity
                }
            } catch {
                print(error)
                return
            }
        }

        assetsLoaded = true
    }
}
