import LetterTracingDraw from '../shared/draw/letterTracingDraw';
import { createPage, type CanvasDataState } from '../../base/pageMixin';
import { defaultShareConfig } from '../../config/config';
import { getWorksheetById } from '../../core/data/worksheets';
import {
    generateLetterTracing,
    mergeLetterTracingConfig,
    type LetterTracingGeneratorConfig,
    type LetterTracingMode,
} from '../../core/generators/letter-tracing-generator';
import { LETTERS_UPPER } from '../../core/data/alphabet';

const PAGE_META: Record<string, { title: string; desc: string }> = {
    'letter-tracing-single': {
        title: '字母学习页',
        desc: '单字母配图与描红',
    },
    'letter-tracing-full': {
        title: '26 字母描红',
        desc: '整页字母书写练习',
    },
    'letter-tracing-upper-lower': {
        title: '大小写字母对照',
        desc: '一页认识 A-Z 与 a-z',
    },
    'letter-tracing-two-column': {
        title: '字母描红（两列）',
        desc: 'A–M / N–Z 两列练习',
    },
};

function pageInfoLookup(id: string) {
    return PAGE_META[id];
}

const MODE_OPTIONS = [
    { id: 'letter-tracing-single', label: '单字母学习页' },
    { id: 'letter-tracing-full', label: '整页描红' },
    { id: 'letter-tracing-upper-lower', label: '大小写对照' },
    { id: 'letter-tracing-two-column', label: '两列描红' },
] as const;

type PageData = CanvasDataState & {
    worksheetId: string;
    traceMode: LetterTracingMode;
    selectedLetter: string;
    letterCaseLower: boolean;
    showLetterPicker: boolean;
    showCaseToggle: boolean;
    showNextLetter: boolean;
    letterGrid: string[];
    modeOptions: ReadonlyArray<{ id: string; label: string }>;
};

createPage(
    {
        canvas: null as Canvas | null,
        ctx: null as RenderingContext | null,
        boxHeight: 0,
        boxWidth: 0,
        drawService: null as LetterTracingDraw | null,

        data: {
            pageTitle: '字母描红',
            functionId: '',
            hasContent: false,
            showShareDialog: false,
            worksheetId: 'letter-tracing-single',
            traceMode: 'single-letter',
            selectedLetter: 'A',
            letterCaseLower: false,
            showLetterPicker: true,
            showCaseToggle: false,
            showNextLetter: true,
            letterGrid: LETTERS_UPPER,
            modeOptions: [...MODE_OPTIONS],
        } as unknown as PageData,

        onLoad(options: { id?: string }) {
            const worksheetId =
                options.id && PAGE_META[options.id]
                    ? options.id
                    : 'letter-tracing-single';
            this.applyWorksheet(worksheetId);
        },

        onSelectMode(e: WechatMiniprogram.TouchEvent) {
            const id = e.currentTarget.dataset.id as string | undefined;
            if (!id || id === this.data.worksheetId) return;
            this.applyWorksheet(id, {
                preserveLetter: true,
                redraw: true,
            });
        },

        onReady() {
            this.initCanvas({
                createDrawService: (
                    canvas: Canvas,
                    ctx: RenderingContext,
                    options?: Record<string, unknown>,
                ) => new LetterTracingDraw(canvas, ctx, options),
                drawServiceOptions: {
                    title: this.data.pageTitle,
                    subTitle: this.data.subTitle || '',
                },
                onCanvasReady: () => {
                    this.drawCanvas();
                },
            });
        },

        buildRuntimeConfig(): LetterTracingGeneratorConfig {
            const def = getWorksheetById(this.data.worksheetId);
            const base = (def?.generatorConfig ??
                {}) as Partial<LetterTracingGeneratorConfig>;
            const letterCase =
                this.data.traceMode === 'single-letter'
                    ? (base.letterCase ?? 'upper')
                    : this.data.letterCaseLower
                      ? 'lower'
                      : 'upper';
            return mergeLetterTracingConfig(base, {
                selectedLetter: this.data.selectedLetter,
                letterCase,
            });
        },

        async drawCanvas() {
            if (!this.ctx || !this.drawService) return;
            try {
                const config = this.buildRuntimeConfig();
                const data = generateLetterTracing(config);
                await (this.drawService as LetterTracingDraw).draw(data);
                this.setData({ hasContent: true });
            } catch (e) {
                console.error('letterTracing draw failed', e);
                this.setData({ hasContent: false });
            }
        },

        onSelectLetter(e: WechatMiniprogram.TouchEvent) {
            const letter = e.currentTarget.dataset.letter as string;
            if (!letter) return;
            this.setData({ selectedLetter: letter });
            this.drawCanvas();
        },

        onSelectCaseUpper() {
            this.setData({ letterCaseLower: false });
            this.drawCanvas();
        },

        onSelectCaseLower() {
            this.setData({ letterCaseLower: true });
            this.drawCanvas();
        },

        onNextLetter() {
            const list = LETTERS_UPPER;
            const i = list.indexOf(this.data.selectedLetter);
            const next = list[(i + 1) % list.length];
            this.setData({ selectedLetter: next });
            this.drawCanvas();
        },

        applyWorksheet(
            worksheetId: string,
            options?: {
                preserveLetter?: boolean;
                redraw?: boolean;
            },
        ) {
            const def = getWorksheetById(worksheetId);
            const base = (def?.generatorConfig ??
                {}) as Partial<LetterTracingGeneratorConfig>;
            const merged = mergeLetterTracingConfig(base, {});

            const traceMode = merged.mode;
            const showLetterPicker = traceMode === 'single-letter';
            const showCaseToggle =
                traceMode === 'full-alphabet' || traceMode === 'two-column';
            const showNextLetter = traceMode === 'single-letter';
            const selectedLetter = options?.preserveLetter
                ? this.data.selectedLetter
                : normalizePick(merged.selectedLetter);
            const letterCaseLower =
                traceMode === 'single-letter'
                    ? merged.letterCase === 'lower'
                    : this.data.letterCaseLower;

            this.setData(
                {
                    worksheetId,
                    functionId: worksheetId,
                    traceMode,
                    selectedLetter,
                    letterCaseLower,
                    showLetterPicker,
                    showCaseToggle,
                    showNextLetter,
                },
                () => {
                    this.initPageInfo(
                        worksheetId,
                        PAGE_META[worksheetId]?.title ?? '字母描红',
                    );

                    if (this.drawService) {
                        this.drawService.options.title = this.data.pageTitle;
                        this.drawService.options.subTitle =
                            this.data.subTitle || '';
                    }

                    if (options?.redraw) {
                        this.drawCanvas();
                    }
                },
            );
        },
    },
    {
        shareConfig: defaultShareConfig,
        pageInfoLookup,
    },
);

function normalizePick(c?: string): string {
    if (!c || c.length === 0) return 'A';
    return c.trim().toUpperCase().charAt(0);
}
