
import { Label } from 'cc';
import { Logger } from './Logger';

/*
----------------------------------------------- 基础用法
const typewriter = new VerbatimEffect(this.label, {
    speed: 0.1,       // 每个字符显示间隔
    delay: 1.0,       // 开始前的延迟
    callbackDelay: 0.5 // 完成回调延迟
});
//添加文字
typewriter.addText("第一段文字")
         .addText("第二段文字")
         .addText(["第三段文字", "第四段文字"]);
//设置回调
typewriter.onComplete(() => {
    Logger.log("所有文字显示完成");
});
//开始播放
typewriter.start();
----------------------------------------------- 显示数组用法
const verseArr = this.seleteData.verse.split("，");
const typewriter = new VerbatimEffect(this.verseLabel1, {
    speed: 0.15,
    preserveSpaces: true // 保留空格
});
typewriter.addText(verseArr)
         .onTextComplete((text, index) => {
             Logger.log(`第${index + 1}句显示完成: ${text}`);
         })
         .onComplete(() => {
             Logger.log("所有诗句显示完成");
         })
         .start();
----------------------------------------------- 高阶用法
const typewriter = new VerbatimEffect(this.label);
typewriter.addText("Hello World!")
    .addText("This is Typewriter Effect.")
    .onChar((char) => {
        // 每个字符显示时的音效
        AudioManager.playTypingSound();
    })
    .onTextStart((text, index) => {
        Logger.log(`开始显示第${index + 1}段文字: ${text}`);
    })
    .onTextComplete((text, index) => {
        Logger.log(`第${index + 1}段文字显示完成: ${text}`);
    })
    .onComplete(() => {
        Logger.log("全部文字显示完成");
    })
    .start();
*/


/**
 * 打字机效果配置选项
 */
interface WriterOptions {
    /** 每个字符的显示间隔时间（秒）默认0.1 */
    speed?: number;
    /** 开始播放前的延迟时间（秒）默认0 */
    delay?: number;
    /** 播放完成后的回调延迟（秒）默认0 */
    callbackDelay?: number;
    /** 是否自动开始播放 默认true */
    autoStart?: boolean;
    /** 是否保留空格 默认false */
    preserveSpaces?: boolean;
}

/**
 * 打字机效果类 - 实现文字逐字显示效果
 */
export class VerbatimEffect {
    private label: Label;
    private textQueue: string[] = [];
    private currentIndex: number = 0;
    private isPlaying: boolean = false;
    private options: WriterOptions;
    private onCompleteCallback: Function | null = null;
    private onCharCallback: ((char: string) => void) | null = null;
    private onTextStartCallback: ((text: string, index: number) => void) | null = null;
    private onTextCompleteCallback: ((text: string, index: number) => void) | null = null;

    /**
     * 构造函数
     * @param label 要显示文字的Label组件
     * @param options 配置选项
     */
    constructor(label: Label, options: WriterOptions = {}) {
        this.label = label;
        this.options = {
            speed: 0.1,
            delay: 0,
            callbackDelay: 0,
            autoStart: true,
            preserveSpaces: false,
            ...options
        };
    }

    /**
     * 添加要显示的文字
     * @param text 文字内容（可以是字符串或字符串数组）
     * @return 当前实例（支持链式调用）
     */
    public addText(text: string | string[]): VerbatimEffect {
        if (Array.isArray(text)) {
            this.textQueue.push(...text);
        } else {
            this.textQueue.push(text);
        }
        return this;
    }

    /**
     * 设置完成回调
     * @param callback 所有文字显示完成后的回调
     * @return 当前实例（支持链式调用）
     */
    public onComplete(callback: Function): VerbatimEffect {
        this.onCompleteCallback = callback;
        return this;
    }

    /**
     * 设置字符显示回调
     * @param callback 每个字符显示时的回调
     * @return 当前实例（支持链式调用）
     */
    public onChar(callback: (char: string) => void): VerbatimEffect {
        this.onCharCallback = callback;
        return this;
    }

