import { ref } from 'vue'
import { fabric } from 'fabric-with-all'
import { createId } from '../../tools/tools'
import { exportObjectsToImage, exportObjectToThumbnail } from '../tools/exportMethod'
import { OperationType } from '../tools/layerHelper'
import { getArrowPath, getLinePath, cloneObjects, getStarArr } from '../tools/canvasMethod'

export const FillSourceToBase64 = (source) => {
	if (source?.toDataURL) {
		return source.toDataURL?.();
	} else if (source?.src) {
		return source.src;
	}
	return source;
}

/**
 * 图片添加gap转换
 * @param {HTMLCanvasElement} image - img元素
 * @param {Number} gapX - 水平gap
 * @param {Number} gapY - 垂直gap
 * @returns {HTMLCanvasElement} 转换后的canvas元素
*/
export function imageAddGapToCanvas(image, gapX, gapY) {
	// 创建透明 Canvas
	const tcanvas = document.createElement('canvas');
	tcanvas.width = image.width + gapX;
	tcanvas.height = image.height + gapY;
	const ctx = tcanvas.getContext('2d', { willReadFrequently: true });
	ctx.clearRect(0, 0, tcanvas.width, tcanvas.height);
	ctx.drawImage(image, 0, 0);
	return tcanvas;
}


/**
 * 创建缩放+旋转的变换矩阵
 * @param {number} scale - 缩放比例
 * @param {number} angle - 旋转角度（度）
 * @returns {Array} 变换矩阵 [a, b, c, d, e, f]
*/
export function createPatternTransform(scale, angle) {
	const angle_ = angle * Math.PI / 180;
	const cos = Math.cos(angle_);
	const sin = Math.sin(angle_);

	// 先缩放，后旋转
	return [
		scale * cos,    // a
		scale * sin,    // b
		-scale * sin,   // c
		scale * cos,    // d
		0,              // e (水平位移)
		0               // f (垂直位移)
	];
}
/**
 * 获取变换矩阵的缩放、旋转
 * @param {Array} Transform - 变换矩阵、
 * @returns {Object} 缩放、旋转角度 {scale, angle}
*/
export function getTransformScaleAngle(Transform) {
	const a = Transform[0];
	const b = Transform[1];
	const c = Transform[2];
	const d = Transform[3];
	const scale = Math.sqrt(a * a + b * b);
	const angle = Math.round(Math.atan2(b, a) * 180 / Math.PI);
	return { scale, angle };
}

export class ObjectManager {
	stateManager: any
	canvasManager: any
	layerManager: any
	constructor(options) {
		this.stateManager = options.stateManager;
		this.canvasManager = options.canvasManager;
		this.layerManager = options.layerManager
	}
	onMounted() { }
	/** 设置混合模式 */
	setBlendMode(id: string, blendMode: string) {
		const object = this.canvasManager.getObjectById(id)
		if (!object) return console.warn('设置混合模式失败，对象不存在ID:', id)
		object.set("globalCompositeOperation", blendMode)
		this.canvasManager.renderAll()
	}

