import { AddLinkEventTracker, CustomPrefixPurchaseFailedEvent, ILinkEventTracker, PurchaseCatalogPrefixComposer, PurchaseNickIconComposer, PurchasePrefixComposer, RemoveLinkEventTracker, RequestNickIconsComposer, SetActiveNickIconComposer, SetActivePrefixComposer, SetDisplayOrderComposer, UserNickIconsEvent } from '@nitrots/nitro-renderer';
import data from '@emoji-mart/data';
import Picker from '@emoji-mart/react';
import { FC, useEffect, useMemo, useState } from 'react';
import { INickIconItem, IPrefixItem, PRESET_PREFIX_EFFECTS, PRESET_PREFIX_FONTS, SendMessageComposer, getPrefixEffectStyle, getPrefixFontStyle, parsePrefixColors } from '../../api';
import { GetNickIconUrl } from '../../assets/images/user_custom/nick_icons';
import { Button, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView, Text, UserIdentityView } from '../../common';
import { LayoutCurrencyIcon } from '../../common/layout/LayoutCurrencyIcon';
import { useMessageEvent } from '../../hooks';

type CustomizeTab = 'icons' | 'prefix' | 'settings';
type PrefixSubTab = 'library' | 'custom';

interface ICatalogPrefixItem extends IPrefixItem
{
    points: number;
    pointsType: number;
    owned: boolean;
    ownedPrefixId: number;
}

interface ICombinedPrefixItem extends IPrefixItem
{
    points: number;
    pointsType: number;
    owned: boolean;
    ownedPrefixId: number;
}

const ORDER_LABELS: Record<string, string> = {
    'icon-prefix-name': 'Icon / Prefix / Name',
    'prefix-icon-name': 'Prefix / Icon / Name',
    'name-icon-prefix': 'Name / Icon / Prefix',
    'name-prefix-icon': 'Name / Prefix / Icon',
    'icon-name-prefix': 'Icon / Name / Prefix',
    'prefix-name-icon': 'Prefix / Name / Icon'
};

const PRESET_COLORS: string[] = [
    '#D62828', '#E85D04', '#F77F00', '#2A9D8F',
    '#0077B6', '#4361EE', '#6A4C93', '#C1121F',
    '#B5179E', '#3A86FF', '#3F8E00', '#8D5524'
];

