---
export interface Props {
    text: string | string[];
    speed?: number;
    deleteSpeed?: number;
    pauseTime?: number;
    class?: string;
}

const {
    text,
    speed = 100,
    deleteSpeed = 50,
    pauseTime = 2000,
    class: className = "",
} = Astro.props;
const textData = Array.isArray(text) ? JSON.stringify(text) : text;
---

<span class={`typewriter ${className}`} data-text={textData} data-speed={speed} data-delete-speed={deleteSpeed} data-pause-time={pauseTime}></span>

<script>
class TypewriterEffect {
    private element: HTMLElement;
    private texts: string[];
    private currentTextIndex: number = 0;
    private speed: number;
    private deleteSpeed: number;
    private pauseTime: number;
    private currentIndex: number = 0;
    private isDeleting: boolean = false;
    private timeoutId: number | null = null;

    constructor(element: HTMLElement) {
        this.element = element;
        const textData = element.dataset.text || '';

        // 尝试解析为JSON数组，如果失败则作为单个字符串处理
        try {
            const parsed = JSON.parse(textData);
            this.texts = Array.isArray(parsed) ? parsed : [textData];
        } catch {
            this.texts = [textData];
        }

        this.speed = parseInt(element.dataset.speed || '100');
        this.deleteSpeed = parseInt(element.dataset.deleteSpeed || '50');
        this.pauseTime = parseInt(element.dataset.pauseTime || '2000');

        // 如果有多条文本且未启用打字机效果，随机显示一条
        if (this.texts.length > 1 && !this.isTypewriterEnabled()) {
            this.showRandomText();
        } else {
            this.start();
        }
    }

    private isTypewriterEnabled(): boolean {
        // 检查是否有打字机相关的数据属性
        return this.element.dataset.speed !== undefined ||
               this.element.dataset.deleteSpeed !== undefined ||
               this.element.dataset.pauseTime !== undefined;
    }

    private showRandomText() {
        const randomIndex = Math.floor(Math.random() * this.texts.length);
        this.element.textContent = this.texts[randomIndex];
    }

    private start() {
        if (this.texts.length === 0) return;
        this.type();
    }

    private getCurrentText(): string {
        return this.texts[this.currentTextIndex] || '';
    }

    private type() {
        const currentText = this.getCurrentText();

        if (this.isDeleting) {
            // 删除字符
            if (this.currentIndex > 0) {
                this.currentIndex--;
                this.element.textContent = currentText.substring(0, this.currentIndex);
                this.timeoutId = window.setTimeout(() => this.type(), this.deleteSpeed);
            } else {
                // 删除完成，切换到下一条文本
                this.isDeleting = false;
                this.currentTextIndex = (this.currentTextIndex + 1) % this.texts.length;
                this.timeoutId = window.setTimeout(() => this.type(), this.speed);
            }
        } else {
            // 添加字符
            if (this.currentIndex < currentText.length) {
                this.currentIndex++;
                this.element.textContent = currentText.substring(0, this.currentIndex);
                this.timeoutId = window.setTimeout(() => this.type(), this.speed);
            } else {
                // 打字完成，暂停后开始删除（如果有多条文本）
                if (this.texts.length > 1) {
                    this.isDeleting = true;
                    this.timeoutId = window.setTimeout(() => this.type(), this.pauseTime);
                }
                // 如果只有一条文本，保持显示不删除
            }
        }
    }

    public destroy() {
        if (this.timeoutId) {
            clearTimeout(this.timeoutId);
        }
    }
}

// 初始化所有打字机效果
document.addEventListener('DOMContentLoaded', () => {
    const typewriterElements = document.querySelectorAll('.typewriter');
    typewriterElements.forEach((element) => {
        new TypewriterEffect(element as HTMLElement);
    });
});

// 支持页面切换时重新初始化
document.addEventListener('swup:contentReplaced', () => {
    const typewriterElements = document.querySelectorAll('.typewriter');
    typewriterElements.forEach((element) => {
        new TypewriterEffect(element as HTMLElement);
    });
});
</script>

<style>
.typewriter {
    position: relative;
}

.typewriter::after {
    content: '|';
    animation: blink 1s infinite;
    margin-left: 2px;
}

@keyframes blink {
    0%, 50% {
        opacity: 1;
    }
    51%, 100% {
        opacity: 0;
    }
}
</style>