import { WATER_COLORS, PAPER_SIZE } from '../../constants/colors';
import { WORDS } from '../../constants/words';
import {
    DrawServiceFactory,
    IDrawService,
    TemplateType,
} from '../../service/drawServiceFactory';
import { downloadPrint } from '../../utils/downloadPrint';
import tracker from '../../utils/tracker';
import { defaultShareConfig } from '../../config/config';

Page({
    canvas: null as Canvas | null,
    ctx: null as RenderingContext | null,
    boxHeight: 0,
    boxWidth: 0,
    drawService: null as IDrawService | null,

    data: {
        cardList: [] as CardList,
        selectedWords: [] as string[],
        showColorPopup: false,
        currentKey: 0,
        currentColor: '',
        showIntroductionPopup: false,
        showSelectWordPopup: false, // 选择文字弹窗
        selectedTemplate: 'grid', // 选中的模板类型 grid 或 find 模式
        env: 'release',
        isPCDevtool: false,
        showShareDialog: false, // 显示分享引导弹窗
    },

    onLoad(options: { template?: string }) {
        const { template } = options;
        this.setData({
            selectedTemplate: template || 'grid',
        });

        const hasShowIntroduction =
            wx.getStorageSync('hasShowIntroduction') || false;

        // 判断是否在PC端开发工具上运行
        const systemInfo = wx.getDeviceInfo();
        if (systemInfo.platform === 'devtools') {
            this.setData({
                isPCDevtool: true,
            });
        }

        if (!hasShowIntroduction) {
            this.setData(
                {
                    cardList: [
                        { color: '#FF0000', word: '涂' },
                        { color: '#00FF00', word: '鸦' },
                        { color: '#FF7F00', word: '丫' },
                        { color: '#00FFFF', word: '欢' },
                        { color: '#FFFF00', word: '迎' },
                        { color: '#8A2BE2', word: '您' },
                    ],
                    selectedWords: ['涂', '鸦', '丫', '欢', '迎', '您'],
                    // showIntroductionPopup: true,
                    env: getApp().globalData.env || 'release',
                },
                () => {
                    this.drawCanvas();
                },
            );
        } else {
            this.setData({
                env: getApp().globalData.env || 'release',
            });
        }
    },

    onReady() {
        // 当cardList为空时，canvas相关元素不会被渲染，所以不需要在这里初始化
        // 尺寸计算将在initCanvas方法中进行
    },

    initCanvas() {
        // 先获取canvasWrapper的尺寸来计算canvas尺寸
        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);

                    // 然后初始化canvas
                    wx.createSelectorQuery()
                        .select('#canvasContent')
                        .fields({
                            node: true,
                            size: true,
                        })
                        .exec((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;
                                    // 根据当前选中的模板类型创建对应的绘制服务
                                    const templateType = this.data
                                        .selectedTemplate as TemplateType;
                                    this.drawService =
                                        DrawServiceFactory.create(
                                            templateType,
                                            canvas,
                                            ctx,
                                        );
                                    this.setData({ boxWidth, boxHeight });

                                    // 初始化完成后，如果有cardList内容则立即绘制
                                    const currentCardList = this.data.cardList;
                                    if (currentCardList.length > 0) {
                                        this.drawService
                                            .draw(currentCardList)
                                            .catch((err: any) => {
                                                console.error('绘制失败:', err);
                                            });
                                    }
                                }
                            }
                        });
                }
            })
            .exec();
    },

    /**
     * 创建或更新绘制服务
     * 根据当前选中的模板类型创建对应的服务实例
     */
    createDrawService() {
        if (this.canvas && this.ctx) {
            const templateType = this.data.selectedTemplate as TemplateType;
            this.drawService = DrawServiceFactory.create(
                templateType,
                this.canvas,
                this.ctx,
            );
        }
    },

    /** 变更cardList 并更新canvas */
    drawCanvas(
        updatedCardList?: Array<{ color: string; word: string }>,
        callback: () => void = () => {},
    ) {
        if (updatedCardList) {
            this.setData(
                {
                    cardList: updatedCardList,
                    selectedWords: updatedCardList.map((item) => item.word),
                },
                () => {
                    // 如果cardList有内容且canvas未初始化，先初始化canvas
                    if (!this.canvas) {
                        this.initCanvas();
                    } else {
                        // 如果canvas已初始化，确保绘制服务是最新的
                        this.createDrawService();
                    }
                    // 如果canvas已初始化且有内容，则绘制
                    if (this.drawService && updatedCardList!.length > 0) {
                        this.drawService.draw(updatedCardList!).catch((err: any) => {
                            console.error('绘制失败:', err);
                        });
                    }
                    callback();
                },
            );
        } else {
            const currentCardList = this.data.cardList;
            // 如果cardList有内容且canvas未初始化，先初始化canvas
            if (!this.canvas) {
                this.initCanvas();
            } else {
                // 如果canvas已初始化，确保绘制服务是最新的
                this.createDrawService();
            }
            // 如果canvas已初始化且有内容，则绘制
            if (this.drawService && currentCardList.length > 0) {
                this.drawService.draw(currentCardList).catch((err: any) => {
                    console.error('绘制失败:', err);
                });
            }
        }
    },

    tapCard(e: WechatMiniprogram.TouchEvent) {
        const { url } = e.currentTarget.dataset;
        wx.navigateTo({ url });
    },

    onConfirmInput(e: WechatMiniprogram.Input) {
        const { cardList } = this.data;
        const { value } = e.detail;
        const characters = value.split('');
        // 计算剩余空间
        const remainingSlots = 6 - cardList.length;
        if (remainingSlots <= 0) {
            wx.showToast({
                title: '最多只能添加6个字哦！',
                icon: 'none',
                duration: 2000,
            });
            return;
        }

        // 准备颜色数组
        const allColors = WATER_COLORS.basic12.map((color) => color.hex);
        const usedColors = cardList.map((item) => item.color);
        const usedWords = cardList.map((item) => item.word);

        const availableColors = allColors.filter(
            (color) => !usedColors.includes(color),
        );
        const shuffledColors = [...availableColors].sort(
            () => Math.random() - 0.5,
        );

        const newCharacters: string[] = [];
        let isBeyond = false;
        for (const char of characters) {
            if (newCharacters.length >= remainingSlots) {
                isBeyond = true;
                break;
            }
            if (!usedWords.includes(char) && !newCharacters.includes(char)) {
                newCharacters.push(char);
            }
        }
        if (isBeyond) {
            wx.showToast({
                title: '最多只能添加6个字，多余的字未被添加哦！',
                icon: 'none',
                duration: 2000,
            });
        }

        // 为新字符创建卡片
        const newCards = newCharacters.map((char) => {
            // 获取字对应的颜色
            const colorHex = this.getColorByWord(char);
            let color: string;

            if (colorHex && !usedColors.includes(colorHex)) {
                // 如果有对应颜色且未被使用,使用对应颜色
                color = colorHex;
            } else {
                // 否则随机选择一个可用颜色
                const randomIndex = Math.floor(
                    Math.random() * shuffledColors.length,
                );
                color = shuffledColors[randomIndex];
                // 从可用颜色中移除已使用的颜色
                shuffledColors.splice(randomIndex, 1);
            }

            return {
                word: char,
                color: color,
            };
        });

        // 合并新旧卡片
        const updatedCardList = [...cardList, ...newCards];
        this.drawCanvas(updatedCardList);
    },

    deleteWordCard(e: WechatMiniprogram.CustomEvent) {
        const { key, word } = e.detail;
        const { cardList } = this.data;
        const updatedCardList = cardList.filter((_, index) => index !== key);
        this.drawCanvas(updatedCardList, () => {
            wx.showToast({
                title: `已删除 "${word}"`,
                icon: 'none',
                duration: 2000,
            });
        });
    },

    /** 下载打印 */
    async exportToPrint() {
        if (!this.canvas || this.data.cardList.length <= 0) {
            return;
        }

        await downloadPrint(this.canvas, {
            errorToast: '请先生成涂色卡',
            trackerName: '涂色识字',
            trackerMode: this.data.selectedTemplate,
        });
    },

    /** 分享成功回调（由组件触发） */
    onShareSuccess() {
        this.setData({ showShareDialog: false });
    },

    onColorTap(e: WechatMiniprogram.CustomEvent) {
        const { key, color } = e.detail;
        this.setData({
            showColorPopup: true,
            currentKey: key,
            currentColor: color,
        });
    },

    onCloseColorPopup() {
        this.setData({
            showColorPopup: false,
            currentKey: 0,
            currentColor: '',
        });
    },

    onChangeColor(e: WechatMiniprogram.CustomEvent) {
        const { color } = e.detail;
        const { currentKey, cardList } = this.data;
        cardList[currentKey].color = color;
        this.setData(
            {
                showColorPopup: false,
                cardList,
            },
            () => {
                this.drawCanvas();
            },
        );
    },

    onCloseIntroductionPopup() {
        this.setData({ showIntroductionPopup: false });
        wx.setStorageSync('hasShowIntroduction', true);
    },

    onShareAppMessage() {
        // 上报分享埋点
        tracker.reportShare('涂色识字');

        return {
            ...defaultShareConfig,
            path: `/pages/index/index?template=${this.data.selectedTemplate}`,
        };
    },
    onShareTimeline() {
        // 上报分享埋点
        tracker.reportShare('涂色识字');

        return {
            ...defaultShareConfig,
            query: `/pages/index/index?template=${this.data.selectedTemplate}`,
        };
    },

    clearCardList() {
        // 清空cardList时，重置canvas相关引用，因为DOM元素会被移除
        this.canvas = null;
        this.ctx = null;
        this.drawService = null;
        this.drawCanvas([]);
    },

    // 随机生成
    refreshCardList() {
        // 获取前4个分类的所有文字
        const allWords = WORDS.slice(0, 2).reduce((acc, category) => {
            return acc.concat(category.words);
        }, [] as string[]);

        // 随机获取6个不重复的文字
        const selectedWords: string[] = [];
        while (selectedWords.length < 6) {
            const randomWord =
                allWords[Math.floor(Math.random() * allWords.length)];
            if (!selectedWords.includes(randomWord)) {
                selectedWords.push(randomWord);
            }
        }

        // 随机获取6个不重复的颜色
        const colors = [...WATER_COLORS.basic12];
        const selectedColors: string[] = [];
        while (selectedColors.length < 6) {
            const randomIndex = Math.floor(Math.random() * colors.length);
            const color = colors.splice(randomIndex, 1)[0];
            selectedColors.push(color.hex);
        }

        // 组合文字和颜色
        const cardList = selectedWords.map((word, index) => ({
            color: selectedColors[index],
            word,
        }));
        this.drawCanvas(cardList);
    },
    openSelectWordPopup() {
        this.setData({
            showSelectWordPopup: true,
        });
    },

    closeSelectWordPopup() {
        this.setData({
            showSelectWordPopup: false,
        });
    },

    // 获取颜色字对应的16进制颜色值
    getColorByWord(word: string): string | null {
        const colorMap: Record<string, string> = {
            红: '#FF0000',
            蓝: '#0000FF',
            绿: '#00FF00',
            黄: '#FFFF00',
            黑: '#000000',
            白: '#FFFFFF',
            紫: '#800080',
            橙: '#FF7F00',
            粉: '#FF69B4',
            棕: '#A52A2A',
            灰: '#808080',
        };
        return colorMap[word] || null;
    },

    onChangeWord(e: WechatMiniprogram.CustomEvent) {
        const selectedWords = e.detail.selectedWords as string[];
        const colors = [...WATER_COLORS.basic12];

        const cardList = selectedWords.map((word, index) => {
            const colorHex = this.getColorByWord(word);
            return {
                color: colorHex || colors[index].hex,
                word,
            };
        });

        this.setData({ showSelectWordPopup: false });
        this.drawCanvas(cardList);
    },

    onDebugEntryTap() {
        wx.navigateTo({
            url: '/pages/debug/debug',
        });
    },

    // 模板选择事件
    onSelectTemplate(e: WechatMiniprogram.TouchEvent) {
        const { template } = e.currentTarget.dataset;
        this.setData(
            {
                selectedTemplate: template,
            },
            () => {
                // 模板切换后，重新创建绘制服务并重新绘制
                if (this.canvas && this.ctx) {
                    this.createDrawService();
                    // 如果有文字卡片，重新绘制canvas
                    if (this.data.cardList.length > 0) {
                        this.drawCanvas();
                    }
                }
            },
        );
    },
});
