import WordDrawService from '../../service/wordDrawService';
import { downloadPrint } from '../../utils/downloadPrint';
import { PAPER_SIZE } from '../../constants/colors';
import { getWordsSvgData } from '../../utils/getWordsSvgJson';
import { WORDS } from '../../constants/words';
import { CharacterItem } from '../../types/characterType';
import tracker from '../../utils/tracker';
import { defaultShareConfig } from '../../config/config';

Page({
    canvas: null as Canvas | null,
    ctx: null as RenderingContext | null,
    wordDrawService: null as WordDrawService | null,
    svgWords: {} as Record<string, string[]>,
    maxRow: 0 as number,
    maxCol: 0 as number,

    data: {
        // 最终的汉字列表（合并输入和选择的汉字）
        words: [] as string[],
        // 来自文本框输入的汉字（每次输入替换）
        inputWords: [] as string[],
        // 来自弹窗选择的汉字（追加）
        selectedWords: [] as string[],
        // 输入框的值（用于清空）
        inputValue: '',
        showSelectWordPopup: false,
        showColorPopup: false,
        currentKey: 0,
        currentColor: '',
        boxWidth: 0,
        boxHeight: 0,
        showShareDialog: false, // 显示分享引导弹窗
    },

    async onLoad() {
        await this.loadSvgWords();
        const hasShowPracticeDemo =
            wx.getStorageSync('hasShowPracticeDemo') || false;
        if (!hasShowPracticeDemo) {
            const demoWords = ['好', '好', '学', '习', '天', '天', '向', '上'];
            this.setData(
                {
                    words: demoWords,
                    inputWords: demoWords,
                    selectedWords: [],
                },
                () => {
                    wx.setStorageSync('hasShowPracticeDemo', true);
                },
            );
        }
        await this.setCanvasBoxSize();
        await this.initCanvas();
    },

    async loadSvgWords() {
        try {
            wx.showToast({ title: '加载字体中...', icon: 'loading' });
            // 使用带缓存的SVG汉字数据获取函数
            const svgWordsData = await getWordsSvgData();

            this.svgWords = svgWordsData;
            wx.hideToast();

            console.log(
                'SVG汉字数据加载成功，共',
                Object.keys(this.svgWords).length,
                '个汉字',
            );

            const { words } = this.data as any;
            if (words && words.length > 0) {
                this.renderPracticeContent().catch(console.error);
            }
        } catch (error) {
            console.error('加载SVG汉字数据失败:', error);
            wx.hideToast();

            // 显示错误提示
            wx.showModal({
                title: '加载失败',
                content: '无法加载汉字数据，请检查网络连接后重试',
                showCancel: true,
                cancelText: '取消',
                confirmText: '重试',
                success: (res) => {
                    if (res.confirm) {
                        // 用户点击重试，重新加载
                        this.loadSvgWords();
                    }
                },
            });
        }
    },

    // 输入组件回调（所见即所得：替换文本框输入的汉字）
    onConfirmInput(e: any) {
        const value: string = (e && e.detail && e.detail.value) || '';
        const text = (value || '').trim();
        
        // 如果文本框为空，清空输入汉字
        if (!text) {
            const { selectedWords } = this.data as any;
            const updatedWords = [...selectedWords];
            this.setData(
                {
                    inputWords: [],
                    words: updatedWords,
                    inputValue: '', // 同步清空输入框值
                },
                () => {
                    this.renderPracticeContent().catch(console.error);
                },
            );
            return;
        }

        if (!this.isChineseText(text)) {
            wx.showToast({ title: '请输入汉字', icon: 'none' });
            return;
        }

        // 1. 解析输入的汉字
        const newInputChars = this.splitToSingleChars(text);
        if (newInputChars.length === 0) {
            wx.showToast({ title: '请输入有效汉字', icon: 'none' });
            return;
        }

        const { selectedWords } = this.data as any;

        // 2. 检查是否超过限制（输入汉字 + 已选择的汉字）
        if (newInputChars.length + selectedWords.length > 11) {
            wx.showToast({
                title: `最多只能添加 11 个字，当前已选择 ${selectedWords.length} 个，输入了 ${newInputChars.length} 个`,
                icon: 'none',
                duration: 3000,
            });
            return;
        }

        // 3. 替换输入汉字（不是追加），合并已选择的汉字
        const updatedWords = [...newInputChars, ...selectedWords];

        // 4. 更新数据并提示（同步更新 inputValue 保持一致）
        this.setData(
            {
                inputWords: newInputChars,
                words: updatedWords,
                inputValue: text, // 同步输入框值
            },
            () => {
                this.renderPracticeContent().catch(console.error);
            },
        );

        // 5. 显示添加结果提示
        wx.showToast({
            title: `已更新输入汉字（${newInputChars.length} 个）`,
            icon: 'none',
            duration: 2000,
        });
    },

    // 选择面板
    openSelectWordPopup() {
        this.setData({ showSelectWordPopup: true });
    },
    closeSelectWordPopup() {
        this.setData({ showSelectWordPopup: false });
    },
    onChangeWord(e: any) {
        const newSelectedWords = e.detail.selectedWords as string[];
        const { inputWords } = this.data as any;

        // 检查是否超过限制
        if (inputWords.length + newSelectedWords.length > 11) {
            wx.showToast({
                title: `最多只能添加 11 个字，当前输入 ${inputWords.length} 个，选择了 ${newSelectedWords.length} 个`,
                icon: 'none',
                duration: 3000,
            });
            return;
        }

        // 合并输入汉字和选择的汉字（求并集）
        const updatedWords = [...inputWords, ...newSelectedWords];
        this.setData(
            {
                selectedWords: newSelectedWords,
                words: updatedWords,
                showSelectWordPopup: false,
            },
            () => {
                if (updatedWords && updatedWords.length > 0) {
                    this.renderPracticeContent().catch(console.error);
                }
            },
        );
    },

    // 删除（需要判断删除的是输入汉字还是选择的汉字）
    deleteWordCard(e: any) {
        const { key } = e.detail;
        const { inputWords, selectedWords } = this.data as any;
        
        // 判断删除的是输入汉字还是选择的汉字
        if (key < inputWords.length) {
            // 删除的是输入汉字
            const nextInputWords = inputWords.filter(
                (_: string, index: number) => index !== key,
            );
            const nextWords = [...nextInputWords, ...selectedWords];
            this.setData(
                {
                    inputWords: nextInputWords,
                    words: nextWords,
                },
                () => this.renderPracticeContent().catch(console.error),
            );
        } else {
            // 删除的是选择的汉字
            const selectedIndex = key - inputWords.length;
            const nextSelectedWords = selectedWords.filter(
                (_: string, index: number) => index !== selectedIndex,
            );
            const nextWords = [...inputWords, ...nextSelectedWords];
            this.setData(
                {
                    selectedWords: nextSelectedWords,
                    words: nextWords,
                },
                () => this.renderPracticeContent().catch(console.error),
            );
        }
    },

    // 清空（清空所有来源的汉字：文本框、预览、弹窗选择）
    clearWords() {
        // 清空所有汉字数据
        this.setData(
            {
                words: [],
                inputWords: [],
                selectedWords: [],
                inputValue: '', // 清空输入框
            },
            () => {
                this.renderPracticeContent().catch(console.error);
            },
        );

        // 关闭弹窗（如果打开）
        if (this.data.showSelectWordPopup) {
            this.setData({ showSelectWordPopup: false });
        }
    },

    // 随机生成（取基础分类，过滤为可用SVG字，最多11个）
    refreshWords() {
        // 选取较简单的几个分类（如 0:基础独体字，1:生活高频字，2:自然与动作）
        const candidate = WORDS.slice(0, 3).reduce(
            (acc: string[], c: any) => acc.concat(c.words),
            [] as string[],
        );
        // 去重
        const unique = Array.from(new Set(candidate));
        // 打乱
        const shuffled = unique.sort(() => Math.random() - 0.5);
        // 先取前 11 个
        const picked = shuffled.slice(0, 10);
        // 过滤为支持的SVG字
        const supported = this.getSupportedWords(picked);
        if (supported.length === 0) {
            wx.showToast({
                title: '随机到的字暂不支持，重试一下',
                icon: 'none',
            });
            return;
        }
        this.setData({ words: supported }, () =>
            this.renderPracticeContent().catch(console.error),
        );
    },

    // 校验 & 分割
    isChineseText(text: string): boolean {
        const chineseRegex = /^[\u4e00-\u9fff]+$/;
        return chineseRegex.test(text);
    },
    splitToSingleChars(text: string): string[] {
        const chineseRegex = /[\u4e00-\u9fff]/g;
        const matches = text.match(chineseRegex);
        return matches || [];
    },

    setCanvasBoxSize() {
        const query = wx.createSelectorQuery();
        query
            .select('#canvasWrapper')
            .boundingClientRect((rect) => {
                if (rect) {
                    const { width, height } = PAPER_SIZE['A4'];
                    const boxWidth = rect.width;
                    const boxHeight = boxWidth / (width / height);
                    this.setData({ boxWidth, boxHeight });
                }
            })
            .exec();
    },
    async initCanvas() {
        return new Promise<void>((resolve) => {
            // 然后初始化canvas
            wx.createSelectorQuery()
                .select('#canvasContent')
                .fields({
                    node: true,
                    size: true,
                })
                .exec(async (res) => {
                    if (res[0] && res[0].node) {
                        const canvas = res[0].node;
                        const ctx = canvas.getContext('2d');
                        if (ctx) {
                            this.canvas = canvas;
                            this.ctx = ctx;
                            this.wordDrawService = new WordDrawService(
                                canvas,
                                ctx,
                            );

                            // 初始化时只绘制页眉和布局
                            await this.wordDrawService.drawLayout();

                            // 绘制完成后计算并缓存最大行列数（与实际绘制一致）
                            const { maxRow, maxCol } =
                                this.wordDrawService.getMaxGridLayout();
                            this.maxRow = maxRow;
                            this.maxCol = maxCol;

                            // 如果有汉字数据，绘制练字内容
                            const { words } = this.data as any;
                            if (words && words.length > 0) {
                                await this.renderPracticeContent();
                            }

                            resolve();
                        }
                    }
                });
        });
    },

    // 绘制练字内容（只绘制田字格和汉字内容）
    async renderPracticeContent() {
        if (!this.canvas || !this.wordDrawService) {
            await this.initCanvas();
            return;
        }

        const { words } = this.data as any;

        if (!words || words.length === 0) {
            this.wordDrawService.drawContentEmpty();
            return;
        }

        // 检查汉字是否支持
        const supportedWords = this.getSupportedWords(words);
        if (supportedWords.length === 0) {
            wx.showToast({ title: '暂不支持这些汉字', icon: 'none' });
            this.wordDrawService.drawContentEmpty();
            return;
        }

        // 使用初始化阶段缓存的最大行列数；若未初始化则计算一次并缓存
        let maxRow = this.maxRow;
        let maxCol = this.maxCol;
        if (!maxRow || !maxCol) {
            const layout = this.wordDrawService!.getMaxGridLayout();
            this.maxRow = layout.maxRow;
            this.maxCol = layout.maxCol;
            maxRow = layout.maxRow;
            maxCol = layout.maxCol;
        }

        // 处理布局和生成练字数据（基于实际最大行列数）
        const characterData = this.processCharacterLayout(
            supportedWords,
            maxRow,
            maxCol,
        );
        this.wordDrawService.drawPracticeContent(characterData);
    },

    /** 检查汉字是否支持，返回支持的汉字列表 */
    getSupportedWords(words: string[]): string[] {
        return words.filter((word) => this.svgWords[word]);
    },

    /** 处理汉字布局，生成练字数据 */
    processCharacterLayout(
        words: string[],
        maxRow: number,
        maxCol: number,
    ): CharacterItem[] {
        let rowIndex = 0;
        const characterData: CharacterItem[] = [];
        const boundaryWords: string[] = [];

        // 按顺序处理每个汉字
        words.forEach((word: string) => {
            const strokes = this.svgWords[word];
            const strokeCount = strokes.length;
            const totalCells = 1 + strokeCount + 0; // 预览格 + 练习格 + 空白格
            const totalRows = Math.ceil(totalCells / maxCol);

            // 这里的意思是：把这一个汉字所占的行数（totalRows）累加到 rowIndex 上。
            // 这样 rowIndex 就记录了当前已经排布了多少行，用于判断是否超出了最大允许行数（maxRow）。
            rowIndex = rowIndex + totalRows;

            if (rowIndex <= maxRow) {
                characterData.push({ character: word, strokes });
            } else {
                boundaryWords.push(word);
            }
        });
        // // 提示超出页面的汉字
        // if (showToast && boundaryWords.length > 0) {
        //     wx.showToast({
        //         title: `练字贴已超过一页，部分汉字未包含在本次生成结果中`,
        //         icon: 'none'
        //     });
        // }

        return characterData;
    },

    // 下载打印练字贴
    async exportToPrint() {
        await downloadPrint(this.canvas, {
            errorToast: '请先生成练字贴',
            trackerName: '练字贴',
        });
    },

    // 分享功能
    onShareAppMessage() {
        // 上报分享埋点
        tracker.reportShare('练字贴');

        return {
            ...defaultShareConfig,
            path: '/pages/copyBook/copyBook',
        };
    },
    onShareTimeline() {
        // 上报分享埋点
        tracker.reportShare('练字贴');

        return {
            ...defaultShareConfig,
            query: '/pages/copyBook/copyBook',
        };
    },

    /** 分享成功回调（由组件触发） */
    onShareSuccess() {
        // 只关闭弹窗，不触发下载
        this.setData({ showShareDialog: false });
    },
});
