import { getRandomNumberColor } from '../../constants/colors';
import MissingNumberDraw from '../shared/service/missingNumberDraw';
import {
    createMathPage,
    CanvasDataState,
} from '../shared/common/mathPageMixin';

createMathPage({
    canvas: null as Canvas | null,
    ctx: null as RenderingContext | null,
    boxHeight: 0,
    boxWidth: 0,
    drawService: null as MissingNumberDraw | null,
    missingNumberData: null as {
        grids: Array<{
            numbers: (number | null)[];
            colors: (string | null)[];
        }>;
        maxNumber: number;
    } | null,

    data: {
        pageTitle: '填上缺少的数字',
        subTitle: '在数字序列中找出并填写缺失的数字',
        functionId: '',
        hasContent: false,
        showShareDialog: false,
        showTypeSelector: true,
        currentMode: 10,
        currentModeName: '10以内',
        typeActions: [
            { name: '10以内', value: 10 },
            { name: '20以内', value: 20 },
            { name: '40以内', value: 40 },
            { name: '50以内', value: 50 },
            { name: '80以内', value: 80 },
            { name: '100以内', value: 100 },
            { name: '120以内', value: 120 },
        ],
    } as CanvasDataState & {
        showTypeSelector: boolean;
        currentMode: number;
        currentModeName: string;
        typeActions: Array<{ name: string; value: number }>;
    },

    onLoad(options: { id?: string; mode?: number }) {
        const functionId = options.id || 'missing-number';
        this.initPageInfo(functionId, '填上缺少的数字');

        this.setData({
            currentMode: options.mode || 10,
            currentModeName: options.mode ? `${options.mode}以内` : '10以内',
        });
    },

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

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

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

    /**
     * 随机生成
     */
    onRandom() {
        const maxNumber = this.data.currentMode;
        this.generateMissingNumberData(maxNumber);
        this.drawCanvas();
    },

    /**
     * 生成缺失数字数据
     */
    generateMissingNumberData(maxNumber: number) {
        const grids: Array<{
            numbers: (number | null)[];
            colors: (string | null)[];
        }> = [];
        const gridMap = {
            10: {
                gridCount: 3,
            },
            20: {
                gridCount: 2,
            },
            40: {
                gridCount: 2,
            },
            50: {
                gridCount: 2,
            },
            80: {
                gridCount: 1,
            },
            100: {
                gridCount: 1,
            },
            120: {
                gridCount: 1,
            },
        };
        const { gridCount } = gridMap[maxNumber as keyof typeof gridMap];

        // 生成多个网格
        for (let gridIndex = 0; gridIndex < gridCount; gridIndex++) {
            let startNumber = 1;
            let endNumber = maxNumber;

            const actualNumbersPerGrid = endNumber - startNumber + 1;

            const numbers: number[] = Array.from(
                { length: actualNumbersPerGrid },
                (_, i) => startNumber + i,
            );

            // 随机隐藏一部分数字（隐藏40-60%）
            const hideCount = Math.floor(
                actualNumbersPerGrid * (0.4 + Math.random() * 0.2),
            );
            const hiddenIndices = new Set<number>();

            while (hiddenIndices.size < hideCount) {
                const randomIndex = Math.floor(
                    Math.random() * actualNumbersPerGrid,
                );
                hiddenIndices.add(randomIndex);
            }

            const gridNumbers: (number | null)[] = numbers.map((num, index) =>
                hiddenIndices.has(index) ? null : num,
            );

            // 为每个数字分配颜色（包括null位置）
            const gridColors: (string | null)[] = gridNumbers.map((num) =>
                num ? this.getRandomNumberColor() : null,
            );

            grids.push({ numbers: gridNumbers, colors: gridColors });
        }

        this.missingNumberData = {
            grids,
            maxNumber,
        };
    },

    /**
     * 获取随机数字颜色
     */
    getRandomNumberColor(): string {
        return getRandomNumberColor();
    },

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