    /**
     * 设置单个文本开始显示回调
     * @param callback 单个文本开始显示时的回调
     * @return 当前实例（支持链式调用）
     */
    public onTextStart(callback: (text: string, index: number) => void): VerbatimEffect {
        this.onTextStartCallback = callback;
        return this;
    }

    /**
     * 设置单个文本显示完成回调
     * @param callback 单个文本显示完成时的回调
     * @return 当前实例（支持链式调用）
     */
    public onTextComplete(callback: (text: string, index: number) => void): VerbatimEffect {
        this.onTextCompleteCallback = callback;
        return this;
    }

    /**
     * 开始播放文字
     */
    public start(): void {
        if (this.isPlaying || this.textQueue.length === 0) return;
        this.isPlaying = true;
        this.currentIndex = 0;
        this.label.node.active = true;
        this.label.string = '';
        if (this.options.delay && this.options.delay > 0) {
            this.label.scheduleOnce(() => this.playNextText(), this.options.delay);
        } else {
            this.playNextText();
        }
    }

    /**
     * 停止播放
     */
    public stop(): void {
        this.isPlaying = false;
        this.label.unscheduleAllCallbacks();
    }

    /**
     * 跳过当前文本，立即显示完整内容
     */
    public skipCurrent(): void {
        if (!this.isPlaying) return;
        this.label.unscheduleAllCallbacks();
        const currentText = this.textQueue[this.currentIndex];
        this.label.string = this.options.preserveSpaces ? currentText : currentText.replace(/\s/g, '');
        
        this.handleTextComplete(currentText, this.currentIndex);
    }

    /**
     * 跳过所有，立即显示所有完整内容
     */
    public skipAll(): void {
        if (!this.isPlaying) return;
        this.stop();
        let fullText = '';
        for (let i = this.currentIndex; i < this.textQueue.length; i++) {
            fullText += this.options.preserveSpaces 
                ? this.textQueue[i] 
                : this.textQueue[i].replace(/\s/g, '');
        }
        this.label.string = fullText;
        if (this.onCompleteCallback) {
            this.executeCallback(this.onCompleteCallback, this.options.callbackDelay);
        }
    }

    /**
     * 清空文字队列
     */
    public clear(): void {
        this.stop();
        this.textQueue = [];
        this.currentIndex = 0;
    }

    /**
     * 播放下一个文本（内部方法）
     */
    private playNextText(): void {
        if(!this.isPlaying || this.currentIndex >= this.textQueue.length) {
            this.isPlaying = false;
            if (this.onCompleteCallback) {
                this.executeCallback(this.onCompleteCallback, this.options.callbackDelay);
            }
            return;
        }
        const currentText = this.textQueue[this.currentIndex];
        const processedText = this.options.preserveSpaces ? currentText : currentText.replace(/\s/g, '');
        const chars = processedText.split('');
        let currentPos = 0;
        let displayText = '';
        //触发文本开始回调
        if(this.onTextStartCallback) {
            this.onTextStartCallback(currentText, this.currentIndex);
        }
        const updateFunc = () => {
            if (!this.isPlaying) return;
            const char = chars[currentPos];
            displayText += char;
            this.label.string = displayText;
            //触发字符回调
            if(this.onCharCallback) {
                this.onCharCallback(char);
            }
            if (++currentPos >= chars.length) {
                this.label.unschedule(updateFunc);
                this.handleTextComplete(currentText, this.currentIndex++);
            }
        };

        this.label.schedule(updateFunc, this.options.speed, chars.length - 1, 0);
    }

    /**
     * 处理文本完成（内部方法）
     */
    private handleTextComplete(text: string, index: number): void {
        //触发文本完成回调
        if (this.onTextCompleteCallback) {
            this.onTextCompleteCallback(text, index);
        }
        //播放下一个文本
        this.playNextText();
    }

    /**
     * 执行回调（带延迟）
     */
    private executeCallback(callback: Function, delay: number = 0): void {
        if (delay && delay > 0) {
            this.label.scheduleOnce(() => callback(), delay);
        } else {
            callback();
        }
    }
}