/**  克隆对象 */
export async function cloneObjects(objects = []) {
	const arrs = []
	for (const obj of objects) {
		const clonedObj = await new Promise((resolve, reject) => {
			obj.clone((v) => {
				v.set({
					left: obj.left,
					top: obj.top,
					width: obj.width,
					height: obj.height,
					scaleX: obj.scaleX,
					scaleY: obj.scaleY,
					angle: obj.angle,
				})
				resolve(v)
			})
		})
		arrs.push(clonedObj)
	}
	return arrs
}


/**  获取组合对象边界 */
export async function getObjectsBoundingBox(objects = []) {
	const box1 = { x: Infinity, y: Infinity }
	const box2 = { x: -Infinity, y: -Infinity }
	objects.forEach(obj => {
		const rect = obj.getBoundingRect()
		box1.x = Math.min(box1.x, rect.left)
		box1.y = Math.min(box1.y, rect.top)
		box2.x = Math.max(box2.x, rect.left + rect.width)
		box2.y = Math.max(box2.y, rect.top + rect.height)
	})
	return {
		left: box1.x,
		top: box1.y,
		width: box2.x - box1.x,
		height: box2.y - box1.y,
	}
}

/** 获取五角星数组 */
export function getStarArr(width = 0, height = 0) {
	const arr = [
		{ x: 0, y: -0.5 },     // 顶点0 (上)
		{ x: 0.15, y: -0.15 },    // 顶点1 (内)
		{ x: 0.50, y: -0.15 },    // 顶点2 (右上外)
		{ x: 0.20, y: 0.10 },     // 顶点3 (内)
		{ x: 0.30, y: 0.50 },     // 顶点4 (右下外)
		{ x: 0.0, y: 0.25 },      // 顶点5 (内)
		{ x: -0.30, y: 0.50 },    // 顶点6 (左下外)
		{ x: -0.20, y: 0.10 },    // 顶点7 (内)
		{ x: -0.50, y: -0.15 },   // 顶点8 (左上外)
		{ x: -0.15, y: -0.15 }    // 顶点9 (内)
	]
	return arr.map(item => ({
		x: item.x * width,
		y: item.y * height,
	}))
}
/** 获取箭头路径 */
export function getArrowPath(width = 0, strokeWidth = 4) {
	const height = strokeWidth * 4
	const arr = [
		["M", 0, height / 2],
		["L", width, height / 2],
		["M", width - height, 0],
		["L", width, height / 2],
		["L", width - height, height],
	]
	var path = ""
	arr.forEach(item => {
		path += item.join(" ") + " "
	})
	return path
}
/** 获取直线路径 */
export function getLinePath(width = 0, height = 0) {
	const arr = [
		["M", 0, height / 2],
		["L", width, height / 2],
	]
	var path = ""
	arr.forEach(item => {
		path += item.join(" ") + " "
	})
	return path
}

/** 计算两点之间的距离 */
export function distance(x1, y1, x2, y2) {
	const dx = x2 - x1;
	const dy = y2 - y1;
	return Math.sqrt(dx * dx + dy * dy);
}
/** 计算两点之间的角度（角度） */
export function angleBetweenPointsDegrees(x1, y1, x2, y2) {
	const dx = x2 - x1;
	const dy = y2 - y1;

	// 计算弧度并转换为角度
	const rad = Math.atan2(dy, dx);
	const deg = rad * 180 / Math.PI;

	return deg;
}



/**
 * 获取对象黑白通道画布
 * @param {fabric.Object} object - 要处理的 fabric 对象
 * @param {ImageData} revData - 相反的ImageData，白通道的相同位置是否为透明，revData为白色为透明，黑色为不透明
 * @param {number} diff - 差值，默认 25
 * @param {Object} rgba - 自定义 rgba 值，默认 { r: 255, g: 255, b: 255, a: 255 }
 * @param {boolean} isMerge - 是否合并，true=合并revData，false=反转revData
 * @returns {HTMLCanvasElement|null} 包含黑白通道的画布，或 null 如果失败
*/
export function getObjectAlphaToCanvas(object, revData, diff = 30, rgba = { r: 255, g: 255, b: 255, a: 255 }, isMerge = false) {
	const image = object.getElement();
	if (image.nodeName !== "IMG" && image.nodeName !== "CANVAS") {
		console.warn("对象不是图片");
		return null;
	}
	const { width, height } = image;
	if (!width || !height) {
		console.warn("对象没有元素");
		return null;
	}
	const canvas = document.createElement("canvas");
	canvas.width = width;
	canvas.height = height;
	const ctx = canvas.getContext("2d", { willReadFrequently: true });
	ctx.drawImage(image, 0, 0, width, height);
	const data = ctx.getImageData(0, 0, width, height);
	for (let i = 0; i < data.data.length; i += 4) {
		const r = data.data[i + 0];
		const g = data.data[i + 1];
		const b = data.data[i + 2];
		const a = data.data[i + 3];
		const revR = revData?.data[i + 0] || 0;
		const revG = revData?.data[i + 1] || 0;
		const revB = revData?.data[i + 2] || 0;
		const revA = revData?.data[i + 3] || 0;
		let isHave = false;
		if (r || g || b || a) {
			if (revR > diff || revG > diff || revB > diff || revA > diff) {
				isHave = false;
			} else {
				isHave = true;
			}
		}
		if (isMerge && (revR || revG || revB || revA)) isHave = true;
		if (isHave) {
			data.data[i + 0] = rgba.r;
			data.data[i + 1] = rgba.g;
			data.data[i + 2] = rgba.b;
			data.data[i + 3] = rgba.a;
		} else {
			data.data[i + 0] = 0;
			data.data[i + 1] = 0;
			data.data[i + 2] = 0;
			data.data[i + 3] = 0;
		}
	}
	ctx.clearRect(0, 0, width, height);
	ctx.putImageData(data, 0, 0);
	return canvas;
}


