/**
 * 连连看绘制服务
 */

import { BaseDrawService } from '../../../core/draw/baseDraw';
import { getImage } from '../../../utils/index';

/**
 * 连连看数据
 */
export interface MatchConnectData {
    /** 参考序列：5张图片的索引数组 */
    referenceSequence: number[];
    /** 6个框，每个框包含5张图片的索引（位置由绘制服务随机生成） */
    boxes: Array<{
        imageIndices: number[];
    }>;
}

/**
 * 连连看绘制服务
 */
class MatchConnectDraw extends BaseDrawService {
    matchData: MatchConnectData | null = null;

    constructor(
        canvas: Canvas,
        ctx: RenderingContext,
        options?: Record<string, any>,
    ) {
        super(canvas, ctx, options);
    }

    /**
     * 绘制连连看内容
     */
    async draw(matchData: MatchConnectData) {
        if (!matchData || !matchData.referenceSequence || !matchData.boxes) {
            return;
        }

        this.matchData = matchData;
        this.prepareDraw();
        await this.drawHeaderAndDivider();
        await this.drawContent({
            canvas: this.canvas,
            ctx: this.ctx,
            matchData: this.matchData,
            canvasWidth: this.canvasWidth,
            startY: this.currentY,
        });
    }

    /**
     * 生成不重叠的图片位置
     * @param count 图片数量
     * @param contentWidth 内容区域宽度
     * @param contentHeight 内容区域高度
     * @param imageSize 图片大小
     * @param imagePadding 图片padding
     * @returns 图片位置数组，每个位置包含x和y（相对于内容区域的坐标）
     */
    private generateNonOverlappingPositions(
        count: number,
        contentWidth: number,
        contentHeight: number,
        imageSize: number,
        imagePadding: number,
    ): Array<{ x: number; y: number }> {
        // 计算最大可放置位置（图片左上角的位置）
        const maxX = contentWidth - imageSize;
        const maxY = contentHeight - imageSize;
        const positions: Array<{ x: number; y: number }> = [];
        const placedRects: Array<{
            left: number;
            top: number;
            right: number;
            bottom: number;
        }> = [];

        /**
         * 检查两个矩形是否重叠
         */
        const isRectOverlap = (
            rect1: {
                left: number;
                top: number;
                right: number;
                bottom: number;
            },
            rect2: {
                left: number;
                top: number;
                right: number;
                bottom: number;
            },
        ): boolean => {
            return !(
                rect1.right < rect2.left ||
                rect1.left > rect2.right ||
                rect1.bottom < rect2.top ||
                rect1.top > rect2.bottom
            );
        };

        // 计算图片的实际占用大小（包含padding）
        const occupiedSize = imageSize + imagePadding * 2;

        // 生成候选位置网格，然后随机打乱
        // 这样可以确保位置分布更均匀，同时保持随机性
        const gridCols = Math.max(3, Math.floor(contentWidth / occupiedSize));
        const gridRows = Math.max(2, Math.floor(contentHeight / occupiedSize));
        const cellWidth = maxX / Math.max(1, gridCols - 1);
        const cellHeight = maxY / Math.max(1, gridRows - 1);

        // 生成所有可能的网格位置
        const candidatePositions: Array<{ x: number; y: number }> = [];
        for (let row = 0; row < gridRows; row++) {
            for (let col = 0; col < gridCols; col++) {
                const x = col * cellWidth;
                const y = row * cellHeight;
                candidatePositions.push({ x, y });
            }
        }

        // 随机打乱候选位置
        const shuffledCandidates = [...candidatePositions].sort(
            () => Math.random() - 0.5,
        );

        // 从打乱的候选位置中选择不重叠的位置
        for (let i = 0; i < count; i++) {
            let found = false;

            // 先尝试从网格候选位置中选择
            for (const candidate of shuffledCandidates) {
                const x = candidate.x;
                const y = candidate.y;

                // 计算当前图片的实际占用区域（包含padding）
                const currentRect = {
                    left: x - imagePadding,
                    top: y - imagePadding,
                    right: x + imageSize + imagePadding,
                    bottom: y + imageSize + imagePadding,
                };

                // 确保不超出内容区域的范围
                if (
                    currentRect.left < 0 ||
                    currentRect.top < 0 ||
                    currentRect.right > contentWidth ||
                    currentRect.bottom > contentHeight
                ) {
                    continue;
                }

                // 检查是否与已放置的图片重叠
                let overlaps = false;
                for (const placedRect of placedRects) {
                    if (isRectOverlap(currentRect, placedRect)) {
                        overlaps = true;
                        break;
                    }
                }

                if (!overlaps) {
                    // 存储实际占用区域
                    placedRects.push({
                        left: x - imagePadding,
                        top: y - imagePadding,
                        right: x + imageSize + imagePadding,
                        bottom: y + imageSize + imagePadding,
                    });

                    positions.push({ x, y });
                    found = true;
                    break;
                }
            }

            // 如果网格位置都不行，尝试完全随机的位置
            if (!found) {
                let attempts = 0;
                const maxAttempts = 1000;

                while (attempts < maxAttempts) {
                    // 生成随机位置，添加一些随机偏移
                    const randomOffsetX =
                        (Math.random() - 0.5) * cellWidth * 0.5;
                    const randomOffsetY =
                        (Math.random() - 0.5) * cellHeight * 0.5;
                    const baseX = Math.random() * maxX;
                    const baseY = Math.random() * maxY;
                    const x = Math.max(
                        0,
                        Math.min(maxX, baseX + randomOffsetX),
                    );
                    const y = Math.max(
                        0,
                        Math.min(maxY, baseY + randomOffsetY),
                    );

                    // 计算当前图片的实际占用区域（包含padding）
                    const currentRect = {
                        left: x - imagePadding,
                        top: y - imagePadding,
                        right: x + imageSize + imagePadding,
                        bottom: y + imageSize + imagePadding,
                    };

                    // 确保不超出内容区域的范围
                    if (
                        currentRect.left < 0 ||
                        currentRect.top < 0 ||
                        currentRect.right > contentWidth ||
                        currentRect.bottom > contentHeight
                    ) {
                        attempts++;
                        continue;
                    }

                    // 检查是否与已放置的图片重叠
                    let overlaps = false;
                    for (const placedRect of placedRects) {
                        if (isRectOverlap(currentRect, placedRect)) {
                            overlaps = true;
                            break;
                        }
                    }

                    if (!overlaps) {
                        // 存储实际占用区域
                        placedRects.push({
                            left: x - imagePadding,
                            top: y - imagePadding,
                            right: x + imageSize + imagePadding,
                            bottom: y + imageSize + imagePadding,
                        });

                        positions.push({ x, y });
                        found = true;
                        break;
                    }

                    attempts++;
                }
            }

            // 最后的后备方案：使用网格布局，但添加随机偏移
            if (!found) {
                const gridCols = 3;
                const gridRows = 2;
                const gridCellWidth = maxX / Math.max(1, gridCols - 1);
                const gridCellHeight = maxY / Math.max(1, gridRows - 1);
                const baseX = (i % gridCols) * gridCellWidth;
                const baseY = Math.floor(i / gridCols) * gridCellHeight;
                // 添加随机偏移，但确保不重叠
                const offsetX = (Math.random() - 0.5) * gridCellWidth * 0.3;
                const offsetY = (Math.random() - 0.5) * gridCellHeight * 0.3;
                const x = Math.max(0, Math.min(maxX, baseX + offsetX));
                const y = Math.max(0, Math.min(maxY, baseY + offsetY));
                positions.push({ x, y });
            }
        }

        // 最后再次随机打乱位置顺序，增加随机性
        return positions.sort(() => Math.random() - 0.5);
    }

