import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js'
import { RectAreaLightUniformsLib } from 'three/examples/jsm/lights/RectAreaLightUniformsLib.js';
import hdri from '@/assets/images/three/hdri.hdr'

interface ModelInfo {
    box: THREE.Box3;
    center: THREE.Vector3;
    size: THREE.Vector3;
    maxSize: number;
}
const CONFIG = {
    hdriIntensity: 7.4,
    exposureBase: 0.92,
    backlightBoost: { min: 2.1, max: 4.8 }, // 背光增强系数
    hdriUrl: hdri,
};
export class ThreeManager {
    threeDom: HTMLElement;
    scene: THREE.Scene;//场景对象
    camera: THREE.PerspectiveCamera;//相机对象
    renderer: THREE.WebGLRenderer;//渲染器对象
    controls: OrbitControls;//轨道控制器对象
	animationId: number | null = null;

    pointLight: THREE.AmbientLight;//环境光对象
    studioLights: any;//工作室光对象数组
	v1: THREE.Vector3;//相机前向向量
	camDir: THREE.Vector3;//相机前向向量
	camForward: THREE.Vector3;//相机前向向量
	camToTarget: THREE.Vector3;//相机目标向量

	currentModel: any;//当前模型对象
	animate: any;//动画对象

    modelInfo: ModelInfo;//模型信息对象
	defaultSoftboxPositions: Array<{ x: number; y: number; z: number; intensity: number; w: number; h: number }> = [
        { x: 0, y: 5.8, z: 3.5, intensity: 3.5, w: 6, h: 4.8 },   // 主光
        { x: 0, y: 2.8, z: 7.5, intensity: 2.2, w: 5, h: 4 },      // 前光
        { x: 0, y: 2.8, z: -7.5, intensity: 6.5, w: 5, h: 4 },     // 背光
        { x: -7.5, y: 2.8, z: 0, intensity: 10.8, w: 5, h: 4 },    // 侧光
        { x: 7.5, y: 2.8, z: 0, intensity: 2.0, w: 5, h: 4 },      // 侧光
        { x: 0, y: -2.2, z: 3, intensity: 0.8, w: 9, h: 4 }        // 地面反光板
    ];
	constructor(threeDom: HTMLElement,config:any = {}){

		this.threeDom = threeDom;
		this.studioLights = []
		//创建场景
		this.scene = new THREE.Scene();
		this.scene.background = new THREE.Color(0xffffff);
		//创建相机
		this.camera = new THREE.PerspectiveCamera(45, threeDom.offsetWidth / threeDom.offsetHeight, 0.1, 10000);
		this.camera.position.set(0, 1.5, 6); //设置相机位置

		this.v1 = new THREE.Vector3();
		this.camDir = new THREE.Vector3();
		this.camForward = new THREE.Vector3();
		this.camToTarget = new THREE.Vector3();
		//设置渲染器
		this.renderer = new THREE.WebGLRenderer({ antialias: true, powerPreference: "high-performance", preserveDrawingBuffer: true });
		//设置环境光
		this.scene.add(new THREE.AmbientLight(0xffffff, 0.15));

		// 关键优化：物理光照与色彩管理
		this.renderer.outputEncoding = THREE.sRGBEncoding;
		this.renderer.toneMapping = THREE.ACESFilmicToneMapping;
		this.renderer.toneMappingExposure = CONFIG.exposureBase;
		this.renderer.physicallyCorrectLights = true; // 开启物理光照模式，光衰减更真实
		this.renderer.setPixelRatio(window.devicePixelRatio);
		this.renderer.setSize(threeDom.offsetWidth, threeDom.offsetHeight); //设置渲染区域尺寸
		this.renderer.setClearColor(0xffffff, 1); //设置背景颜色 
		threeDom.innerHTML = '';
		threeDom.appendChild(this.renderer.domElement);

		RectAreaLightUniformsLib.init();
		//设置轨道控制器
		this.controls = new OrbitControls(this.camera,this.renderer.domElement)//监听鼠标、键盘事件;
		// controls.minDistance = 500; // 设置相机与焦点的最小距离
		// controls.maxDistance = 4000; // 设置相机与焦点的最大距离
		this.controls.mouseButtons = {
			// LEFT:THREE.MOUSE.PAN, // 左键 拖动(默认旋转：ROTATE)
			LEFT:THREE.MOUSE.ROTATE, // 左键 拖动(默认旋转：ROTATE)
			MIDDLE:THREE.MOUSE.DOLLY, // 滑轮 缩放
			RIGHT:THREE.MOUSE.PAN // 右键 旋转（默认拖动：PAN）
			// RIGHT:THREE.MOUSE.ROTAafTE // 右键 旋转（默认拖动：PAN）
		}
		this.controls.enableDamping = true;

	}
	/**
     * 根据模型大小计算自适应配置
     */
    calculateAdaptiveConfig(modelInfo: ModelInfo) {
        const { size, maxSize, center } = modelInfo;
        // 基础距离系数（可根据需要调整）
        let distanceFactor = 1.5;
        // 根据模型形状调整距离系数
        const aspectRatio = size.x / size.y;
        if (aspectRatio > 2) {
            // 扁平模型，拉远一点
            distanceFactor = 3.0;
        } else if (aspectRatio < 0.5) {
            // 高瘦模型，稍微拉近
            distanceFactor = 2.0;
        }
        // 计算相机距离
        const fov = this.camera.fov * (Math.PI / 180);
        const cameraDistance = (maxSize / 2) / Math.tan(fov / 2) * distanceFactor;
        // 灯光缩放系数
        const lightScale = Math.max(0.5, Math.min(2.0, maxSize / 2.5));
        // 强度缩放系数（模型越大，灯光需要越强）
        const intensityScale = Math.max(0.6, Math.min(2.5, maxSize / 2));
        
        console.log('自适应配置:', {
            相机距离: cameraDistance,
            灯光缩放: lightScale,
            强度缩放: intensityScale,
            目标中心: center
        });
        
        return {
            cameraDistance,
            lightScale,
            intensityScale,
            targetCenter: center.clone()
        };
    }
	/**
     * 获取模型信息（包围盒、中心点、尺寸等）
     */
    getModelInfo(model: THREE.Object3D): ModelInfo {
        const box = new THREE.Box3().setFromObject(model);
        const center = box.getCenter(new THREE.Vector3());
        const size = box.getSize(new THREE.Vector3());
        const maxSize = Math.max(size.x, size.y, size.z);
        
        console.log('模型信息:', {
            中心点: center,
            尺寸: { x: size.x, y: size.y, z: size.z },
            最大尺寸: maxSize
        });
        
        return { box, center, size, maxSize };
    }
  	/**
     * 根据模型大小自适应创建柔光箱灯光
     */
	createAdaptiveSoftboxes(modelInfo: ModelInfo) {
		const { lightScale, intensityScale, targetCenter } = this.calculateAdaptiveConfig(modelInfo);
		// 清除现有灯光
		this.studioLights.forEach(item => {
			this.scene.remove(item.light);
		});
		this.studioLights = [];
		
		// 根据模型大小创建自适应灯光
		this.defaultSoftboxPositions.forEach(pos => {
			const scaledX = pos.x * lightScale;
			const scaledY = pos.y * lightScale;
			const scaledZ = pos.z * lightScale;
			const scaledW = pos.w * lightScale;
			const scaledH = pos.h * lightScale;
			const scaledIntensity = pos.intensity * intensityScale;
			
			const light = new THREE.RectAreaLight(0xffffff, scaledIntensity, scaledW, scaledH);
			light.position.set(
				targetCenter.x + scaledX,
				targetCenter.y + scaledY,
				targetCenter.z + scaledZ
			);
			light.lookAt(targetCenter);
			this.scene.add(light);
			
			this.studioLights.push({ 
				light, 
				offset: new THREE.Vector3(scaledX, scaledY, scaledZ), 
				baseIntensity: scaledIntensity 
			});
		});
		console.log('自适应灯光已创建，缩放系数:', lightScale, '强度系数:', intensityScale);
	}
	  /**
     * 根据模型大小调整相机位置
     */
	adjustCameraToModel(modelInfo: ModelInfo) {
		const { cameraDistance, targetCenter } = this.calculateAdaptiveConfig(modelInfo);
		// 正面俯视角度：相机在模型正前方，稍高于模型中心
		// X 轴：模型中心（正面视角，不左右偏移）
		// Y 轴：相机高度 = 模型中心高度 + 模型高度的 0.3 倍（俯视效果）
		// Z 轴：相机距离 = 根据模型大小计算的距离
		const x = targetCenter.x;
		const y = targetCenter.y + modelInfo.size.y * 0.3; // 相机高度为模型中心的 0.3 倍
		const z = targetCenter.z + cameraDistance;
		
		this.camera.position.set(x, y, z);
		this.controls.target.copy(targetCenter);
		this.controls.update();
	}


