import NumberDecomposeDraw from '../shared/service/numberDecomposeDraw';
import {
    createMathPage,
    CanvasDataState,
} from '../shared/common/mathPageMixin';

type DecomposeMode = 'with-image' | 'decompose' | 'compose';

createMathPage({
    canvas: null as Canvas | null,
    ctx: null as RenderingContext | null,
    boxHeight: 0,
    boxWidth: 0,
    drawService: null as NumberDecomposeDraw | null,
    decomposeData: null as {
        problems: Array<{
            whole: number | null; // 总数（null表示组合模式需要填写）
            part1: number | null; // 第一个部分（null表示需要填写）
            part2: number | null; // 第二个部分（null表示需要填写）
            imageIndex?: number; // 图片索引（有图片模式需要）
            imageType?: 'fruits' | 'twelve-animals'; // 图片类型
        }>;
        mode: DecomposeMode;
    } | null,

    data: {
        pageTitle: '10以内数的分与合',
        subTitle: '学习数的分解与组合',
        functionId: '',
        hasContent: false,
        showShareDialog: false,
        showTypeSelector: true,
        currentMode: 'with-image',
        currentModeName: '有图片模式',
        typeActions: [
            { name: '有图片模式', value: 'with-image' },
            { name: '分模式', value: 'decompose' },
            { name: '组合模式', value: 'compose' },
        ],
        maxNumber: 10, // 最大数字：10 或 20
    } as CanvasDataState & {
        showTypeSelector: boolean;
        currentMode: DecomposeMode;
        currentModeName: string;
        typeActions: Array<{ name: string; value: DecomposeMode }>;
        maxNumber: number;
    },

    onLoad(options: { id?: string; mode?: DecomposeMode }) {
        const functionId = options.id || 'number-decompose';
        const is20Within = functionId === 'number-decompose-20';
        const maxNumber = is20Within ? 20 : 10;

        // 20以内只有两种模式，10以内有三种模式
        let defaultMode: DecomposeMode;
        let typeActions: Array<{ name: string; value: DecomposeMode }>;
        let defaultTypeName: string;

        if (is20Within) {
            // 20以内：只有分模式和组合模式
            defaultMode = options.mode || 'decompose';
            typeActions = [
                { name: '20以内的分解', value: 'decompose' },
                { name: '20以内的组合', value: 'compose' },
            ];
            defaultTypeName =
                defaultMode === 'decompose' ? '20以内的分解' : '20以内的组合';
        } else {
            // 10以内：有图片模式、分模式、组合模式
            defaultMode = options.mode || 'with-image';
            typeActions = [
                { name: '有图片模式', value: 'with-image' },
                { name: '分模式', value: 'decompose' },
                { name: '组合模式', value: 'compose' },
            ];
            defaultTypeName =
                defaultMode === 'with-image'
                    ? '有图片模式'
                    : defaultMode === 'decompose'
                      ? '分模式'
                      : '组合模式';
        }

        this.setData({
            currentMode: defaultMode,
            currentModeName: defaultTypeName,
            typeActions,
            maxNumber,
        });
        this.initPageInfo(
            functionId,
            is20Within ? '20以内数的分与合' : '10以内数的分与合',
        );
    },

    onReady() {
        this.initCanvas({
            createDrawService: (
                canvas: Canvas,
                ctx: RenderingContext,
                options?: Record<string, any>,
            ) => {
                return new NumberDecomposeDraw(canvas, ctx, options);
            },
            drawServiceOptions: {
                subTitle: this.data.subTitle,
            },
            onCanvasReady: () => {
                // Canvas 初始化完成后，生成初始数据
                this.onRandom();
            },
        });
    },

    /**
     * 绘制Canvas内容
     */
    async drawCanvas() {
        if (!this.ctx || !this.drawService || !this.decomposeData) {
            return;
        }

        try {
            await this.drawService.draw(this.decomposeData);
            this.setData({ hasContent: true });
        } catch (error) {
            console.error('绘制失败:', error);
            this.setData({ hasContent: false });
        }
    },

    /**
     * 随机生成
     */
    onRandom() {
        this.generateDecomposeData();
        this.drawCanvas();
    },

    /**
     * 生成分解数据（确保不重复）
     */
    generateDecomposeData() {
        const mode = this.data.currentMode;
        const maxNumber = this.data.maxNumber;
        const is20Within = maxNumber === 20;

        const problems: Array<{
            whole: number | null;
            part1: number | null;
            part2: number | null;
            imageIndex?: number;
            imageType?: 'fruits' | 'twelve-animals';
        }> = [];

        // 用于去重的 Set，存储题目唯一标识
        // 格式：对于分解模式 "whole:part1:part2:showPart1"，对于组合模式 "part1:part2"
        const usedKeys = new Set<string>();

        // 确定根节点的数字范围
        const minWhole = is20Within ? 11 : 2; // 20以内从11开始，10以内从2开始
        const maxWhole = maxNumber;

        if (mode === 'with-image') {
            // 有图片模式：9个题目，一行三列，总共三行（仅10以内）
            const problemCount = 9;
            let attempts = 0;
            const maxAttempts = problemCount * 50; // 最大尝试次数

            while (problems.length < problemCount && attempts < maxAttempts) {
                attempts++;

                // 生成总数（2-10）
                const whole =
                    Math.floor(Math.random() * (maxWhole - minWhole + 1)) +
                    minWhole;
                // 随机选择一个部分（1 到 whole-1）
                const part1 = Math.floor(Math.random() * (whole - 1)) + 1;
                const part2 = whole - part1;

                // 随机决定显示 part1 还是 part2（另一个为 null）
                const showPart1 = Math.random() < 0.5;

                // 生成唯一标识（统一格式：part1 <= part2）
                const minPart = Math.min(part1, part2);
                const maxPart = Math.max(part1, part2);
                const key = `${whole}:${minPart}:${maxPart}:${showPart1}`;

                // 检查是否已存在
                if (usedKeys.has(key)) {
                    continue;
                }

                usedKeys.add(key);

                // 随机选择图片类型和索引
                const imageType: 'fruits' | 'twelve-animals' =
                    Math.random() < 0.5 ? 'fruits' : 'twelve-animals';
                const maxImageIndex = imageType === 'fruits' ? 22 : 12;
                const imageIndex =
                    Math.floor(Math.random() * maxImageIndex) + 1;

                problems.push({
                    whole,
                    part1: showPart1 ? part1 : null,
                    part2: showPart1 ? null : part2,
                    imageIndex,
                    imageType,
                });
            }
        } else if (mode === 'decompose') {
            // 分模式：15个题目，一行3个，总共5行
            const problemCount = 15;
            let attempts = 0;
            const maxAttempts = problemCount * 50; // 最大尝试次数

            while (problems.length < problemCount && attempts < maxAttempts) {
                attempts++;

                // 生成总数（2-10 或 11-20）
                const whole =
                    Math.floor(Math.random() * (maxWhole - minWhole + 1)) +
                    minWhole;
                // 随机选择一个部分（1 到 whole-1）
                const part1 = Math.floor(Math.random() * (whole - 1)) + 1;
                const part2 = whole - part1;

                // 随机决定显示 part1 还是 part2（另一个为 null）
                const showPart1 = Math.random() < 0.5;

                // 生成唯一标识（统一格式：part1 <= part2）
                const minPart = Math.min(part1, part2);
                const maxPart = Math.max(part1, part2);
                const key = `${whole}:${minPart}:${maxPart}:${showPart1}`;

                // 检查是否已存在
                if (usedKeys.has(key)) {
                    continue;
                }

                usedKeys.add(key);

                problems.push({
                    whole,
                    part1: showPart1 ? part1 : null,
                    part2: showPart1 ? null : part2,
                });
            }
        } else if (mode === 'compose') {
            // 组合模式：15个题目，一行3个，总共5行
            const problemCount = 15;
            let attempts = 0;
            const maxAttempts = problemCount * 50; // 最大尝试次数

            while (problems.length < problemCount && attempts < maxAttempts) {
                attempts++;

                // 生成总数（2-10 或 11-20）
                const whole =
                    Math.floor(Math.random() * (maxWhole - minWhole + 1)) +
                    minWhole;
                // 随机选择一个部分（1 到 whole-1）
                const part1 = Math.floor(Math.random() * (whole - 1)) + 1;
                const part2 = whole - part1;

                // 生成唯一标识（统一格式：part1 <= part2）
                const minPart = Math.min(part1, part2);
                const maxPart = Math.max(part1, part2);
                const key = `${minPart}:${maxPart}`;

                // 检查是否已存在
                if (usedKeys.has(key)) {
                    continue;
                }

                usedKeys.add(key);

                // 组合模式：两个部分都显示，根节点为 null
                problems.push({
                    whole: null, // 根节点需要填写
                    part1,
                    part2,
                });
            }
        }

        this.decomposeData = { problems, mode };
    },

    /** 选择类型 */
    onSelectType(event: any) {
        const { name, value } = event.detail;
        this.setData({
            currentMode: value,
            currentModeName: name,
        });
        // 重新生成数据
        this.onRandom();
    },
});
