/**
 * 数一数比大小绘制服务
 */

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

/**
 * 数一数比大小数据
 */
export interface CompareData {
    problems: Array<{
        leftCount: number;
        rightCount: number;
        leftImageIndex: number;
        rightImageIndex: number;
        imageType: 'fruits' | 'twelve-animals';
    }>;
}

/**
 * 数一数比大小绘制服务
 */
class CompareDraw extends BaseDrawService {
    compareData: CompareData | null = null;

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

    /**
     * 绘制数一数比大小内容
     */
    async draw(compareData: CompareData) {
        if (!compareData || !compareData.problems) {
            return;
        }

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

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

        // 布局参数
        const leftMargin = 30;
        const rightMargin = 30;
        const topMargin = 12;
        const rowSpacing = 116; // 行之间的间距
        const columnSpacing = 40; // 两列之间的间距（可调节）

        // 计算每列的宽度（减去边距和列间距）
        const availableWidth =
            canvasWidth - leftMargin - rightMargin - columnSpacing;
        const columnWidth = availableWidth / 2;

        // 框的尺寸
        const boxWidth = 100;
        const boxHeight = 100;
        const borderRadius = 12;
        const circleRadius = 18; // 圆圈半径

        // 框与圆圈之间的间距
        const boxToCircleSpacing = 12;

        // 计算左侧列和右侧列的起始X位置
        const leftColumnStartX = leftMargin;
        const rightColumnStartX = leftMargin + columnWidth + columnSpacing;

        // 计算每列内部的布局（左框 | 圆圈 | 右框，居中）
        const totalWidthPerColumn =
            boxWidth +
            boxToCircleSpacing +
            circleRadius * 2 +
            boxToCircleSpacing +
            boxWidth;
        const columnPadding = (columnWidth - totalWidthPerColumn) / 2;

        let currentY = startY + topMargin;

        // 固定绘制6行
        const totalRows = 6;
        for (let rowIndex = 0; rowIndex < totalRows; rowIndex++) {
            const rowY = currentY + rowIndex * rowSpacing;
            // 绘制左侧列
            const leftProblemIndex = rowIndex * 2;
            if (leftProblemIndex < problems.length) {
                await this.drawCompareProblem(
                    ctx,
                    canvas,
                    problems[leftProblemIndex],
                    leftColumnStartX + columnPadding,
                    rowY,
                    boxWidth,
                    boxHeight,
                    borderRadius,
                    circleRadius,
                    boxToCircleSpacing,
                );
            }

            // 绘制右侧列
            const rightProblemIndex = rowIndex * 2 + 1;
            if (rightProblemIndex < problems.length) {
                await this.drawCompareProblem(
                    ctx,
                    canvas,
                    problems[rightProblemIndex],
                    rightColumnStartX + columnPadding,
                    rowY,
                    boxWidth,
                    boxHeight,
                    borderRadius,
                    circleRadius,
                    boxToCircleSpacing,
                );
            }
        }
    }

    /**
     * 绘制一个比较问题（左框 | 圆圈 | 右框）
     */
    private async drawCompareProblem(
        ctx: RenderingContext,
        canvas: WechatMiniprogram.Canvas,
        problem: {
            leftCount: number;
            rightCount: number;
            leftImageIndex: number;
            rightImageIndex: number;
            imageType: 'fruits' | 'twelve-animals';
        },
        startX: number,
        startY: number,
        boxWidth: number,
        boxHeight: number,
        borderRadius: number,
        circleRadius: number,
        boxToCircleSpacing: number,
    ) {
        const {
            leftCount,
            rightCount,
            leftImageIndex,
            rightImageIndex,
            imageType,
        } = problem;

        // 图片配置
        const imageConfig = {
            'twelve-animals': {
                folder: 'twelve-animals',
                maxIndex: 12,
            },
            fruits: {
                folder: 'fruits',
                maxIndex: 22,
            },
        };

        const config = imageConfig[imageType] || imageConfig['twelve-animals'];

        // 计算左框位置
        const leftBoxX = startX;
        const leftBoxY = startY;

        // 计算圆圈位置
        const circleX = leftBoxX + boxWidth + boxToCircleSpacing + circleRadius;
        const circleY = startY + boxHeight / 2;

        // 计算右框位置
        const rightBoxX = circleX + circleRadius + boxToCircleSpacing;
        const rightBoxY = startY;

        // 绘制左框
        ctx.strokeStyle = '#999';
        ctx.lineWidth = 1;
        this.drawRoundedRectInternal(
            ctx,
            leftBoxX,
            leftBoxY,
            boxWidth,
            boxHeight,
            borderRadius,
            true,
        );

        // 绘制左框内的图片
        await this.drawImagesInBox(
            ctx,
            canvas,
            leftCount,
            leftImageIndex,
            config.folder,
            leftBoxX,
            leftBoxY,
            boxWidth,
            boxHeight,
        );

        // 绘制实心圆圈
        ctx.fillStyle = '#fff';
        ctx.strokeStyle = '#333';
        ctx.lineWidth = 2;
        ctx.beginPath();
        ctx.arc(circleX, circleY, circleRadius, 0, Math.PI * 2);
        ctx.fill(); // 先填充白色
        ctx.stroke(); // 再绘制边框

        // 绘制右框
        ctx.strokeStyle = '#999';
        ctx.lineWidth = 1;
        this.drawRoundedRectInternal(
            ctx,
            rightBoxX,
            rightBoxY,
            boxWidth,
            boxHeight,
            borderRadius,
            true,
        );

        // 绘制右框内的图片
        await this.drawImagesInBox(
            ctx,
            canvas,
            rightCount,
            rightImageIndex,
            config.folder,
            rightBoxX,
            rightBoxY,
            boxWidth,
            boxHeight,
        );
    }