	createSoftbox(x, y, z, intensity, w = 5, h = 4) {
		const light = new THREE.RectAreaLight(0xffffff, intensity, w, h);
		light.position.set(x, y, z);
		light.lookAt(0, 0, 0);
		this.scene.add(light);
		// 存储 offset 向量副本，避免后续重复创建
		this.studioLights.push({ 
			light, 
			offset: new THREE.Vector3(x, y, z), 
			baseIntensity: intensity 
		});
	}
	async setHDRI(){
		const rgbeLoader = new RGBELoader()
		await rgbeLoader.load(CONFIG.hdriUrl, (texture)=>{
			texture.mapping = THREE.EquirectangularReflectionMapping;
			const pmremGenerator = new THREE.PMREMGenerator(this.renderer);
			const envMap = pmremGenerator.fromEquirectangular(texture).texture;
	
			this.scene.environment = envMap;
			this.scene.environmentIntensity = CONFIG.hdriIntensity;
	
			pmremGenerator.dispose();
			texture.dispose();
			console.log('✅ HDRI Loaded');
		});
		this.createSoftbox(0, 5.8, 3.5, 3.5, 6, 4.8);   // 主光
		this.createSoftbox(0, 2.8, 7.5, 2.2);         // 前光
		this.createSoftbox(0, 2.8, -7.5, 6.5);        // 背光 (增强)
		this.createSoftbox(-7.5, 2.8, 0, 10.8);       // 侧光
		this.createSoftbox(7.5, 2.8, 0, 2.0);
		this.createSoftbox(0, -2.2, 3, 0.8, 9, 4);    // 地面反光板
	}
	// 更新工作室光位置
	updateStudioLighting(){
		this.camera.getWorldDirection(this.camDir);
		this.studioLights.forEach(item => {
			// 使用 applyQuaternion 同步灯光位置
			this.v1.copy(item.offset).applyQuaternion(this.camera.quaternion);
			item.light.position.copy(this.controls.target).add(this.v1);
			item.light.lookAt(this.controls.target);

			// 动态背光逻辑
			if (item.offset.z < -2) {
				this.v1.copy(item.light.position).sub(this.controls.target).normalize();
				const dot = this.v1.dot(this.camDir); 
				const factor = THREE.MathUtils.lerp(CONFIG.backlightBoost.min, CONFIG.backlightBoost.max, Math.max(0, 1 - dot));
				item.light.intensity = item.baseIntensity * factor;
			}
		});
	}
	//动态设置曝光
	updateImagePipeline() {
		let exposure = 1.0;
		this.camera.getWorldDirection(this.camForward);
		this.camToTarget.copy(this.controls.target).sub(this.camera.position).normalize();
		const facing = Math.abs(this.camForward.dot(this.camToTarget));
		const targetExposure = THREE.MathUtils.lerp(1.25, 0.90, facing);
		exposure = THREE.MathUtils.lerp(exposure, targetExposure, 0.08);
		this.renderer.toneMappingExposure = CONFIG.exposureBase * exposure;
	}

