//
//  HomeCenterView.swift
//  Toolboxes
//
//  Created by 研发2组 on 2024/9/23.
//

import SwiftUI
import SceneKit
import CoreMotion

struct CircularLevelView: UIViewRepresentable {
    let motionManager = CMMotionManager()
    let scene = SCNScene()
    
    // 视图的半径为100，因为frame是200x200
    let viewRadius: CGFloat = 25.0
    
    func makeUIView(context: Context) -> SCNView {
        let scnView = SCNView()
        scnView.scene = scene
        scnView.backgroundColor = UIColor.clear
        scnView.allowsCameraControl = false
        scnView.antialiasingMode = .multisampling4X // 开启4倍抗锯齿
        // 创建圆形桌面，使用视图的半径（100）
        let tableRadius: CGFloat = viewRadius / 100.0 // 将视图的半径映射到SCN场景的比例
        
        let table = SCNCylinder(radius: tableRadius, height: 0.01)
        
        let tableMaterial = SCNMaterial()
        tableMaterial.diffuse.contents = UIColor.white
        tableMaterial.transparency = 0.0
        
        table.materials = [tableMaterial]
        let tableNode = SCNNode(geometry: table)
        tableNode.position = SCNVector3(0, 0, 0)
        scene.rootNode.addChildNode(tableNode)
        
        // 创建小球
        let ballRadius: CGFloat = 0.12
        let ball = SCNSphere(radius: ballRadius)
        ball.segmentCount = 64 // 增加细分水平
        let ballNode = SCNNode(geometry: ball)
        ballNode.position = SCNVector3(0, 0.1, 0)
        
        let ballMaterial = SCNMaterial()
        ballMaterial.diffuse.contents = UIColor(.tab_sel)
        ballMaterial.specular.contents = UIColor(.tab_nor)
        ballMaterial.ambient.contents = UIColor.lightGray
        ballMaterial.shininess = 100.0
        ballMaterial.isLitPerPixel = true // 开启逐像素光照
        ballMaterial.isDoubleSided = false // 关闭双面渲染，减少渲染开销
        ball.firstMaterial = ballMaterial
        scene.rootNode.addChildNode(ballNode)
        
        let lightNode = SCNNode()
        lightNode.light = SCNLight()
        lightNode.light?.type = .omni
//        lightNode.light?.intensity = 10000
        lightNode.light?.intensity = 5000 // 降低光照强度，避免过度曝光
        lightNode.position = SCNVector3(x: -1, y: 2, z: -1)
        scene.rootNode.addChildNode(lightNode)
        
        // 添加环境光照
        let ambientLightNode = SCNNode()
        ambientLightNode.light = SCNLight()
        ambientLightNode.light?.type = .ambient
        ambientLightNode.light?.color = UIColor.darkGray
        scene.rootNode.addChildNode(ambientLightNode)
        
        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        cameraNode.position = SCNVector3(0, 2, 0)
        cameraNode.look(at: SCNVector3(0, 0, 0))
        scene.rootNode.addChildNode(cameraNode)
        
        // 开始设备运动数据更新
        startDeviceMotionUpdates(ballNode: ballNode, tableRadius: Float(tableRadius))
        return scnView
    }
    
    func updateUIView(_ uiView: SCNView, context: Context) {}
    
    func startDeviceMotionUpdates(ballNode: SCNNode, tableRadius: Float) {
        if motionManager.isDeviceMotionAvailable {
            motionManager.deviceMotionUpdateInterval = 0.1
            motionManager.startDeviceMotionUpdates(to: .main) { (data, error) in
                guard let data = data else { return }
                let gravity = data.gravity
                
                // 根据重力更新小球位置
                let x = Float(gravity.x) * tableRadius
                let z = Float(gravity.y) * tableRadius
                
                // 计算小球到中心的距离
                let distance = sqrt(x * x + z * z)
                
                // 如果小球超出视图半径，将其位置限制在边界
                var targetPosition: SCNVector3
                if distance >= tableRadius {
                    let angle = atan2(z, x)
                    targetPosition = SCNVector3(cos(angle) * tableRadius, 0.1, sin(angle) * tableRadius)
                } else {
                    targetPosition = SCNVector3(x, 0.1, -z)
                }
                
                // 更新小球的位置
                moveBall(ballNode: ballNode, to: targetPosition)
            }
        }
    }
    
    private func moveBall(ballNode: SCNNode, to targetPosition: SCNVector3) {
        let currentBallPosition = ballNode.position
        let dx = targetPosition.x - currentBallPosition.x
        let dz = targetPosition.z - currentBallPosition.z
        let moveDistance = sqrt(dx * dx + dz * dz)
        
        if moveDistance > 0.001 {
            let moveAction = SCNAction.move(to: targetPosition, duration: 0.1)
            ballNode.runAction(moveAction)
            
            let ballRadius: Float = 0.12
            let rotationAngle = moveDistance / ballRadius
            
            let rollDirection = SCNVector3(dz, 0, -dx).normalized()
            let rotationAction = SCNAction.rotate(by: CGFloat(rotationAngle), around: rollDirection, duration: 0.1)
            ballNode.runAction(rotationAction)
        }
    }
}

extension SCNVector3 {
    func normalized() -> SCNVector3 {
        let length = sqrt(x * x + y * y + z * z)
        return SCNVector3(x / length, y / length, z / length)
    }
}