/**
 * 图片边界跟踪算法(透明底)
 * @param {HTMLCanvasElement} canvas - canvas元素
 * @param {Number} scale - 缩放比例
 * @returns {Array} 边界点数组 [{x, y}, ...]
*/
export function traceImageContour(canvas) {
	const ctx = canvas.getContext("2d", { willReadFrequently: true });
	const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
	const data = imageData.data;
	const width = canvas.width;
	const height = canvas.height;

	// 查找起始点（第一个不透明像素）
	let startX = -1;
	let startY = -1;

	outer: for (let y = 0; y < height; y++) {
		for (let x = 0; x < width; x++) {
			const index = (y * width + x) * 4;
			if (data[index + 3] > 0) {
				startX = x;
				startY = y;
				break outer;
			}
		}
	}

	if (startX === -1) return []; // 没有不透明像素

	// Moore-Neighbor边界跟踪算法
	const contour = [];
	const visited = new Set();
	const directions = [
		[-1, 0],
		[-1, -1],
		[0, -1],
		[1, -1],
		[1, 0],
		[1, 1],
		[0, 1],
		[-1, 1],
	];

	let currentX = startX;
	let currentY = startY;
	let backtrackDir = 4; // 起始方向：右

	do {
		const pointKey = `${currentX},${currentY}`;
		if (!visited.has(pointKey)) {
			contour.push({ x: currentX, y: currentY });
			visited.add(pointKey);
		}

		// 从右方向开始顺时针查找
		let found = false;
		for (let i = 0; i < 8; i++) {
			const dir = (backtrackDir + i) % 8;
			const dx = directions[dir][0];
			const dy = directions[dir][1];
			const checkX = currentX + dx;
			const checkY = currentY + dy;

			if (
				checkX >= 0 &&
				checkX < width &&
				checkY >= 0 &&
				checkY < height
			) {
				const index = (checkY * width + checkX) * 4;
				if (data[index + 3] > 0) {
					currentX = checkX;
					currentY = checkY;
					backtrackDir = (dir + 5) % 8; // 下一个开始查找的方向
					found = true;
					break;
				}
			}
		}

		if (!found) break;
	} while (
		!(currentX === startX && currentY === startY) &&
		visited.size < width * height
	);

	return contour;
}

/** 裁剪画布透明像素 */
export function clipCanvasTransparent(canvas) {
	const ctx = canvas.getContext("2d", { willReadFrequently: true });
	const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
	const data = imageData.data;
	const width = canvas.width;
	const height = canvas.height;
	var minX = width;
	var minY = height;
	var maxX = 0;
	var maxY = 0;
	for (let y = 0; y < height; y++) {
		for (let x = 0; x < width; x++) {
			const index = (y * width + x) * 4;
			if (data[index + 3] > 0) {
				if (x < minX) minX = x;
				if (y < minY) minY = y;
				if (x > maxX) maxX = x;
				if (y > maxY) maxY = y;
			}
		}
	}
	const newCanvas = document.createElement("canvas");
	newCanvas.width = maxX - minX + 1;
	newCanvas.height = maxY - minY + 1;
	const newCtx = newCanvas.getContext("2d");
	newCtx.drawImage(canvas, minX, minY, maxX - minX + 1, maxY - minY + 1, 0, 0, maxX - minX + 1, maxY - minY + 1);
	return {
		minX,
		minY,
		maxX,
		maxY,
		canvas: newCanvas,
	};
}