    /**
     * 在框内绘制多张图片
     */
    private async drawImagesInBox(
        ctx: RenderingContext,
        canvas: WechatMiniprogram.Canvas,
        count: number,
        imageIndex: number,
        folder: string,
        boxX: number,
        boxY: number,
        boxWidth: number,
        boxHeight: number,
    ) {
        const padding = 8; // 框内边距
        const availableWidth = boxWidth - padding * 2;
        const availableHeight = boxHeight - padding * 2;

        // 根据数量确定每行的图片数和图片大小
        let imagesPerRow: number;
        let imageSize: number;

        if (count <= 4) {
            imagesPerRow = count <= 2 ? count : 2;
            imageSize =
                Math.min(availableWidth / imagesPerRow, availableHeight / 2) -
                4;
        } else if (count <= 6) {
            imagesPerRow = 3;
            imageSize = Math.min(availableWidth / 3, availableHeight / 2) - 4;
        } else {
            imagesPerRow = 3;
            imageSize = Math.min(availableWidth / 3, availableHeight / 3) - 4;
        }

        const rows = Math.ceil(count / imagesPerRow);
        const imageSpacing =
            (availableWidth - imageSize * imagesPerRow) / (imagesPerRow + 1);
        const rowSpacing =
            rows > 1 ? (availableHeight - imageSize * rows) / (rows + 1) : 0;

        // 加载图片
        let boxImage: any = null;
        try {
            const imagePath = `/mathPages/shared/assets/${folder}/${imageIndex}.png`;
            boxImage = await getImage(canvas, imagePath);
        } catch (error) {
            console.error(`加载${folder}/${imageIndex}图片失败:`, error);
            return;
        }

        // 绘制图片
        for (let i = 0; i < count; i++) {
            const row = Math.floor(i / imagesPerRow);
            const col = i % imagesPerRow;

            const imageX =
                boxX +
                padding +
                imageSpacing +
                col * (imageSize + imageSpacing);
            const imageY =
                boxY +
                padding +
                (rows > 1 ? rowSpacing : (availableHeight - imageSize) / 2) +
                row * (imageSize + (rows > 1 ? rowSpacing : 0));

            if (boxImage) {
                // 计算图片高度（等比例缩放）
                // @ts-ignore - 微信小程序图片对象有 width 和 height 属性
                const scaledHeight =
                    (boxImage.height / boxImage.width) * imageSize;

                ctx.drawImage(
                    boxImage,
                    imageX,
                    imageY,
                    imageSize,
                    scaledHeight,
                );
            }
        }
    }

    /**
     * 绘制圆角矩形（虚线边框）
     */
    private drawRoundedRectInternal(
        ctx: RenderingContext,
        x: number,
        y: number,
        width: number,
        height: number,
        radius: number,
        isDashed: boolean = true,
    ) {
        ctx.beginPath();
        ctx.moveTo(x + radius, y);
        ctx.lineTo(x + width - radius, y);
        ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
        ctx.lineTo(x + width, y + height - radius);
        ctx.quadraticCurveTo(
            x + width,
            y + height,
            x + width - radius,
            y + height,
        );
        ctx.lineTo(x + radius, y + height);
        ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
        ctx.lineTo(x, y + radius);
        ctx.quadraticCurveTo(x, y, x + radius, y);
        ctx.closePath();

        if (isDashed) {
            ctx.setLineDash([6 / 3, 6 / 3]); // 约2px的虚线
        } else {
            ctx.setLineDash([]);
        }
        ctx.stroke();
        ctx.setLineDash([]); // 重置为实线
    }
}

export default CompareDraw;
