import { BaseComponent, ImageTexture } from '@uino/thing';
import { Utils } from '../common/Utils';

// generate gradient
function gradient(reversal) {
	const colorArr = [];
	for (let i = 0; i < 10; i++) {
		let temp = 0;
		if(reversal){
			 temp = i > 1 ? 255 : 0;
		}else{
			 temp = i < 9 ? 255 : 0;
		}
		colorArr.push(...[temp, temp, temp, 255]);
	}
	const imageData = new Uint8Array(colorArr);
	let texture = new THING.ImageTexture({ data: imageData, width: 10, height: 1 });
	texture.wrapType = THING.ImageWrapType.ClampToEdge;

	return texture;
}

let _gradientMap ;
let _reversalGradientMap;
  
/**
 * 线生长动画组件类,用于通过操作UV坐标控制线条的生长动画效果。
 * @class LineGrowthComponent
 * @public
 * @memberof THING
 * @example
 * // 创建并添加组件到线条
 * const line = new THING.RouteLine();
 * const growth = line.addComponent(THING.LineGrowthComponent);
 * 
 * // 控制线可见范围
 * growth.progress = 0.3;  // 隐藏起点30%
 */
class LineGrowthComponent extends BaseComponent {

	/**
	 * 线生长动画组件类构造函数,用于通过操作UV坐标控制线条的生长动画效果。
	 * @constructor
     * @public
	 */
	constructor() {
		super();
		this._objectName = '';
	}

	/**
	 * When add component.
	 * @param {THING.BaseObject} object The object
	 */
	onAdd(object) {
		super.onAdd(object);
		_gradientMap = _gradientMap ? _gradientMap : gradient(false);
		_reversalGradientMap = _reversalGradientMap ? _reversalGradientMap : gradient(true);
		this._gradientMap = _gradientMap;
		this._reversalGradientMap = _reversalGradientMap;

		object.style.begin();
		object.style.alphaMap =  _gradientMap;
		object.style.transparent = true;
		object.style.end();

		this._object = object;

		this._objectName = object.name;

		this._result = null;
		this._reversal = false;
		this._progress = 0;
	}

	/**
	 * When remove component.
	 */
	onRemove() {
		if(this._result)
		{
			this._result.stop();
		}

		this._result = null;

		super.onRemove();

		this._objectName = '';
	}

	/**
	 * Calculate scale factor and update object style
	 * @param {number} progress - Progress value between 0 and 1
	 * @returns {object} - Contains scaleFactor and adjustedProgress
	 */
	_calculateStyleParams(progress) {
		let scaleFactor;
		if (this._object.uvModeType === THING.UVModeType.Tile) {
			let width = 1;
			switch (this._object.type) {
				case 'RouteLine':
					width = this._object.width;
					break;
				case 'PolygonLine':
					width = this._object.radius * 2 * Math.PI;
					break;
				default:
					break;
			}
			scaleFactor = 1 / this._object.length * width;
		} else {
			scaleFactor = 1;
		}

		// 调整进度计算逻辑
		// progress = 0 时 adjustedProgress = 0.9
		// progress = 1 时 adjustedProgress = -0.15
		const adjustedProgress = this._reversal ? 
			(-0.22 + (1 - progress) * 1.05) :  // 当progress=1时为-0.15,当progress=0时为0.9
			(0.92 - progress * 1.05);           // 当progress=0时为0.9,当progress=1时为-0.15

		this._object.style.begin();
		this._object.style.alphaMap = this._reversal ? this._reversalGradientMap : this._gradientMap;
		this._object.style.end();

		return { scaleFactor, adjustedProgress };
	}

	/**
	 * 播放线生长动画。
	 * @public
	 * @param {object} [options={}] 动画参数。
	 * @param {number} [options.time=1000] 动画持续时间,单位为毫秒。
	 * @param {number} [options.delayTime=0] 动画开始前的延迟时间。
	 * @param {THING.LerpType} [options.lerpType=THING.LerpType.Linear.None] 动画缓动类型。
	 * @param {THING.LoopType} [options.loopType] 动画循环类型。
	 * @param {number} [options.repeatTimes=1] 动画重复次数。
	 * @param {number} [options.progress=1] 动画进度值,取值范围为0到1。
	 * @param {Function} [options.onComplete] 动画完成时触发的回调函数。
	 * @param {Function} [options.complete] 动画完成时触发的备用回调函数。
	 * @example
	 * lineGrowth.play({
	 *   time: 2000,        // 动画持续2秒
	 *   delayTime: 500,    // 延迟0.5秒开始
	 *   repeatTimes: 3,    // 重复3次
	 *   progress: 0.8      // 动画播放到线条的80%
	 * });
	 */
	play(options = {}) {

		this.setProgress(0);
		const time = options['time'] || 1000;
		const delayTime = options['delayTime'] || 0;
		const lerpType = options['lerpType'] || THING.LerpType.Linear.None;
		const loopType = options['loopType'];
		const repeatTimes = options['repeatTimes'] || 1;
		const progress = options['progress'] || 1;
		const callback = Utils.parseValue(options['onComplete'], options['complete']);

		const { scaleFactor, adjustedProgress } = this._calculateStyleParams(progress);
		const to = adjustedProgress;

		this._object.style.imageSlotType = THING.ImageSlotType.AlphaMap;
		this._object.style.uv = {
			offset: [1, 0],
			repeat: [scaleFactor, 1],
			center: [0, 0],
			rotation: 0
		};
		this._object.style.imageSlotType = THING.ImageSlotType.Map;

		this._result = this._object.app.tweenManager.lerpTo(1, to, time, delayTime)
			.times(repeatTimes)
			.easing(lerpType)
			.looping(loopType)
			.onUpdate((ev, progress) => {
				this._object.style.imageSlotType = THING.ImageSlotType.AlphaMap;
				this._object.style.uv = {
					offset: [this._reversal ? -ev.value : ev.value, 0],
					repeat: [scaleFactor, 1],
					center: [0, 0],
					rotation:  0
				};
				this._object.style.imageSlotType = THING.ImageSlotType.Map;
			})
			.onComplete(ev => {
				if (callback) {
					callback();
				}
			})
			.start();
	}

	/**
	 * 获取当前线生长动画进度。进度值范围为0到1。
	 * @public
	 * @type {number}
	 */
	get progress() {
		return this._progress;
	}
	
	set progress(value) {
		this.setProgress(value)
		this._progress = value;
	}

	/**
	 * 设置线生长进度。
	 * @public
	 * @param {number} value - 进度值范围为0到1。
	 */
	setProgress(value) {
		if (!this._object) return;

		const progress = Math.max(0, Math.min(1, value));
		const { scaleFactor, adjustedProgress } = this._calculateStyleParams(progress);

		this._object.style.imageSlotType = THING.ImageSlotType.AlphaMap;
		this._object.style.uv = {
			offset: [this._reversal ? -adjustedProgress : adjustedProgress, 0],
			repeat: [scaleFactor, 1],
			center: [0, 0],
			rotation: 0
		};
		this._object.style.imageSlotType = THING.ImageSlotType.Map;
	}

	/**
	 * 设置线生长方向是否反转。
	 * @public
	 * @type {boolean} value - 是否反转线生长方向。
	 */
	set reversal(value) {
		this._reversal = value;
	}

	get reversal() {
		return this._reversal;
	}

}

export { LineGrowthComponent }