	/** 设置平铺状态 */
	setFillRepeat(id: string, isRecord = true) {
		const object = this.canvasManager.getObjectById(id)
		if (!object) return console.warn('设置平铺状态失败，对象不存在ID:', id)
		if (object.type !== 'image') return console.warn('设置平铺状态失败，对象不是图片类型:', id)

		// 创建透明 Canvas
		const imgEl = object.getElement();
		const tcanvas = document.createElement('canvas');
		tcanvas.width = imgEl.width;
		tcanvas.height = imgEl.height;
		const ctx = tcanvas.getContext('2d');
		ctx.clearRect(0, 0, tcanvas.width, tcanvas.height);
		ctx.drawImage(imgEl, 0, 0);
		const fill = {
			source: FillSourceToBase64(imgEl),
			gapX: 0,
			gapY: 0,
		}
		const pattern = new fabric.Pattern({
			source: tcanvas,
			repeat: 'repeat',
			patternTransform: createPatternTransform(1, 0),
			offsetX: 0, // 水平偏移
			offsetY: 0, // 垂直偏移
		});
		const info = {
			...object.info,
			fill,
		}
		const rect = new fabric.Rect({
			width: object.width,
			height: object.height,
			top: object.top,
			left: object.left,
			angle: object.angle,
			scaleX: object.scaleX,
			scaleY: object.scaleY,
			flipX: object.flipX,
			flipY: object.flipY,
			globalCompositeOperation: object.globalCompositeOperation,
			originX: "left",
			originY: "top",
			info,
		});
		rect.set("fill", pattern)
		this.canvasManager.canvas.remove(object)
		this.canvasManager.add(rect, isRecord)
	}
	/** 获取填充对象 */
	getFillRepeatObject(id: string) {
		const object = this.canvasManager.getObjectById(id)
		if (!object) {
			console.warn('getFillRepeatObject 对象不存在ID:', id)
			return null
		}
		if (object.type !== 'rect') {
			console.warn('getFillRepeatObject 对象不是矩形类型:', id)
			return null
		}
		if (object.fill?.repeat !== 'repeat') {
			console.warn('getFillRepeatObject 对象不是平铺填充类型:', id)
			return null
		}
		return object
	}
	/** 
	 * 修改平铺参数
	 * @param id 目标对象ID
	 * @param options 参数
	 * @param options.scale 缩放比例
	 * @param options.angle 旋转角度
	 * @param options.offsetX 水平偏移
	 * @param options.offsetY 垂直偏移
	 */
	async updateFillRepeatTransform(id: string, options: any, isRecord: boolean) {
		const object = this.getFillRepeatObject(id)
		if (!object) return null
		const fill = object.get("fill");
		const scale = options.hasOwnProperty('scale') ? options.scale : getTransformScaleAngle(fill.patternTransform).scale
		const angle = options.hasOwnProperty('angle') ? options.angle : getTransformScaleAngle(fill.patternTransform).angle
		const offsetX = options.hasOwnProperty('offsetX') ? options.offsetX : fill.offsetX
		const offsetY = options.hasOwnProperty('offsetY') ? options.offsetY : fill.offsetY
		fill.patternTransform = createPatternTransform(scale, angle)
		fill.offsetX = offsetX
		fill.offsetY = offsetY
		object.set("fill", new fabric.Pattern(fill));
		this.canvasManager.renderAll()
		if (isRecord) {
			this.stateManager.recordState()
			this.layerManager.updateLayerThumbnailsById(id)
		}
	}

	/** 修改平铺间隙
	 * @param id 目标对象ID
	 * @param options 间隙参数
	 * @param options.gapX 水平间隙
	 * @param options.gapY 垂直间隙
	 */
	async updateFillRepeatGap(id: string, options: any, isRecord: boolean) {
		const object = this.getFillRepeatObject(id)
		if (!object) return null
		const gapX = options.hasOwnProperty('gapX') ? options.gapX : object.info.fill.gapX
		const gapY = options.hasOwnProperty('gapY') ? options.gapY : object.info.fill.gapY
		const fill = object.get("fill");
		const image = new Image();
		image.crossOrigin = "anonymous";
		image.src = object.info.fill.source;
		await image.decode();
		fill.source = imageAddGapToCanvas(image, gapX, gapY)
		object.info.fill.gapX = gapX
		object.info.fill.gapY = gapY
		object.set("fill", new fabric.Pattern(fill));
		this.canvasManager.renderAll()
		if (isRecord) {
			this.stateManager.recordState()
			this.layerManager.updateLayerThumbnailsById(id)
		}
	}

	/** 修改属性
	 * @param id 目标对象ID
	 * @param options 参数
	 * @param isRecord 是否记录
	 */
	async updateProperty(id: string, options: any, isRecord: boolean) {
		const object = this.canvasManager.getObjectById(id)
		if (!object) return null
		const type = object.type
		const isWidth = options.hasOwnProperty('width')
		const isHeight = options.hasOwnProperty('height')
		if (isWidth || isHeight) {
			const width = isWidth ? options.width : object.width
			const height = isHeight ? options.height : object.height
			console.log(width, height)
			if (type === "polygon") {
				if (object.points.length === 10) {// 五角星
					options.points = getStarArr(width, height)
				}
			} else if (type === "ellipse") {// 椭圆
				options.rx = width / 2
				options.ry = height / 2
			}
		}
		object.set(options);
		this.canvasManager.renderAll()
		if (isRecord) {
			this.stateManager.recordState()
			this.layerManager.updateLayerThumbnailsById(id)
		}
	}

	dispose() { }
}