	async setModel(modelUrl,load){
    	await new Promise((resolve, reject) => {
			const drac = new DRACOLoader()
			drac.setDecoderPath('/draco/')
			const loader = new GLTFLoader().setDRACOLoader(drac);
			
			if (this.currentModel) {
				this.scene.remove(this.currentModel);
				this.dispose(this.currentModel); // 核心优化：释放显存
			}
			
			loader.load(modelUrl, 
				(gltf) => {
					this.currentModel = gltf.scene;
					
					// 遍历模型：增强材质表现
					this.currentModel.traverse(child => {
						if (child.isMesh) {
							child.castShadow = true;
							child.receiveShadow = true;
							if (child.material) {
								child.material.envMapIntensity = 1.2; // 增强 HDRI 反射强度
							}
						}
					});
			
					const box = new THREE.Box3().setFromObject(this.currentModel);
					const center = box.getCenter(new THREE.Vector3());
					// this.currentModel.position.sub(center);
					this.scene.add(this.currentModel);
					this.modelInfo = this.getModelInfo(this.currentModel)
					 // 根据模型大小调整相机位置
					 this.adjustCameraToModel(this.modelInfo);
                    
					 // 根据模型大小创建自适应灯光
					 this.createAdaptiveSoftboxes(this.modelInfo);
					resolve('')
				},
				(xhr: any) => { // 加载进度回调
					const percent = xhr.total == 0 ? 100 : (xhr.loaded / xhr.total * 100).toFixed(2);
					load.value.progress = percent
					console.log('模型加载进度:', percent);
				},
				(error: any) => { // 加载失败回调
					console.error('模型加载失败:', error);
					resolve('')
				}
			);
		})
	}

