import { Text, TextStyle } from 'pixi.js';
import Locator from '../services/Locator';

interface Options
{
    count?: number;
    transformMethod?: TransformMethod,
    [key: string]: any;
}

type TransformMethod = 'toUpperCase' | 'toLowerCase' | 'trim' | 'normalize';
type KeySegment = {
    key: string;
    count?: number,
    transformMethod?: TransformMethod,
    splitIndexStart?: number,
    splitIndexEnd?: number,
    join?: string
};
type Segment = string | KeySegment;

/**
 * Example usage of the AdvancedText class:
 * @example
 * // Basic static text:
 * const style = { padding: 20 };
 * const text1 = new AdvancedText('hello', style);
 * // output: hello
 *
 * // Assigning content after creation:
 * const text2 = new AdvancedText('', style);
 * text2.content = 'hello';
 * text2.transformMethod('toUpperCase');
 * // output: HELLO
 *
 * // Localized key-based text:
 * const text3 = new AdvancedText({ key: 'free_rounds' }, style);
 * // output: free rounds (resolved from i18n)
 *
 * // Localized key with plural count and uppercase transformation:
 * const text4 = new AdvancedText({
 *   key: 'freespins_left',
 *   count: 1,
 *   transformMethod: 'toUpperCase'
 * }, style);
 * // output: YOU HAVE\n1\nFREE SPIN\nLEFT
 *
 * // Localized key with plural count, transformation, and joined segments:
 * const text5 = new AdvancedText({
 *   key: 'freespins_left',
 *   count: 3,
 *   transformMethod: 'toUpperCase',
 *   join: ' '
 * }, style);
 * // output: YOU HAVE 3 FREE SPINS LEFT
 *
 * // Mixed content: multiple segments with localization and raw string:
 * const text6 = new AdvancedText([
 *   { key: 'freespins_left', count: 3, transformMethod: 'toUpperCase', join: ' ' },
 *   ' hello world ',
 *   { key: 'congrats_you_won_additional_freespins', count: 1, join: ' ' }
 * ], style);
 * // output: YOU HAVE 3 FREE SPINS LEFT hello world Congratulations! You won 1 additional Free Spin
 *
 * // Using splitIndexStart / splitIndexEnd to extract parts of multiline text:
 * const text7 = new AdvancedText([
 *   { key: 'freespins_left', count: 3, splitIndexStart: 0, splitIndexEnd: 2, join: ' ' },
 *   ' hello world ',
 *   { key: 'congrats_you_won_additional_freespins', count: 1, splitIndexStart: 0, splitIndexEnd: 3 }
 * ], style);
 * // output: You have 3 hello world Congratulations! You won 1
 */

export default class AdvancedText extends Text
{
    private _segments: Segment[];
    private _onLangChange: () => void;
    public _transformMethod?: TransformMethod;

    constructor(content: Segment | Segment[], style?: TextStyle, options: Options = {})
    {
        super('', style);

        this._transformMethod = options.transformMethod;

        this._segments = Array.isArray(content) ? content : [content];

        this.rebuild();

        this._onLangChange = () =>
        {
            this.rebuild();
            //@ts-expect-error type
            this.emit('textUpdated');
        };

        Locator.locales._i18n.on('languageChanged', this._onLangChange);
    }

    public transformMethod(value: TransformMethod)
    {
        this._transformMethod = value;
    }

    public set content(content: Segment[])
    {
        this._segments = Array.isArray(content) ? content : [content];
        this.rebuild();
    }

    public get content(): string
    {
        return this.text;
    }

    private rebuild()
    {
        let translated = this._segments
            .map((seg) =>
            {
                if (typeof seg === 'object')
                {
                    const parts = Locator.locales.get(seg.key, seg.count).split('\n');
                    let text = '';

                    if (seg.splitIndexStart != null && seg.splitIndexEnd != null)
                    {
                        text = parts.slice(seg.splitIndexStart, seg.splitIndexEnd).join(seg.join ?? '\n');
                    }
                    else
                    {
                        text = parts.join(seg.join ?? '\n');
                    }

                    return seg.transformMethod ? text[seg.transformMethod]() : text;
                }

                return seg;
            })
            .join('');

        if (this._transformMethod)
        {
            translated = (translated as any)[this._transformMethod]();
        }

        super.text = translated;
    }

    override destroy(options?: boolean | { children?: boolean; texture?: boolean; baseTexture?: boolean }): void
    {
        Locator.locales._i18n.off('languageChanged', this._onLangChange);
        super.destroy(options);
    }
}