    /**
     * 绘制箭头
     */
    private drawArrow(
        ctx: RenderingContext,
        x1: number,
        y1: number,
        x2: number,
        y2: number,
    ) {
        ctx.strokeStyle = '#FF69B4'; // 粉色
        ctx.lineWidth = 2;
        ctx.setLineDash([]); // 实线

        // 绘制箭头线
        ctx.beginPath();
        ctx.moveTo(x1, y1);
        ctx.lineTo(x2, y2);
        ctx.stroke();

        // 绘制箭头头部
        const angle = Math.atan2(y2 - y1, x2 - x1);
        const arrowLength = 8;
        const arrowAngle = Math.PI / 6; // 30度

        ctx.beginPath();
        ctx.moveTo(x2, y2);
        ctx.lineTo(
            x2 - arrowLength * Math.cos(angle - arrowAngle),
            y2 - arrowLength * Math.sin(angle - arrowAngle),
        );
        ctx.moveTo(x2, y2);
        ctx.lineTo(
            x2 - arrowLength * Math.cos(angle + arrowAngle),
            y2 - arrowLength * Math.sin(angle + arrowAngle),
        );
        ctx.stroke();
    }

    /**
     * 绘制内容区域
     */
    private async drawContent(params: {
        canvas: WechatMiniprogram.Canvas;
        ctx: RenderingContext;
        matchData: MatchConnectData;
        canvasWidth: number;
        startY: number;
    }): Promise<void> {
        const { ctx, matchData, canvasWidth } = params;
        let { startY } = params;

        startY = startY + 25;

        const margin = 40; // 左右边距
        const imageSize = 50; // 图片大小
        const arrowLength = 30; // 箭头长度
        const arrowSpacing = 8; // 箭头左右间距

        // 计算参考序列的总宽度
        // 总宽度 = 所有图片宽度 + 所有箭头长度 + 所有箭头间距（左右各8px）
        const arrowCount = matchData.referenceSequence.length - 1;
        const referenceWidth =
            matchData.referenceSequence.length * imageSize +
            arrowCount * arrowLength +
            arrowCount * arrowSpacing * 2; // 每个箭头左右各8px

        // 绘制参考序列（上面部分）- 居中显示
        const referenceStartX =
            margin + (canvasWidth - margin * 2 - referenceWidth) / 2;
        const referenceY = startY;

        // 绘制参考序列的图片和箭头
        let currentX = referenceStartX;
        for (let i = 0; i < matchData.referenceSequence.length; i++) {
            const imageIndex = matchData.referenceSequence[i];

            // 绘制图片
            try {
                const imagePath = `/focusPages/shared/aeests/material/${imageIndex}.png`;
                const image = await getImage(this.canvas, imagePath);
                ctx.drawImage(
                    image,
                    currentX,
                    referenceY,
                    imageSize,
                    imageSize,
                );
            } catch (error) {
                console.error(`加载参考图片失败: ${imageIndex}`, error);
            }

            // 如果不是最后一张，绘制箭头
            if (i < matchData.referenceSequence.length - 1) {
                // 箭头左边间距8px
                const arrowStartX = currentX + imageSize + arrowSpacing;
                const arrowEndX = arrowStartX + arrowLength;
                const arrowY = referenceY + imageSize / 2;
                this.drawArrow(ctx, arrowStartX, arrowY, arrowEndX, arrowY);
                // 箭头右边间距8px，然后开始下一张图片
                currentX = arrowEndX + arrowSpacing;
            } else {
                currentX += imageSize;
            }
        }

        // 绘制虚线分割线
        const dividerY = referenceY + imageSize + 30;
        this.drawDashedDivider(dividerY, margin);

        // 绘制下面的6个框（3行2列）
        const boxStartY = dividerY + 30;
        const boxWidth = (canvasWidth - margin * 2 - 20) / 2; // 减去列间距
        const boxHeight = 165; // 框的高度
        const boxSpacingX = 20; // 列间距
        const boxSpacingY = 30; // 行间距
        const boxPadding = 10; // 框内边距
        const boxImageSize = 35; // 框内图片大小
        const imagePadding = 20; // 每张图片的内边距（padding）

        for (let row = 0; row < 3; row++) {
            for (let col = 0; col < 2; col++) {
                const boxIndex = row * 2 + col;
                const box = matchData.boxes[boxIndex];
                if (!box || !box.imageIndices) continue;

                const boxX = margin + col * (boxWidth + boxSpacingX);
                const boxY = boxStartY + row * (boxHeight + boxSpacingY);

                // 绘制框（圆角实线）
                this.drawRoundedRect(boxX, boxY, boxWidth, boxHeight, {
                    isDashed: false,
                    radius: 16,
                    color: '#000',
                    lineWidth: 1,
                });

                // 计算框内可用的内容区域
                const contentWidth = boxWidth - boxPadding * 2;
                const contentHeight = boxHeight - boxPadding * 2;

                // 为这个框的图片随机分配位置，确保图片+padding不重叠
                const imagePositions = this.generateNonOverlappingPositions(
                    box.imageIndices.length,
                    contentWidth,
                    contentHeight,
                    boxImageSize,
                    imagePadding,
                );

                // 绘制框内的图片
                for (let i = 0; i < box.imageIndices.length; i++) {
                    const imageIndex = box.imageIndices[i];
                    const position = imagePositions[i];

                    try {
                        const imagePath = `/focusPages/shared/aeests/material/${imageIndex}.png`;
                        const image = await getImage(this.canvas, imagePath);

                        // 计算图片位置
                        const imageX = boxX + boxPadding + position.x;
                        const imageY = boxY + boxPadding + position.y;

                        ctx.drawImage(
                            image,
                            imageX,
                            imageY,
                            boxImageSize,
                            boxImageSize,
                        );
                    } catch (error) {
                        console.error(`加载框内图片失败: ${imageIndex}`, error);
                    }
                }
            }
        }
    }
}

export default MatchConnectDraw;