export const CustomizeNickIconView: FC<{}> = () =>
{
    const [ isVisible, setIsVisible ] = useState(false);
    const [ isLoading, setIsLoading ] = useState(false);
    const [ activeTab, setActiveTab ] = useState<CustomizeTab>('icons');
    const [ activePrefixSubTab, setActivePrefixSubTab ] = useState<PrefixSubTab>('library');
    const [ iconItems, setIconItems ] = useState<INickIconItem[]>([]);
    const [ prefixItems, setPrefixItems ] = useState<IPrefixItem[]>([]);
    const [ catalogPrefixes, setCatalogPrefixes ] = useState<ICatalogPrefixItem[]>([]);
    const [ displayOrder, setDisplayOrder ] = useState('icon-prefix-name');
    const [ customPrefixMaxLength, setCustomPrefixMaxLength ] = useState(15);
    const [ customPrefixPriceCredits, setCustomPrefixPriceCredits ] = useState(0);
    const [ customPrefixPricePoints, setCustomPrefixPricePoints ] = useState(0);
    const [ customPrefixPointsType, setCustomPrefixPointsType ] = useState(0);
    const [ customPrefixFontPriceCredits, setCustomPrefixFontPriceCredits ] = useState(0);
    const [ customPrefixFontPricePoints, setCustomPrefixFontPricePoints ] = useState(0);
    const [ customPrefixFontPointsType, setCustomPrefixFontPointsType ] = useState(0);
    const [ customPrefixText, setCustomPrefixText ] = useState('');
    const [ customPrefixColor, setCustomPrefixColor ] = useState('#FFFFFF');
    const [ customPrefixIcon, setCustomPrefixIcon ] = useState('');
    const [ customPrefixEffect, setCustomPrefixEffect ] = useState('');
    const [ customPrefixFont, setCustomPrefixFont ] = useState('');
    const [ showEmojiPicker, setShowEmojiPicker ] = useState(false);

    useMessageEvent<CustomPrefixPurchaseFailedEvent>(CustomPrefixPurchaseFailedEvent, () =>
    {
        setIsLoading(false);
        setIsVisible(false);
    });

    useMessageEvent<UserNickIconsEvent>(UserNickIconsEvent, event =>
    {
        const parser = event.getParser();

        setIconItems(parser.nickIcons.map(icon => ({
            id: icon.id,
            iconKey: icon.iconKey,
            displayName: icon.displayName,
            points: icon.points,
            pointsType: icon.pointsType,
            owned: icon.owned,
            active: icon.active
        })));
        setPrefixItems(parser.ownedPrefixes.map(prefix => ({
            id: prefix.id,
            displayName: prefix.displayName,
            text: prefix.text,
            color: prefix.color,
            icon: prefix.icon || '',
            effect: prefix.effect || '',
            font: prefix.font || '',
            active: prefix.active,
            isCustom: prefix.isCustom,
            points: prefix.points,
            pointsType: prefix.pointsType,
            catalogPrefixId: prefix.catalogPrefixId
        })));
        setCatalogPrefixes(parser.prefixCatalog.map(prefix => ({
            id: prefix.id,
            displayName: prefix.displayName,
            text: prefix.text,
            color: prefix.color,
            icon: prefix.icon || '',
            effect: prefix.effect || '',
            font: prefix.font || '',
            active: prefix.active,
            points: prefix.points,
            pointsType: prefix.pointsType,
            owned: prefix.owned,
            ownedPrefixId: prefix.ownedPrefixId
        })));
        setDisplayOrder(parser.displayOrder || 'icon-prefix-name');
        setCustomPrefixMaxLength(parser.customPrefixMaxLength || 15);
        setCustomPrefixPriceCredits(parser.customPrefixPriceCredits || 0);
        setCustomPrefixPricePoints(parser.customPrefixPricePoints || 0);
        setCustomPrefixPointsType(parser.customPrefixPointsType || 0);
        setCustomPrefixFontPriceCredits(parser.customPrefixFontPriceCredits || 0);
        setCustomPrefixFontPricePoints(parser.customPrefixFontPricePoints || 0);
        setCustomPrefixFontPointsType(parser.customPrefixFontPointsType || 0);
        setIsLoading(false);
    });

    useEffect(() =>
    {
        const linkTracker: ILinkEventTracker = {
            linkReceived: (url: string) =>
            {
                const parts = url.split('/');

                if(parts.length < 2) return;

                switch(parts[1])
                {
                    case 'show':
                        setIsVisible(true);
                        return;
                    case 'hide':
                        setIsVisible(false);
                        return;
                    case 'toggle':
                        setIsVisible(previousValue => !previousValue);
                        return;
                }
            },
            eventUrlPrefix: 'customize/'
        };

        AddLinkEventTracker(linkTracker);

        return () => RemoveLinkEventTracker(linkTracker);
    }, []);

    useEffect(() =>
    {
        if(!isVisible) return;

        setIsLoading(true);
        SendMessageComposer(new RequestNickIconsComposer());
    }, [ isVisible ]);

    const activeIcon = useMemo(() => iconItems.find(item => item.active) || null, [ iconItems ]);
    const activePrefix = useMemo(() => prefixItems.find(item => item.active) || null, [ prefixItems ]);
    const combinedPrefixes = useMemo(() =>
    {
        const ownedByCatalogId = new Map<number, IPrefixItem>();

        for(const prefix of prefixItems)
        {
            if(prefix.catalogPrefixId && (prefix.catalogPrefixId > 0)) ownedByCatalogId.set(prefix.catalogPrefixId, prefix);
        }

        const catalogEntries: ICombinedPrefixItem[] = catalogPrefixes.map(prefix =>
        {
            const ownedPrefix = ownedByCatalogId.get(prefix.id);

            return {
                id: ownedPrefix?.id || prefix.id,
                displayName: ownedPrefix?.displayName || prefix.displayName,
                text: ownedPrefix?.text || prefix.text,
                color: ownedPrefix?.color || prefix.color,
                icon: ownedPrefix?.icon || prefix.icon,
                effect: ownedPrefix?.effect || prefix.effect,
                font: ownedPrefix?.font || prefix.font,
                active: ownedPrefix?.active || prefix.active,
                isCustom: false,
                points: prefix.points,
                pointsType: prefix.pointsType,
                catalogPrefixId: prefix.id,
                owned: prefix.owned || !!ownedPrefix,
                ownedPrefixId: prefix.ownedPrefixId || ownedPrefix?.id || 0
            };
        });

        const customEntries: ICombinedPrefixItem[] = prefixItems
            .filter(prefix => !prefix.catalogPrefixId || (prefix.catalogPrefixId <= 0))
            .map(prefix => ({
                id: prefix.id,
                displayName: prefix.displayName,
                text: prefix.text,
                color: prefix.color,
                icon: prefix.icon,
                effect: prefix.effect,
                font: prefix.font || '',
                active: prefix.active,
                isCustom: true,
                points: prefix.points || customPrefixPricePoints,
                pointsType: prefix.pointsType || customPrefixPointsType,
                catalogPrefixId: 0,
                owned: true,
                ownedPrefixId: prefix.id
            }));

        return [ ...catalogEntries, ...customEntries ];
    }, [ catalogPrefixes, customPrefixPointsType, customPrefixPricePoints, prefixItems ]);
    const selectedEffectOption = useMemo(() => PRESET_PREFIX_EFFECTS.find(effect => effect.id === customPrefixEffect) || PRESET_PREFIX_EFFECTS[0], [ customPrefixEffect ]);
    const selectedFontOption = useMemo(() => PRESET_PREFIX_FONTS.find(font => font.id === customPrefixFont) || PRESET_PREFIX_FONTS[0], [ customPrefixFont ]);
    const basicEffects = useMemo(() => PRESET_PREFIX_EFFECTS.filter(effect => effect.tier === 'basic'), []);
    const premiumEffects = useMemo(() => PRESET_PREFIX_EFFECTS.filter(effect => effect.tier === 'premium'), []);
    const basicFonts = useMemo(() => PRESET_PREFIX_FONTS.filter(font => font.tier === 'basic'), []);
    const premiumFonts = useMemo(() => PRESET_PREFIX_FONTS.filter(font => font.tier === 'premium'), []);
    const prefixPreviewColors = useMemo(() => parsePrefixColors(customPrefixText || 'Preview', customPrefixColor || '#FFFFFF'), [ customPrefixText, customPrefixColor ]);
    const customPrefixPreviewStyle = useMemo(() => getPrefixEffectStyle(customPrefixEffect, prefixPreviewColors[0] || '#FFFFFF'), [ customPrefixEffect, prefixPreviewColors ]);
    const customPrefixFontStyle = useMemo(() => getPrefixFontStyle(customPrefixFont), [ customPrefixFont ]);
    const customPrefixTotalCredits = useMemo(() => customPrefixPriceCredits + (customPrefixFont ? customPrefixFontPriceCredits : 0), [ customPrefixFont, customPrefixFontPriceCredits, customPrefixPriceCredits ]);
    const customPrefixTotalPoints = useMemo(() => customPrefixPricePoints + ((customPrefixFont && (customPrefixFontPointsType === customPrefixPointsType)) ? customPrefixFontPricePoints : 0), [ customPrefixFont, customPrefixFontPointsType, customPrefixFontPricePoints, customPrefixPointsType, customPrefixPricePoints ]);
    const customPrefixIsValid = useMemo(() =>
    {
        const trimmed = customPrefixText.trim();

        if(!trimmed.length || (trimmed.length > customPrefixMaxLength)) return false;

        return customPrefixColor.split(',').every(color => /^#[0-9A-Fa-f]{6}$/.test(color));
    }, [ customPrefixColor, customPrefixMaxLength, customPrefixText ]);

    const refreshCustomizeData = () =>
    {
        setIsLoading(true);
        SendMessageComposer(new RequestNickIconsComposer());
    };

    const handleIconAction = (item: INickIconItem) =>
    {
        setIsLoading(true);

        if(!item.owned)
        {
            SendMessageComposer(new PurchaseNickIconComposer(item.iconKey));
            return;
        }

        SendMessageComposer(new SetActiveNickIconComposer(item.active ? 0 : item.id));
    };

    const handleCombinedPrefixAction = (item: ICombinedPrefixItem) =>
    {
        setIsLoading(true);

        if(item.owned)
        {
            SendMessageComposer(new SetActivePrefixComposer(item.active ? 0 : item.ownedPrefixId));
            return;
        }

        SendMessageComposer(new PurchaseCatalogPrefixComposer(item.catalogPrefixId || item.id));
    };

    const handleCustomPrefixPurchase = () =>
    {
        if(!customPrefixIsValid) return;

        setIsLoading(true);
        SendMessageComposer(new PurchasePrefixComposer(customPrefixText.trim(), customPrefixColor, customPrefixIcon, customPrefixEffect, customPrefixFont));
    };

    const handleDisplayOrderChange = (nextDisplayOrder: string) =>
    {
        if(nextDisplayOrder === displayOrder) return;

        setDisplayOrder(nextDisplayOrder);
        setIsLoading(true);
        SendMessageComposer(new SetDisplayOrderComposer(nextDisplayOrder));
    };

    if(!isVisible) return null;

    return (
        <NitroCardView className="customize-nick-icon-window w-[680px] max-w-[95vw]" theme="primary-slim" uniqueKey="customize-nick-icons">
            <NitroCardHeaderView headerText="Customize Bubble Identity" onCloseClick={ () => setIsVisible(false) } />
            <NitroCardTabsView>
                <NitroCardTabsItemView isActive={ activeTab === 'icons' } onClick={ () => setActiveTab('icons') }>
                    <Text>Icons</Text>
                </NitroCardTabsItemView>
                <NitroCardTabsItemView isActive={ activeTab === 'prefix' } onClick={ () => setActiveTab('prefix') }>
                    <Text>Prefix</Text>
                </NitroCardTabsItemView>
                <NitroCardTabsItemView isActive={ activeTab === 'settings' } onClick={ () => setActiveTab('settings') }>
                    <Text>Settings</Text>
                </NitroCardTabsItemView>
            </NitroCardTabsView>
            <NitroCardContentView className="flex max-h-[78vh] flex-col gap-3 overflow-y-auto text-black">
                <div className="rounded border border-black/10 bg-black/5 p-3">
                    <Text bold>Live preview</Text>
                    <div className="mt-2 flex min-h-[54px] items-center justify-center rounded border border-black/10 bg-[#cfe8fb] px-3 py-2 text-[#1f2937]">
                        <UserIdentityView
                            displayOrder={ displayOrder }
                            nickIcon={ activeIcon?.iconKey || '' }
                            prefixColor={ activePrefix?.color || customPrefixColor }
                            prefixEffect={ activePrefix?.effect || customPrefixEffect }
                            prefixFont={ activePrefix?.font || customPrefixFont }
                            prefixIcon={ activePrefix?.icon || customPrefixIcon }
                            prefixText={ activePrefix?.text || customPrefixText }
                            username="Username" />
                    </div>
                </div>

                { activeTab === 'icons' &&
                    <>
                        <div className="rounded border border-black/10 bg-black/5 p-2 text-[11px] leading-4">
                            Choose the icon shown in your bubble identity.
                        </div>
                        <div className="grid grid-cols-3 gap-2">
                            { iconItems.map(item =>
                            {
                                const iconUrl = GetNickIconUrl(item.iconKey);

                                return (
                                    <div
                                        key={ item.iconKey }
                                        className={ `relative flex min-h-[126px] flex-col items-center justify-between gap-2 rounded border p-3 transition-colors ${ item.active ? 'border-[#1e7295] bg-[#dff3fb]' : 'border-black/10 bg-black/5' }` }>
                                        { item.active && <span className="absolute right-1 top-1 rounded bg-[#1e7295] px-1.5 py-0.5 text-[9px] font-bold uppercase text-white">Active</span> }
                                        <img className="h-auto max-h-[28px] w-auto object-contain" src={ iconUrl } alt={ item.iconKey } />
                                        <div className="flex flex-col items-center gap-1 text-center text-[11px]">
                                            <span>{ item.owned ? (item.active ? 'Owned - Active' : 'Owned') : 'Locked' }</span>
                                            <span className="max-w-[140px] truncate">{ item.displayName || `Icon #${ item.iconKey }` }</span>
                                            <span className="inline-flex items-center gap-1">
                                                <LayoutCurrencyIcon type={ item.pointsType } />
                                                { item.points }
                                            </span>
                                        </div>
                                        <Button disabled={ isLoading } onClick={ () => handleIconAction(item) }>
                                            { !item.owned && 'Buy' }
                                            { item.owned && !item.active && 'Activate' }
                                            { item.owned && item.active && 'Deactivate' }
                                        </Button>
                                    </div>
                                );
                            }) }
                        </div>
                    </> }

                { activeTab === 'prefix' &&
                    <div className="flex flex-col gap-3">
                        <div className="rounded border border-black/10 bg-black/5 p-1">
                            <div className="flex items-center gap-2">
                                <button
                                    className={ `rounded px-3 py-1.5 text-[11px] font-bold transition-colors ${ activePrefixSubTab === 'library' ? 'bg-[#1e7295] text-white' : 'bg-white text-black' }` }
                                    type="button"
                                    onClick={ () => setActivePrefixSubTab('library') }>
                                    Library
                                </button>
                                <button
                                    className={ `rounded px-3 py-1.5 text-[11px] font-bold transition-colors ${ activePrefixSubTab === 'custom' ? 'bg-[#1e7295] text-white' : 'bg-white text-black' }` }
                                    type="button"
                                    onClick={ () => setActivePrefixSubTab('custom') }>
                                    Custom
                                </button>
                            </div>
                        </div>

                        { activePrefixSubTab === 'library' &&
                            <>
                                <div className="rounded border border-black/10 bg-black/5 p-2 text-[11px] leading-4">
                            Choose a preset or custom prefix for your bubble identity.
                                </div>
                                <div className="grid grid-cols-2 gap-2">
                                    { combinedPrefixes.map(item => (
                                        <div key={ `${ item.catalogPrefixId || 'custom' }-${ item.ownedPrefixId || item.id }` } className={ `relative flex min-h-[96px] flex-col gap-2 rounded border p-2.5 ${ item.active ? 'border-[#1e7295] bg-[#dff3fb]' : 'border-black/10 bg-black/5' }` }>
                                            { item.active && <span className="absolute right-1 top-1 rounded bg-[#1e7295] px-1.5 py-0.5 text-[9px] font-bold uppercase text-white">Active</span> }
                                            <UserIdentityView
                                                displayOrder={ displayOrder }
                                                nickIcon={ activeIcon?.iconKey || '' }
                                                prefixColor={ item.color }
                                                prefixEffect={ item.effect }
                                                prefixFont={ item.font || '' }
                                                prefixIcon={ item.icon }
                                                prefixText={ item.text }
                                                username="Username" />
                                            <div className="flex flex-col gap-1 text-[11px]">
                                                <span>{ item.owned ? (item.active ? 'Owned - Active' : 'Owned') : 'Locked' }</span>
                                                <span className="truncate">{ item.displayName || item.text }{ item.isCustom ? ' - Custom' : '' }</span>
                                                <span className="inline-flex items-center gap-1">
                                                    <LayoutCurrencyIcon type={ item.pointsType } />
                                                    { item.points }
                                                </span>
                                            </div>
                                            <Button disabled={ isLoading } onClick={ () => handleCombinedPrefixAction(item) }>
                                                { !item.owned && 'Buy' }
                                                { item.owned && !item.active && 'Activate' }
                                                { item.owned && item.active && 'Deactivate' }
                                            </Button>
                                        </div>
                                    )) }
                                </div>
                            </> }

                        { activePrefixSubTab === 'custom' &&
                        <div className="rounded border border-black/10 bg-black/5 p-3">
                            <div className="mb-2 flex items-center justify-between">
                                <Text bold>Custom prefix</Text>
                                <Button disabled={ isLoading } onClick={ refreshCustomizeData }>Refresh</Button>
                            </div>
                            <div className="mt-2 flex flex-col gap-2">
                                <div className="flex items-center gap-2">
                                    <input
                                        className="flex-1 rounded border border-black/10 bg-white px-3 py-2 text-sm"
                                        maxLength={ customPrefixMaxLength }
                                        placeholder="Enter your prefix"
                                        type="text"
                                        value={ customPrefixText }
                                        onChange={ event => setCustomPrefixText(event.target.value) } />
                                    <span className="text-[11px] text-black/60">{ customPrefixText.length }/{ customPrefixMaxLength }</span>
                                </div>
                                <div className="flex flex-wrap items-center gap-2">
                                    <button className="rounded border border-black/10 bg-white px-3 py-2 text-sm" type="button" onClick={ () => setShowEmojiPicker(true) }>
                                        { customPrefixIcon || 'Emoji' }
                                    </button>
                                    { !!customPrefixIcon && <Button onClick={ () => setCustomPrefixIcon('') }>Clear</Button> }
                                </div>
                                <div className="rounded border border-black/10 bg-white p-2">
                                    <div className="mb-2 text-[11px] leading-4 text-black/70">
                                        Safe colors only, chosen to stay readable on both light and dark backgrounds.
                                    </div>
                                    <div className="grid grid-cols-6 gap-2">
                                        { PRESET_COLORS.map(color => (
                                            <button
                                                key={ color }
                                                className={ `flex h-[28px] items-center justify-center rounded border text-[10px] font-bold uppercase ${ customPrefixColor === color ? 'border-[#1e7295] ring-1 ring-[#1e7295]' : 'border-black/10' }` }
                                                style={ { backgroundColor: color } }
                                                type="button"
                                                onClick={ () => setCustomPrefixColor(color) }>
                                                { customPrefixColor === color ? 'ON' : '' }
                                            </button>
                                        )) }
                                    </div>
                                </div>
                                <div className="rounded border border-black/10 bg-white p-2">
                                    <div className="mb-2 text-[11px] leading-4 text-black/70">
                                        Effect
                                    </div>
                                    <div className="flex items-center gap-2">
                                        <select
                                            className="flex-1 rounded border border-black/10 bg-white px-2 py-2 text-sm"
                                            value={ customPrefixEffect }
                                            onChange={ event => setCustomPrefixEffect(event.target.value) }>
                                            <optgroup label="Basic">
                                                { basicEffects.map(effect => (
                                                    <option key={ effect.id || 'none' } value={ effect.id }>
                                                        { effect.label }
                                                    </option>
                                                )) }
                                            </optgroup>
                                            <optgroup label="Premium">
                                                { premiumEffects.map(effect => (
                                                    <option key={ effect.id } value={ effect.id }>
                                                        { effect.label }
                                                    </option>
                                                )) }
                                            </optgroup>
                                        </select>
                                        <div className="min-w-[130px] rounded border border-black/10 bg-black/5 px-2 py-2 text-center text-[11px] font-bold">
                                            { selectedEffectOption.icon } { selectedEffectOption.label }
                                            <div className="mt-1 text-[9px] uppercase text-black/60">
                                                { selectedEffectOption.tier }
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div className="rounded border border-black/10 bg-white p-2">
                                    <div className="mb-2 text-[11px] leading-4 text-black/70">
                                        Font
                                    </div>
                                    <div className="flex items-center gap-2">
                                        <select
                                            className="flex-1 rounded border border-black/10 bg-white px-2 py-2 text-sm"
                                            value={ customPrefixFont }
                                            onChange={ event => setCustomPrefixFont(event.target.value) }>
                                            <optgroup label="Basic">
                                                { basicFonts.map(font => (
                                                    <option key={ font.id || 'default' } value={ font.id }>
                                                        { font.label }
                                                    </option>
                                                )) }
                                            </optgroup>
                                            <optgroup label="Premium">
                                                { premiumFonts.map(font => (
                                                    <option key={ font.id } value={ font.id }>
                                                        { font.label }
                                                    </option>
                                                )) }
                                            </optgroup>
                                        </select>
                                        <div className="min-w-[130px] rounded border border-black/10 bg-black/5 px-2 py-2 text-center text-[11px] font-bold">
                                            <span style={ customPrefixFontStyle }>{ selectedFontOption.label }</span>
                                            <div className="mt-1 text-[9px] uppercase text-black/60">
                                                { selectedFontOption.tier }
                                            </div>
                                        </div>
                                    </div>
                                    { !!customPrefixFont &&
                                        <div className="mt-2 text-[10px] leading-4 text-black/60">
                                            Premium fonts add an extra price on top of the custom prefix.
                                        </div> }
                                </div>
                                <div className="rounded border border-black/10 bg-[#cfe8fb] px-3 py-2 text-[#1f2937]" style={ customPrefixPreviewStyle }>
                                    <UserIdentityView
                                        displayOrder={ displayOrder }
                                        nickIcon={ activeIcon?.iconKey || '' }
                                        prefixColor={ customPrefixColor }
                                        prefixEffect={ customPrefixEffect }
                                        prefixFont={ customPrefixFont }
                                        prefixIcon={ customPrefixIcon }
                                        prefixText={ customPrefixText || 'Preview' }
                                        username="Username" />
                                </div>
                                <div className="flex items-center justify-between">
                                    <div className="flex items-center gap-2 text-[12px]">
                                        { customPrefixTotalCredits > 0 && <span>{ customPrefixTotalCredits } credits</span> }
                                        { customPrefixTotalPoints > 0 &&
                                            <span className="inline-flex items-center gap-1">
                                                <LayoutCurrencyIcon type={ customPrefixPointsType } />
                                                { customPrefixTotalPoints }
                                            </span> }
                                        { !!customPrefixFont && (customPrefixFontPointsType !== customPrefixPointsType) && (customPrefixFontPricePoints > 0) &&
                                            <span className="inline-flex items-center gap-1">
                                                <LayoutCurrencyIcon type={ customPrefixFontPointsType } />
                                                { customPrefixFontPricePoints }
                                            </span> }
                                    </div>
                                    <Button disabled={ !customPrefixIsValid || isLoading } onClick={ handleCustomPrefixPurchase }>
                                        Buy custom prefix
                                    </Button>
                                </div>
                            </div>
                        </div> }
                    </div> }

                { activeTab === 'settings' &&
                    <div className="flex flex-col gap-3">
                        <div className="rounded border border-black/10 bg-black/5 p-3">
                            <Text bold>Display order</Text>
                            <div className="mt-2 grid grid-cols-2 gap-2">
                                { Object.entries(ORDER_LABELS).map(([ key, label ]) => (
                                    <Button key={ key } disabled={ isLoading && (displayOrder === key) } onClick={ () => handleDisplayOrderChange(key) }>
                                        { displayOrder === key ? '* ' : '' }{ label }
                                    </Button>
                                )) }
                            </div>
                        </div>
                        <div className="rounded border border-black/10 bg-black/5 p-3">
                            <div className="mb-2 flex items-center justify-between">
                                <Text bold>Refresh data</Text>
                                <Button disabled={ isLoading } onClick={ refreshCustomizeData }>Refresh</Button>
                            </div>
                            <div className="text-[11px] leading-4 text-black/70">
                                Use this tab to control how your icon, prefix and username are ordered in bubbles, profile and infostand.
                            </div>
                        </div>
                    </div> }
            </NitroCardContentView>
            { showEmojiPicker &&
                <>
                    <div className="fixed inset-0 z-[999]" onClick={ () => setShowEmojiPicker(false) } />
                    <div className="fixed left-1/2 top-1/2 z-[1000] -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-xl shadow-2xl">
                        <Picker
                            data={ data }
                            locale="en"
                            onEmojiSelect={ (emoji: { native: string }) =>
                            {
                                setCustomPrefixIcon(emoji.native); setShowEmojiPicker(false);
                            } }
                            previewPosition="none"
                            set="native"
                            theme="dark" />
                    </div>
                </> }
        </NitroCardView>
    );
};

