/**
 * 数一数选一选/填一填绘制服务
 * 支持两种模式：'select'（选一选）和 'fill'（填一填）
 */

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

/**
 * 数一数选一选/填一填数据
 */
export interface CountingSelectData {
    problems: Array<{
        count: number;
        imageIndex: number;
        imageType: 'fruits' | 'twelve-animals';
        options?: number[]; // 选一选模式需要，填一填模式不需要
        correctIndex?: number; // 选一选模式需要
    }>;
}

/**
 * 数一数选一选/填一填绘制服务
 */
class CountingSelectDraw extends BaseDrawService {
    countingData: CountingSelectData | null = null;
    mode: 'select' | 'fill';

    constructor(
        canvas: Canvas,
        ctx: RenderingContext,
        options?: Record<string, any>,
    ) {
        super(canvas, ctx, options);
        this.countingData = null;
        this.mode = 'select'; // 默认选一选模式
    }

    /**
     * 绘制数一数选一选/填一填内容
     */
    async draw(
        countingData: CountingSelectData,
        mode: 'select' | 'fill' = 'select',
    ) {
        if (!countingData || !countingData.problems) {
            return;
        }

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

    /**
     * 绘制内容区域
     */
    private async drawContent(params: {
        canvas: WechatMiniprogram.Canvas;
        ctx: RenderingContext;
        countingData: CountingSelectData;
        mode: 'select' | 'fill';
        canvasWidth: number;
        startY: number;
    }): Promise<void> {
        const { canvas, ctx, countingData, mode, canvasWidth, startY } = params;
        const { problems } = countingData;

        // 布局参数
        const leftMargin = 30;
        const rightMargin = 30;
        const topMargin = 20;
        const boxSpacing = 20; // 框之间的间距

        // 计算每个框的尺寸
        const availableWidth = canvasWidth - leftMargin - rightMargin;
        const boxWidth = (availableWidth - boxSpacing * 2) / 3; // 3列，2个间距
        const boxHeight = 210; // 框的高度（增加）

        // 图片区域高度
        const imageAreaHeight = 160;
        // 底部区域高度（选项表格或括号区域）
        const bottomAreaHeight = boxHeight - imageAreaHeight;

        // 选项表格相关（仅 select 模式使用）
        const optionCellWidth = boxWidth / 3; // 每列宽度（均匀分三列）

        let currentY = startY + topMargin;

        // 绘制3x3网格
        for (let row = 0; row < 3; row++) {
            for (let col = 0; col < 3; col++) {
                const problemIndex = row * 3 + col;
                if (problemIndex >= problems.length) {
                    continue;
                }

                const problem = problems[problemIndex];

                // 计算框的位置
                const boxX = leftMargin + col * (boxWidth + boxSpacing);
                const boxY = currentY + row * (boxHeight + boxSpacing);

                // 绘制一个完整的题目框
                await this.drawProblemBox(
                    ctx,
                    canvas,
                    problem,
                    boxX,
                    boxY,
                    boxWidth,
                    boxHeight,
                    imageAreaHeight,
                    bottomAreaHeight,
                    optionCellWidth,
                    mode,
                );
            }
        }
    }

    /**
     * 绘制一个题目框（图片 + 选项表格 或 括号）
     */
    private async drawProblemBox(
        ctx: RenderingContext,
        canvas: WechatMiniprogram.Canvas,
        problem: {
            count: number;
            imageIndex: number;
            imageType: 'fruits' | 'twelve-animals';
            options?: number[];
            correctIndex?: number;
        },
        boxX: number,
        boxY: number,
        boxWidth: number,
        boxHeight: number,
        imageAreaHeight: number,
        bottomAreaHeight: number,
        optionCellWidth: number,
        mode: 'select' | 'fill',
    ) {
        const borderRadius = 12;

        // 绘制实线框
        ctx.strokeStyle = '#333';
        ctx.lineWidth = 1;
        this.drawRoundedRectInternal(
            ctx,
            boxX,
            boxY,
            boxWidth,
            boxHeight,
            borderRadius,
            false,
        );

        // 图片区域
        const imageAreaX = boxX;
        const imageAreaY = boxY;

        // 绘制图片
        await this.drawImagesInBox(
            ctx,
            canvas,
            problem.count,
            problem.imageIndex,
            problem.imageType,
            imageAreaX,
            imageAreaY,
            boxWidth,
            imageAreaHeight,
        );

        // 底部区域
        const bottomAreaX = boxX;
        const bottomAreaY = boxY + imageAreaHeight;

        // 绘制底部区域的顶部横线（两种模式都需要）
        ctx.strokeStyle = '#333';
        ctx.lineWidth = 1;
        ctx.beginPath();
        ctx.moveTo(bottomAreaX, bottomAreaY);
        ctx.lineTo(bottomAreaX + boxWidth, bottomAreaY);
        ctx.stroke();

        if (mode === 'select' && problem.options) {
            // 选一选模式：绘制三个数字选项（表格样式）
            // 绘制三个单元格（均匀分三列）
            for (let i = 0; i < problem.options.length; i++) {
                const cellX = bottomAreaX + i * optionCellWidth;
                const cellY = bottomAreaY;

                // 绘制单元格边框（右边框，除了最后一个）
                if (i < problem.options.length - 1) {
                    ctx.beginPath();
                    ctx.moveTo(cellX + optionCellWidth, cellY);
                    ctx.lineTo(
                        cellX + optionCellWidth,
                        cellY + bottomAreaHeight,
                    );
                    ctx.stroke();
                }

                // 绘制数字（居中）
                const numberX = cellX + optionCellWidth / 2;
                const numberY = cellY + bottomAreaHeight / 2;

                ctx.fillStyle = getRandomNumberColor();
                ctx.font = `bold ${28}px "Microsoft Yahei"`;
                ctx.textAlign = 'center';
                ctx.textBaseline = 'middle';
                ctx.fillText(String(problem.options[i]), numberX, numberY);
            }
        } else if (mode === 'fill') {
            // 填一填模式：绘制括号 "(      )"
            const bracketFontSize = 28;
            const bracketSpacing = 46; // 左右括号之间的间距（留空区域）

            // 计算括号位置（居中）
            const bracketY = bottomAreaY + bottomAreaHeight / 2;
            const centerX = boxX + boxWidth / 2;

            // 左括号
            ctx.fillStyle = '#333';
            ctx.font = `${bracketFontSize}px "Microsoft Yahei"`;
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            const leftBracketX = centerX - bracketSpacing / 2;
            ctx.fillText('(', leftBracketX, bracketY);

            // 右括号
            const rightBracketX = centerX + bracketSpacing / 2;
            ctx.fillText(')', rightBracketX, bracketY);
        }
    }

    /**
     * 在框内绘制多张图片
     */
    private async drawImagesInBox(
        ctx: RenderingContext,
        canvas: WechatMiniprogram.Canvas,
        count: number,
        imageIndex: number,
        imageType: 'fruits' | 'twelve-animals',
        boxX: number,
        boxY: number,
        boxWidth: number,
        boxHeight: number,
    ) {
        // 图片配置
        const imageConfig = {
            'twelve-animals': {
                folder: 'twelve-animals',
                maxIndex: 12,
            },
            fruits: {
                folder: 'fruits',
                maxIndex: 22,
            },
        };

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

        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/${config.folder}/${imageIndex}.png`;
            boxImage = await getImage(canvas, imagePath);
        } catch (error) {
            console.error(`加载${config.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 CountingSelectDraw;
