import { _decorator, CCString, Component, error, Label, RichText } from "cc";
import { EDITOR } from "cc/env";
import { EventName } from "../EventName";
import { eventsOnLoad, preloadEvent } from "../Events";
import I18n from "./I18n";
const { ccclass, property, executeInEditMode, menu } = _decorator;

@ccclass
@eventsOnLoad()
@executeInEditMode
@menu("Framework/I18N/LocalizedLabel")
export default class LocalizedLabel extends Component {
    @property(CCString) private _textKey: string = "";

    @property({ type: CCString, tooltip: "i18n key" })
    public get textKey(): string { return this._textKey; }
    public set textKey(key: string) {
        this._textKey = key;
        this.updateLabel();
    }

    /**
     * 用于正则替换的配置 
     */
    private _option: { [k: string]: string | number } | Array<string | number> = [];

    private _label: Label | RichText = null;
    public get label(): Label | RichText {
        if (!this._label) {
            this._label = this.node.getComponent(Label) || this.node.getComponent(RichText);
            if (!this._label) {
                error("Failed to update localized label, label component is invalid!");
                return null;
            }
        }
        return this._label;
    }

    protected onLoad(): void {
        try {
            I18n.init();
            this.updateLabel();
        } catch (err) {
            error(err);
        }
    }

    protected update(): void {
        if (EDITOR) {
            if (this.label.string) {
                let key = I18n.getKeyByValue(this.label.string);
                if (key) {
                    this.textKey = key;
                }
            }
        }
    }

    /**
     * 更新语言
     */
    @preloadEvent(EventName.UPDATE_LOCALIZED_CMPT)
    public updateLabel(): void {
        let localizedString = this._option instanceof Array ? I18n.getText(this._textKey, ...this._option) : I18n.getText(this._textKey, this._option);
        if (localizedString) {
            localizedString = this.replaceLabelString(localizedString, this._option instanceof Array ? this._option : []);
            this.label.string = localizedString;
        }
    }

    /**
    * 用于动态替换文本中的占位符
    * @param text 原始文本
    * @param options 替换占位符的值
    */
    private replaceLabelString(text: string, options: Array<string | number>): string {

        // 使用正则表达式匹配 @ 符号作为占位符
        let replacedText = text.replace(/@\{(\d+)\}/g, (match, index) => {
            let replacement = options[parseInt(index) - 1];
            return replacement !== undefined ? String(replacement) : match;
        });

        return replacedText;
    }


    /**
     * 设置语言与配置
     * @param key
     * @param option
     */
    public setTextKeyAndOption(key: string, ...option: [{ [k: string]: string | number }] | Array<string | number>): void {
        this._textKey = key;
        this.setOption(...option);
    }

    /**
     * 仅设置配置
     * @param option
     */
    public setOption(...option: [{ [k: string]: string | number }] | Array<string | number>): void {
        if (option.length === 1 && typeof option[0] === 'object' && !Array.isArray(option[0])) {
            this._option = option[0] as { [k: string]: string | number };
        } else {
            this._option = option as Array<string | number>;
        }
        this.updateLabel();
    }

    /**
     * 清除key
     */
    public clear(): void {
        this.label.string = "";
        this.textKey = "";
    }
}