	operation(){
		const animate = () => {
            this.animationId = requestAnimationFrame(animate);
            this.controls?.update();
            this.updateStudioLighting();
            this.updateImagePipeline();
            this.renderer?.render(this.scene, this.camera);
        };
        animate();
	}

	// 释放模型资源
	dispose(obj){
		if (!obj) return;
		obj.traverse(node => {
			if (node.isMesh) {
				if (node.geometry) node.geometry.dispose();
				if (node.material) {
					if (Array.isArray(node.material)) {
						node.material.forEach(m => m.dispose());
					} else {
						node.material.dispose();
					}
				}
			}
		});
	}
	disposeModel() {
        console.log('开始销毁 ThreeManager...');
        // 1. 停止动画
        if (this.animationId) {
            cancelAnimationFrame(this.animationId);
            this.animationId = null;
        }
        
        // 2. 销毁控制器
        if (this.controls) {
            this.controls.dispose();
            this.controls = null;
        }
        
        // 3. 销毁模型
        if (this.currentModel) {
            this.dispose(this.currentModel);
            this.scene?.remove(this.currentModel);
            this.currentModel = null;
        }
        
        // 4. 销毁灯光
        if (this.studioLights?.length) {
            this.studioLights.forEach(item => {
                if (item.light) {
                    this.scene?.remove(item.light);
                    item.light.dispose?.();
                }
            });
            this.studioLights = [];
        }
        
        // 5. 清理环境光
        if (this.pointLight) {
            this.scene?.remove(this.pointLight);
            this.pointLight = null;
        }
        
        // 6. 清理场景
        if (this.scene) {
            this.scene.traverse((obj) => {
                if (obj.isMesh) {
                    const mesh = obj as THREE.Mesh;
                    mesh.geometry?.dispose();
                    if (mesh.material) {
                        if (Array.isArray(mesh.material)) {
                            mesh.material.forEach(m => m.dispose());
                        } else {
                            mesh.material.dispose();
                        }
                    }
                }
            });
            
            while (this.scene.children.length) {
                this.scene.remove(this.scene.children[0]);
            }
            this.scene = null;
        }
        
        // 7. 销毁渲染器
        if (this.renderer) {
            this.renderer.dispose();
            if (this.renderer.domElement?.parentNode) {
                this.renderer.domElement.parentNode.removeChild(this.renderer.domElement);
            }
            this.renderer = null;
        }
        
        // 8. 清空 DOM 容器
        if (this.threeDom) {
            this.threeDom.innerHTML = '';
            this.threeDom = null;
        }
        
        // 9. 清空其他引用
        this.camera = null;
        this.v1 = null;
        this.camDir = null;
        this.camForward = null;
        this.camToTarget = null;
        this.modelInfo = null;
        
        console.log('ThreeManager 已销毁');
    }

	exportAsImage(){
		return this.renderer.domElement.toDataURL('image/png');
	}
}