import ClockReadingDraw from './draw/clockReadingDraw';
import ClockConnectDraw from './draw/clockConnectDraw';
import {
    buildClockReadingData,
    type ClockReadingTimeMode,
} from './generators/clock-generator';
import { buildClockConnectData } from './generators/clock-connect-generator';
import { createPage, type CanvasDataState } from '../../base/pageMixin';
import { defaultShareConfig } from '../../config/config';
import {
    getModeInfo,
    getPublishMetaByMode,
    isValidMode,
    CLOCK_TIME_MODE_OPTIONS,
    CLOCK_EXERCISE_TYPE_OPTIONS,
    type ClockTimeMode,
    type ClockExerciseType,
} from './clockReading.config';
import type { DebugPublishMeta } from '../../utils/debugPublish';
import {
    addFavorite,
    removeFavorite,
    batchCheckFavorited,
} from '../../utils/favorites';
import type { BaseDrawService } from '../../core/draw/baseDraw';

const pageInfoLookup = getModeInfo;
const DEFAULT_WORKSHEET_ID = 'clock-reading';

type PageData = CanvasDataState & {
    worksheetId: string;
    timeMode: ClockTimeMode;
    timeModeOptions: typeof CLOCK_TIME_MODE_OPTIONS;
    exerciseType: ClockExerciseType;
    exerciseTypeOptions: typeof CLOCK_EXERCISE_TYPE_OPTIONS;
    isPreviewFavorite: boolean;
    isDevEnv: boolean;
    debugPublishVisible: boolean;
    debugPublishLoading: boolean;
    debugPublishMeta: DebugPublishMeta | null;
};

createPage(
    {
        canvas: null as Canvas | null,
        ctx: null as RenderingContext | null,
        boxHeight: 0,
        boxWidth: 0,
        drawService: null as BaseDrawService | null,
        _favoritedMap: {} as Record<string, boolean>,

        data: {
            pageTitle: '认识钟表',
            functionId: DEFAULT_WORKSHEET_ID,
            hasContent: false,
            showShareDialog: false,
            worksheetId: DEFAULT_WORKSHEET_ID,
            timeMode: 'random' as ClockTimeMode,
            timeModeOptions: CLOCK_TIME_MODE_OPTIONS,
            exerciseType: 'clock-reading' as ClockExerciseType,
            exerciseTypeOptions: CLOCK_EXERCISE_TYPE_OPTIONS,
            isPreviewFavorite: false,
            isDevEnv: false,
            debugPublishVisible: false,
            debugPublishLoading: false,
            debugPublishMeta: null,
        } as unknown as PageData,

        onLoad(options: { id?: string }) {
            const worksheetId =
                options.id && isValidMode(options.id)
                    ? options.id
                    : DEFAULT_WORKSHEET_ID;

            this.syncDebugPublishEnv();

            // 根据传入 id 判断练习类型
            const exerciseType: ClockExerciseType =
                worksheetId === 'clock-connect' ? 'clock-connect' : 'clock-reading';
            this.setData({ exerciseType });

            this.applyWorksheet(worksheetId);
            this.loadFavoritedMap();
        },

        onSelectTimeMode(e: WechatMiniprogram.TouchEvent) {
            const mode = e.currentTarget.dataset.mode as
                | ClockTimeMode
                | undefined;
            if (!mode || mode === this.data.timeMode) return;
            this.setData({ timeMode: mode }, () => this.drawCanvas());
        },

        onSelectExerciseType(e: WechatMiniprogram.TouchEvent) {
            const type = e.currentTarget.dataset.type as
                | ClockExerciseType
                | undefined;
            if (!type || type === this.data.exerciseType) return;

            const worksheetId = type;
            this.setData({ exerciseType: type });
            this.applyWorksheet(worksheetId);

            // 切换练习类型需要重新创建 drawService
            this.recreateDrawService();
        },

        onCanvasReady(e: WechatMiniprogram.CustomEvent) {
            this.initCanvasFromComponent(e.detail, {
                createDrawService: (
                    canvas: Canvas,
                    ctx: RenderingContext,
                    options?: Record<string, unknown>,
                ) => this.createDrawForType(canvas, ctx, options),
                drawServiceOptions: {
                    title: this.data.pageTitle,
                },
                onCanvasReady: () => {
                    this.drawCanvas();
                },
            });
        },

        createDrawForType(
            canvas: Canvas,
            ctx: RenderingContext,
            options?: Record<string, unknown>,
        ): BaseDrawService {
            if (this.data.exerciseType === 'clock-connect') {
                return new ClockConnectDraw(canvas, ctx, options);
            }
            return new ClockReadingDraw(canvas, ctx, options);
        },

        recreateDrawService() {
            if (!this.canvas || !this.ctx) return;
            const options = { title: this.data.pageTitle };
            this.drawService = this.createDrawForType(
                this.canvas,
                this.ctx,
                options,
            );
            this.drawCanvas();
        },

        async drawCanvas() {
            if (!this.ctx || !this.drawService) return;
            try {
                if (this.data.exerciseType === 'clock-connect') {
                    const data = buildClockConnectData(
                        this.data.timeMode as ClockTimeMode,
                    );
                    await (this.drawService as ClockConnectDraw).draw(data);
                } else {
                    const data = buildClockReadingData(
                        this.data.timeMode as ClockReadingTimeMode,
                    );
                    await (this.drawService as ClockReadingDraw).draw(data);
                }
                this.setData({ hasContent: true });
            } catch (e) {
                console.error('clock draw failed', e);
                this.setData({ hasContent: false });
            }
        },

        onPreviewRefresh() {
            this.drawCanvas();
        },

        async onPreviewFavorite() {
            const next = !this.data.isPreviewFavorite;
            this.setData({ isPreviewFavorite: next });
            const id = this.data.worksheetId;
            if (id && this._favoritedMap) {
                this._favoritedMap[id] = next;
                if (next) {
                    addFavorite(id);
                } else {
                    removeFavorite(id);
                }
            }
            wx.showToast({
                title: next ? '收藏成功' : '已取消收藏',
                icon: 'none',
            });
        },

        async loadFavoritedMap() {
            const ids = ['clock-reading', 'clock-connect'];
            this._favoritedMap = await batchCheckFavorited(ids);
            if (this._favoritedMap?.[this.data.worksheetId]) {
                this.setData({ isPreviewFavorite: true });
            }
        },

        getPublishMeta(): DebugPublishMeta {
            const meta = getPublishMetaByMode(this.data.worksheetId);
            if (!meta) {
                throw new Error('当前题型配置不存在');
            }
            return meta;
        },

        getWorksheetStatsId() {
            return this.data.worksheetId;
        },

        applyWorksheet(worksheetId: string) {
            if (!isValidMode(worksheetId)) return;

            this.setData(
                {
                    worksheetId,
                    functionId: worksheetId,
                    isPreviewFavorite: !!this._favoritedMap?.[worksheetId],
                },
                () => {
                    this.initPageInfo(worksheetId, '认识钟表');
                    if (this.drawService) {
                        this.drawService.options.title = this.data.pageTitle;
                    }
                },
            );
        },
    },
    {
        shareConfig: defaultShareConfig,
        pageInfoLookup,
    },
);
