import { Player, TextDraw, Dialog, DialogStylesEnum, TextDrawEvent } from '@infernus/core';

/**
 * MenuStore v5.0 - TypeScript Edition
 * 
 * A comprehensive shopping cart system for SA-MP servers using Infernus framework.
 * Features include:
 * - Dynamic item management with 3D model previews
 * - Shopping cart with pagination and quantity selection
 * - Customizable store themes and callbacks
 * - Responsive TextDraw-based UI with hover effects
 * - Multi-page navigation for both store items and cart
 * 
 * @author Original: CaioTJF | TypeScript Port: cha5e369
 * @version 0.0.1
 * @framework Infernus Core
 * @license MIT
 */

// Configuration constants (immutable)
const MS_CONFIG = {
    MAX_ITEMS_PER_PAGE: 6,
    MAX_ITEMS_CART_PER_PAGE: 4,
    MAX_ITEMS_CART: 20,
    MAX_ITEMS: 30,
    MAX_SIZE_DESCRIPTION: 7.5,
    INTERVAL_DOUBLECLICK: 300,
    DIALOG_ID: 23132,
    
    // Default texts
    DEFAULT_MONEY_SIGN: "$",
    DEFAULT_CONFIRM: "Buy",
    
    // Messages
    MSG_TITLE_DIALOG: "Choose quantity",
    MSG_DIALOG: "Enter the quantity you want to buy",
    WORD_LIMIT: "Limit",
    WORD_CLOSE: "Close",
    WORD_TOTAL: "Total",
    WORD_GO: "Go",
    WORD_CANCEL: "Cancel",
    WORD_CART: "Cart"
} as const;

// Colors configuration
const MS_COLORS = {
    SELECT_TD: 0xFFFFFFFF,
    TEXT_MAIN: 0xFFFFFFFF,
    BACKGROUND_1: 0x00000080,
    BACKGROUND_2: 0x2C2C2CAA,
    BACKGROUND_ITEM: 0x3E3E3EFF,
    BACKGROUND_ITEM_SELECTED: 0xFFFFFF50,
    BACKGROUND_CONFIRM: 0x5EAF3AFF,
    BACKGROUND_MODEL: 0xFFFFFF50,
    CART_REMOVE_ITEM: 0xCC30A0FF,
    DESCRIPTION_NAME_ITEM: 0xFFFFFFFF,
    DESCRIPTION_TEXT: 0xFFFFFFAA,
    DESCRIPTION_BACKGROUND_MODEL: 0xFFFFFF50
} as const;

const MSTORE_INVALID_ITEM_ID = -1;

// Interfaces
interface StoreItem {
    itemID: number;
    itemModel: number;
    itemPrice: number;
    itemStack: number;
    itemName: string;
    itemDescription: string;
    itemDescriptionBonus: number;
    itemLineJump: boolean;
    itemPreviewRot: [number, number, number, number];
}

interface StoreInfo {
    totalItems: number;
    currentPage: number;
    currentCartPage: number;
    isOpen: boolean;
    storeID: string;
    moneySign: string;
    doubleClick: number;
    doubleClickRow: number;
    selected: number;
    toggleControll: boolean;
}

interface CartItem {
    itemID: number;
    itemPrice: number;
    itemAmount: number;
}

interface StoreTextDraws {
    // Global TextDraws
    backgrounds: [TextDraw | null, TextDraw | null];
    next: TextDraw | null;
    previous: TextDraw | null;
    cartBackgrounds: [TextDraw | null, TextDraw | null];
    cartBackgroundConfirm: TextDraw | null;
    cartCartName: TextDraw | null;
    cartNext: TextDraw | null;
    cartPrevious: TextDraw | null;
    
    // Player TextDraws
    itemName: (TextDraw | null)[];
    itemPrice: (TextDraw | null)[];
    itemModel: (TextDraw | null)[];
    itemBackground: (TextDraw | null)[];
    storeName: TextDraw | null;
    pagination: TextDraw | null;
    cartPagination: TextDraw | null;
    descriptionItemName: TextDraw | null;
    descriptionItemText: TextDraw | null;
    descriptionItemModel: TextDraw | null;
    descriptionBackground: [TextDraw | null, TextDraw | null];
    cartItemBackground: (TextDraw | null)[];
    cartItemName: (TextDraw | null)[];
    cartItemClose: (TextDraw | null)[];
    cartBuyName: TextDraw | null;
    cartTotal: TextDraw | null;
}

// Store callback type
type StoreCallback = (
    player: Player,
    purchased: boolean,
    itemID: number,
    model: number,
    totalPrice: number,
    amount: number,
    itemName: string
) => void;

class MenuStoreManager {
    private playerItems: Map<number, StoreItem[]> = new Map();
    private playerInfo: Map<number, StoreInfo> = new Map();
    private playerCart: Map<number, CartItem[]> = new Map();
    private playerTextDraws: Map<number, StoreTextDraws> = new Map();
    private globalTextDraws: StoreTextDraws | null = null;
    private storeCallbacks: Map<string, StoreCallback> = new Map();

    constructor() {
        // Do not auto-initialize events
    }

    // Method to initialize GameMode events
    public initializeGameModeEvents(): void {
        this.createGlobalTextDraws();
    }

    // Method to initialize Player events
    public initializePlayerEvents(): void {
        TextDrawEvent.onPlayerClickGlobal(({ player, textDraw }) => {
            console.log(`[MenuStore Debug] Global TextDraw clicked by ${player.getName()}, textDraw: ${textDraw || 'null'}`);
            
            // Handle ESC (when textDraw is null)
            if (!textDraw) {
                const playerStoreInfo = this.playerInfo.get(player.id);
                if (playerStoreInfo && playerStoreInfo.isOpen) {
                    console.log(`[MenuStore Debug] ESC detected for ${player.getName()}`);
                    this.handlePlayerESC(player);
                }
                return;
            }
            
            // Handle clicks on global textdraws
            this.handleGlobalTextDrawClick(player, textDraw);
        });

        TextDrawEvent.onPlayerClickPlayer(({ player, textDraw }) => {
            console.log(`[MenuStore Debug] Player TextDraw clicked by ${player.getName()}, textDraw: ${textDraw || 'null'}`);
            this.handlePlayerTextDrawClick(player, textDraw);
        });
    }

    // Method to initialize a specific player
    public initializePlayerData(player: Player): void {
        this.initializePlayer(player);
    }

    // Method to clean up a specific player's data
    public cleanupPlayerData(player: Player): void {
        this.closeStore(player);
        // Remove all player data
        this.playerItems.delete(player.id);
        this.playerInfo.delete(player.id);
        this.playerCart.delete(player.id);
        this.playerTextDraws.delete(player.id);
    }

    private initializePlayer(player: Player): void {
        // Initialize items array
        this.playerItems.set(player.id, Array(MS_CONFIG.MAX_ITEMS).fill(null).map(() => ({
            itemID: MSTORE_INVALID_ITEM_ID,
            itemModel: 0,
            itemPrice: 0,
            itemStack: 0,
            itemName: "",
            itemDescription: "",
            itemDescriptionBonus: 0.0,
            itemLineJump: true,
            itemPreviewRot: [0.0, 0.0, 0.0, 1.0]
        })));

        // Initialize info
        this.playerInfo.set(player.id, {
            totalItems: 0,
            currentPage: 1,
            currentCartPage: 1, // Inicializar página del carrito
            isOpen: false,
            storeID: "",
            moneySign: "",
            doubleClick: 0,
            doubleClickRow: -1,
            selected: -1,
            toggleControll: true
        });

        // Initialize cart - aumentar capacidad
        this.playerCart.set(player.id, Array(MS_CONFIG.MAX_ITEMS_CART).fill(null).map(() => ({
            itemID: MSTORE_INVALID_ITEM_ID,
            itemPrice: 0,
            itemAmount: 0
        })));

        // Initialize TextDraws
        this.playerTextDraws.set(player.id, {
            backgrounds: [null, null],
            next: null,
            previous: null,
            cartBackgrounds: [null, null],
            cartBackgroundConfirm: null,
            cartCartName: null,
            cartNext: null, // Inicializar botones del carrito
            cartPrevious: null,
            itemName: Array(MS_CONFIG.MAX_ITEMS_PER_PAGE).fill(null),
            itemPrice: Array(MS_CONFIG.MAX_ITEMS_PER_PAGE).fill(null),
            itemModel: Array(MS_CONFIG.MAX_ITEMS_PER_PAGE).fill(null),
            itemBackground: Array(MS_CONFIG.MAX_ITEMS_PER_PAGE).fill(null),
            storeName: null,
            pagination: null,
            cartPagination: null, // Inicializar paginación del carrito
            descriptionItemName: null,
            descriptionItemText: null,
            descriptionItemModel: null,
            descriptionBackground: [null, null],
            cartItemBackground: Array(MS_CONFIG.MAX_ITEMS_CART_PER_PAGE).fill(null),
            cartItemName: Array(MS_CONFIG.MAX_ITEMS_CART_PER_PAGE).fill(null),
            cartItemClose: Array(MS_CONFIG.MAX_ITEMS_CART_PER_PAGE).fill(null),
            cartBuyName: null,
            cartTotal: null
        });
    }

    private createGlobalTextDraws(): void {
        if (this.globalTextDraws) return;

        this.globalTextDraws = {
            backgrounds: [null, null],
            next: null,
            previous: null,
            cartBackgrounds: [null, null],
            cartBackgroundConfirm: null,
            cartCartName: null,
            cartNext: null,
            cartPrevious: null,
            itemName: [],
            itemPrice: [],
            itemModel: [],
            itemBackground: [],
            storeName: null,
            pagination: null,
            cartPagination: null,
            descriptionItemName: null,
            descriptionItemText: null,
            descriptionItemModel: null,
            descriptionBackground: [null, null],
            cartItemBackground: [],
            cartItemName: [],
            cartItemClose: [],
            cartBuyName: null,
            cartTotal: null
        };

        // Background 1
        this.globalTextDraws.backgrounds[0] = new TextDraw({
            x: 145.5,
            y: 130.499969,
            text: "box"
        }).create()
            .setLetterSize(0.0, 30.198539)
            .setTextSize(322.0, 0.0)
            .setAlignment(1)
            .setColor(0xFFFFFFFF)
            .useBox(true)
            .setBoxColors(MS_COLORS.BACKGROUND_1)
            .setShadow(0)
            .setOutline(0)
            .setFont(1)
            .setProportional(true);

        // Background 2
        this.globalTextDraws.backgrounds[1] = new TextDraw({
            x: 153.0,
            y: 149.383575,
            text: "box"
        }).create()
            .setLetterSize(0.0, 26.226503)
            .setTextSize(315.0, 0.0)
            .setAlignment(1)
            .setColor(0xFFFFFFFF)
            .useBox(true)
            .setBoxColors(MS_COLORS.BACKGROUND_2)
            .setShadow(0)
            .setOutline(0)
            .setFont(1)
            .setProportional(true);

        // Next button
        this.globalTextDraws.next = new TextDraw({
            x: 251.485229,
            y: 390.033355,
            text: "ld_beat:right"
        }).create()
            .setLetterSize(0.0, 0.0)
            .setTextSize(11.0, 13.0)
            .setAlignment(1)
            .setColor(MS_COLORS.TEXT_MAIN)
            .setShadow(0)
            .setOutline(0)
            .setFont(4)
            .setProportional(true)
            .setSelectable(true);

        // Previous button
        this.globalTextDraws.previous = new TextDraw({
            x: 201.94522,
            y: 390.033355,
            text: "ld_beat:left"
        }).create()
            .setLetterSize(0.0, 0.0)
            .setTextSize(11.0, 13.0)
            .setAlignment(1)
            .setColor(MS_COLORS.TEXT_MAIN)
            .setShadow(0)
            .setOutline(0)
            .setFont(4)
            .setProportional(true)
            .setSelectable(true);

        // Cart Confirm Button - EL MÁS IMPORTANTE
        this.globalTextDraws.cartBackgroundConfirm = new TextDraw({
            x: 444.89923,
            y: 390.233489,
            text: "box"
        }).create()
            .setLetterSize(0.0, 0.850001)
            .setTextSize(507.70169, 15.0)
            .setAlignment(1)
            .setColor(0xFFFFFFFF)
            .useBox(true)
            .setBoxColors(MS_COLORS.BACKGROUND_CONFIRM)
            .setShadow(0)
            .setOutline(0)
            .setFont(1)
            .setProportional(true)
            .setSelectable(true);

        this.createCartGlobalElements();
    }

    private createCartGlobalElements(): void {
        if (!this.globalTextDraws) return;

        // Cart Background 1
        this.globalTextDraws.cartBackgrounds[0] = new TextDraw({
            x: 333.201141,
            y: 271.666656,
            text: "box"
        }).create()
            .setLetterSize(0.0, 14.450012)
            .setTextSize(516.0, 0.0)
            .setAlignment(1)
            .setColor(0xFFFFFFFF)
            .useBox(true)
            .setBoxColors(MS_COLORS.BACKGROUND_1)
            .setShadow(0)
            .setOutline(0)
            .setFont(1)
            .setProportional(true);

        // Cart Background 2
        this.globalTextDraws.cartBackgrounds[1] = new TextDraw({
            x: 341.0,
            y: 290.133575,
            text: "box"
        }).create()
            .setLetterSize(0.0, 10.134258)
            .setTextSize(508.0, 0.0)
            .setAlignment(1)
            .setColor(0xFFFFFFFF)
            .useBox(true)
            .setBoxColors(MS_COLORS.BACKGROUND_2)
            .setShadow(0)
            .setOutline(0)
            .setFont(1)
            .setProportional(true);

        // Cart Name
        this.globalTextDraws.cartCartName = new TextDraw({
            x: 339.143798,
            y: 270.73352,
            text: MS_CONFIG.WORD_CART
        }).create()
            .setLetterSize(0.310357, 1.434998)
            .setTextSize(508.0, 0.0)
            .setAlignment(1)
            .setColor(MS_COLORS.TEXT_MAIN)
            .useBox(true)
            .setBoxColors(0xFFFFFF00)
            .setShadow(0)
            .setOutline(0)
            .setFont(2)
            .setProportional(true);

        // Cart Next button
        this.globalTextDraws.cartNext = new TextDraw({
            x: 395.0,
            y: 371.0,
            text: "ld_beat:right"
        }).create()
            .setLetterSize(0.0, 0.0)
            .setTextSize(8.0, 10.0)
            .setAlignment(1)
            .setColor(MS_COLORS.TEXT_MAIN)
            .setShadow(0)
            .setOutline(0)
            .setFont(4)
            .setProportional(true)
            .setSelectable(true);

        // Cart Previous button
        this.globalTextDraws.cartPrevious = new TextDraw({
            x: 355.0,
            y: 371.0,
            text: "ld_beat:left"
        }).create()
            .setLetterSize(0.0, 0.0)
            .setTextSize(8.0, 10.0)
            .setAlignment(1)
            .setColor(MS_COLORS.TEXT_MAIN)
            .setShadow(0)
            .setOutline(0)
            .setFont(4)
            .setProportional(true)
            .setSelectable(true);
    }


    private handleGlobalTextDrawClick(player: Player, textDraw: any): void {
        const playerStoreInfo = this.playerInfo.get(player.id);
        if (!playerStoreInfo || !playerStoreInfo.toggleControll) return;

        if (textDraw === this.globalTextDraws?.next) {
            if (playerStoreInfo.currentPage < this.getNumberOfPages(player.id)) {
                playerStoreInfo.currentPage++;
                this.setPage(player, playerStoreInfo.currentPage);
                this.unselectRow(player);
            }
        } else if (textDraw === this.globalTextDraws?.previous) {
            if (playerStoreInfo.currentPage > 1) {
                playerStoreInfo.currentPage--;
                this.setPage(player, playerStoreInfo.currentPage);
                this.unselectRow(player);
            }
        } else if (textDraw === this.globalTextDraws?.cartNext) {
            if (playerStoreInfo.currentCartPage < this.getCartNumberOfPages(player.id)) {
                playerStoreInfo.currentCartPage++;
                this.setCartPage(player, playerStoreInfo.currentCartPage);
            }
        } else if (textDraw === this.globalTextDraws?.cartPrevious) {
            if (playerStoreInfo.currentCartPage > 1) {
                playerStoreInfo.currentCartPage--;
                this.setCartPage(player, playerStoreInfo.currentCartPage);
            }
        } else if (textDraw === this.globalTextDraws?.cartBackgroundConfirm) {
            const itemsInCart = this.getTotalItemsInCart(player.id);
            if (itemsInCart > 0) {
                this.processPurchase(player);
                this.closeStore(player);
            } else {
                player.sendClientMessage(0xFF0000FF, "The cart is empty. Double-click an item to add it.");
            }
        }
    }

    private handlePlayerTextDrawClick(player: Player, textDraw: any): void {
        const playerStoreInfo = this.playerInfo.get(player.id);
        const textDraws = this.playerTextDraws.get(player.id);
        if (!playerStoreInfo || !textDraws || !playerStoreInfo.toggleControll) return;

        // Check item clicks
        for (let i = 0; i < MS_CONFIG.MAX_ITEMS_PER_PAGE; i++) {
            if (textDraw === textDraws.itemBackground[i]) {
                this.handleItemClick(player, i);
                return;
            }
        }

        // Check cart item clicks
        for (let row = 0; row < MS_CONFIG.MAX_ITEMS_CART_PER_PAGE; row++) {
            if (textDraw === textDraws.cartItemBackground[row]) {
                const realIndex = row + (MS_CONFIG.MAX_ITEMS_CART_PER_PAGE * (playerStoreInfo.currentCartPage - 1));
                this.removeFromCart(player, realIndex);
                return;
            }
        }
    }

    private handleItemClick(player: Player, row: number): void {
        const playerStoreInfo = this.playerInfo.get(player.id);
        const items = this.playerItems.get(player.id);
        if (!playerStoreInfo || !items) return;

        const index = row + (MS_CONFIG.MAX_ITEMS_PER_PAGE * (playerStoreInfo.currentPage - 1));
        const now = Date.now();

        // Handle double click
        if ((now - playerStoreInfo.doubleClick) < MS_CONFIG.INTERVAL_DOUBLECLICK && playerStoreInfo.doubleClickRow === row) {
            if (items[index].itemStack > 1) {
                this.showQuantityDialog(player, index);
            } else {
                this.addToCart(player, items[index].itemID, items[index].itemPrice, items[index].itemStack);
                this.unselectRow(player);
                this.closeDescription(player);
            }
            
            playerStoreInfo.doubleClickRow = -1;
            playerStoreInfo.doubleClick = 0;
            return;
        } else {
            playerStoreInfo.doubleClickRow = row;
            playerStoreInfo.doubleClick = now;
        }

        // Handle selection
        if (playerStoreInfo.selected === row) {
            this.unselectRow(player);
            this.closeDescription(player);
            return;
        } else if (playerStoreInfo.selected !== -1) {
            this.unselectRow(player);
        }

        this.selectRow(player, row);
        this.openDescription(player, index);
    }

    private handlePlayerESC(player: Player): void {
        const playerStoreInfo = this.playerInfo.get(player.id);
        if (!playerStoreInfo || !playerStoreInfo.isOpen) return;

        console.log(`[MenuStore Debug] ESC handled for ${player.getName()}`);

        const callback = this.storeCallbacks.get(playerStoreInfo.storeID);
        if (callback) {
            callback(player, false, MSTORE_INVALID_ITEM_ID, 0, 0, 0, "CANCELLED");
        }
        
        this.closeStore(player);
    }

    // Helper methods
    private getNumberOfPages(playerId: number): number {
        const playerStoreInfo = this.playerInfo.get(playerId);
        if (!playerStoreInfo) return 1;

        const totalItemsCount = this.getTotalValidItems(playerId);
        if (totalItemsCount <= MS_CONFIG.MAX_ITEMS_PER_PAGE) return 1;

        return Math.ceil(totalItemsCount / MS_CONFIG.MAX_ITEMS_PER_PAGE);
    }

    private getCartNumberOfPages(playerId: number): number {
        const totalCartItems = this.getTotalItemsInCart(playerId);
        if (totalCartItems <= MS_CONFIG.MAX_ITEMS_CART_PER_PAGE) return 1;
        return Math.ceil(totalCartItems / MS_CONFIG.MAX_ITEMS_CART_PER_PAGE);
    }

    private getTotalValidItems(playerId: number): number {
        const items = this.playerItems.get(playerId);
        if (!items) return 0;

        return items.filter(item => item.itemID !== MSTORE_INVALID_ITEM_ID).length;
    }

    private getTotalItemsInCart(playerId: number): number {
        const cart = this.playerCart.get(playerId);
        if (!cart) return 0;

        return cart.filter(item => item.itemID !== MSTORE_INVALID_ITEM_ID).length;
    }

    private getItemNameByID(playerId: number, id: number): string {
        const items = this.playerItems.get(playerId);
        if (!items) return "N/A";

        for (const item of items) {
            if (item.itemID === id) {
                return item.itemName;
            }
        }
        return "N/A";
    }

    private getItemModelByID(playerId: number, id: number): number {
        const items = this.playerItems.get(playerId);
        if (!items) return 0;

        for (const item of items) {
            if (item.itemID === id) {
                return item.itemModel;
            }
        }
        return 0;
    }

    private addToCart(player: Player, itemID: number, price: number, amount: number): void {
        const cart = this.playerCart.get(player.id);
        if (!cart) return;

        // Find empty slot in cart
        for (let i = 0; i < cart.length; i++) {
            const item = cart[i];
            if (item.itemID === MSTORE_INVALID_ITEM_ID) {
                item.itemID = itemID;
                item.itemPrice = price;
                item.itemAmount = amount;
                
                console.log(`[MenuStore Debug] Added to cart: ${this.getItemNameByID(player.id, itemID)} (${amount}x) at slot ${i}`);
                
                // Update cart visuals
                this.setCartPage(player, this.playerInfo.get(player.id)?.currentCartPage || 1);
                this.updateCartTotalValue(player);
                
                // Notify player
                const itemName = this.getItemNameByID(player.id, itemID);
                player.sendClientMessage(0x00FF00FF, `Added to cart: ${amount}x ${itemName}`);
                break;
            }
        }
    }

    private removeFromCart(player: Player, row: number): void {
        const cart = this.playerCart.get(player.id);
        if (!cart || !cart[row]) return;

        cart[row].itemID = MSTORE_INVALID_ITEM_ID;
        cart[row].itemPrice = 0;
        cart[row].itemAmount = 0;

        this.updateCartTotalValue(player);
        this.sortCart(player);
    }

    private sortCart(player: Player): void {
        const cart = this.playerCart.get(player.id);
        if (!cart) return;

        // Compact cart: move valid items to the front, fill the rest with empty slots
        const validItems = cart.filter(item => item.itemID !== MSTORE_INVALID_ITEM_ID);
        const emptySlots = Array(MS_CONFIG.MAX_ITEMS_CART - validItems.length).fill({ itemID: MSTORE_INVALID_ITEM_ID, itemPrice: 0, itemAmount: 0 });
        const newCart = validItems.concat(emptySlots);
        for (let i = 0; i < cart.length; i++) {
            cart[i] = { ...newCart[i] };
        }

        this.updateCart(player);
    }

    private updateCart(player: Player): void {
        const playerStoreInfo = this.playerInfo.get(player.id);
        if (!playerStoreInfo) return;

        const totalCartPages = this.getCartNumberOfPages(player.id);
        if (playerStoreInfo.currentCartPage > totalCartPages && totalCartPages > 0) {
            playerStoreInfo.currentCartPage = totalCartPages;
        } else if (totalCartPages === 0) {
            playerStoreInfo.currentCartPage = 1;
        }

        this.setCartPage(player, playerStoreInfo.currentCartPage);
        this.updateCartPagination(player, playerStoreInfo.currentCartPage);
        
        // Actualizar visibilidad de botones de navegación del carrito
        if (totalCartPages > 1) {
            this.globalTextDraws?.cartPrevious?.show(player);
            this.globalTextDraws?.cartNext?.show(player);
        } else {
            this.globalTextDraws?.cartPrevious?.hide(player);
            this.globalTextDraws?.cartNext?.hide(player);
        }
    }

    private updateCartTotalValue(player: Player): void {
        const cart = this.playerCart.get(player.id);
        const textDraws = this.playerTextDraws.get(player.id);
        const playerStoreInfo = this.playerInfo.get(player.id);
        
        if (!cart || !textDraws || !playerStoreInfo) return;

        let totalValue = 0;
        for (const item of cart) {
            if (item.itemID !== MSTORE_INVALID_ITEM_ID) {
                totalValue += item.itemPrice * item.itemAmount;
            }
        }

        // Destruir textdraw existente del total
        textDraws.cartTotal?.destroy();
        textDraws.cartTotal = null;

        // Crear nuevo textdraw del total
        textDraws.cartTotal = new TextDraw({
            player: player,
            x: 339.200012,
            y: 386.949951,
            text: `${MS_CONFIG.WORD_TOTAL}: ${playerStoreInfo.moneySign}${totalValue}`,
            charset: player.charset
        });

        textDraws.cartTotal
            .create()
            .setLetterSize(0.219999, 1.331665)
            .setTextSize(437.000000, 0.0)
            .setAlignment(1)
            .setColor(MS_COLORS.TEXT_MAIN)
            .setShadow(0)
            .setOutline(0)
            .setFont(2)
            .setProportional(true)
            .show(player);
    }

    private showQuantityDialog(player: Player, index: number): void {
        const playerStoreInfo = this.playerInfo.get(player.id);
        const items = this.playerItems.get(player.id);
        if (!playerStoreInfo || !items) return;

        playerStoreInfo.toggleControll = false;
        this.selectRow(player, playerStoreInfo.selected);

        const dialog = new Dialog({
            style: DialogStylesEnum.INPUT,
            caption: MS_CONFIG.MSG_TITLE_DIALOG,
            info: `${MS_CONFIG.MSG_DIALOG} (${MS_CONFIG.WORD_LIMIT}: ${items[index].itemStack})`,
            button1: MS_CONFIG.WORD_GO,
            button2: MS_CONFIG.WORD_CANCEL
        });

        dialog.show(player).then(({ response, inputText }) => {
            playerStoreInfo.toggleControll = true;
            this.closeDescription(player);

            if (!response || playerStoreInfo.selected === -1 || !inputText) {
                this.unselectRow(player);
                // Reactivate TextDraw selection mode if store is still open
                if (playerStoreInfo.isOpen) {
                    player.selectTextDraw(MS_COLORS.SELECT_TD);
                }
                return;
            }

            const quantity = parseInt(inputText);
            if (isNaN(quantity) || quantity < 1 || quantity > items[index].itemStack) {
                this.unselectRow(player);
                // Reactivate TextDraw selection mode if store is still open
                if (playerStoreInfo.isOpen) {
                    player.selectTextDraw(MS_COLORS.SELECT_TD);
                }
                return;
            }

            this.addToCart(player, items[index].itemID, items[index].itemPrice, quantity);
            this.unselectRow(player);
            // Reactivate TextDraw selection mode if store is still open
            if (playerStoreInfo.isOpen) {
                player.selectTextDraw(MS_COLORS.SELECT_TD);
            }
        });
    }

    private setPage(player: Player, pageId: number): void {
        const items = this.playerItems.get(player.id);
        const textDraws = this.playerTextDraws.get(player.id);
        const playerStoreInfo = this.playerInfo.get(player.id);
        
        if (!items || !textDraws || !playerStoreInfo) return;

        const startIndex = MS_CONFIG.MAX_ITEMS_PER_PAGE * (pageId - 1);
        let currentRow = 0;

        // Remove existing item textdraws
        for (let i = 0; i < MS_CONFIG.MAX_ITEMS_PER_PAGE; i++) {
            textDraws.itemBackground[i]?.destroy();
            textDraws.itemName[i]?.destroy();
            textDraws.itemPrice[i]?.destroy();
            textDraws.itemModel[i]?.destroy();
            textDraws.itemBackground[i] = null;
            textDraws.itemName[i] = null;
            textDraws.itemPrice[i] = null;
            textDraws.itemModel[i] = null;
        }

        // Create new item textdraws for actual items
        for (let i = startIndex; i < Math.min(startIndex + MS_CONFIG.MAX_ITEMS_PER_PAGE, MS_CONFIG.MAX_ITEMS); i++) {
            const item = items[i];
            if (item.itemID === MSTORE_INVALID_ITEM_ID || currentRow >= MS_CONFIG.MAX_ITEMS_PER_PAGE) continue;

            const baseY = 155.2 + (currentRow * 39.0);

            // Item background
            textDraws.itemBackground[currentRow] = new TextDraw({
                player: player,
                x: 158.0,
                y: baseY,
                text: "box",
                charset: player.charset
            });

            textDraws.itemBackground[currentRow]!
                .create()
                .setLetterSize(0.0, 3.3)
                .setTextSize(311.0, 22.0)
                .setAlignment(1)
                .setColor(0xFFFFFFFF)
                .useBox(true)
                .setBoxColors(MS_COLORS.BACKGROUND_ITEM)
                .setShadow(0)
                .setOutline(0)
                .setFont(1)
                .setProportional(true)
                .setSelectable(true)
                .show(player);

            // Item name
            textDraws.itemName[currentRow] = new TextDraw({
                player: player,
                x: 190.0,
                y: baseY + 3.0,
                text: item.itemName,
                charset: player.charset
            });

            textDraws.itemName[currentRow]!
                .create()
                .setLetterSize(0.231, 1.198)
                .setTextSize(310.0, 0.0)
                .setAlignment(1)
                .setColor(MS_COLORS.TEXT_MAIN)
                .useBox(true)
                .setBoxColors(0xFFFFFF00)
                .setShadow(0)
                .setOutline(0)
                .setFont(2)
                .setProportional(true)
                .show(player);

            // Item price
            textDraws.itemPrice[currentRow] = new TextDraw({
                player: player,
                x: 311.1,
                y: baseY + 18.0,
                text: `${playerStoreInfo.moneySign}${item.itemPrice}`,
                charset: player.charset
            });

            textDraws.itemPrice[currentRow]!
                .create()
                .setLetterSize(0.284, 1.227)
                .setTextSize(0.0, 0.0)
                .setAlignment(3)
                .setColor(MS_COLORS.TEXT_MAIN)
                .setShadow(0)
                .setOutline(0)
                .setFont(2)
                .setProportional(true)
                .show(player);

            // Item model (3D preview)
            textDraws.itemModel[currentRow] = new TextDraw({
                player: player,
                x: 158.7,
                y: baseY + 1.0,
                text: "",
                charset: player.charset
            });

            textDraws.itemModel[currentRow]!
                .create()
                .setLetterSize(0.0, 0.0)
                .setTextSize(29.0, 28.0)
                .setAlignment(1)
                .setColor(0xFFFFFFFF)
                .setShadow(0)
                .setOutline(0)
                .setBackgroundColors(MS_COLORS.BACKGROUND_MODEL)
                .setFont(5)
                .setProportional(false)
                .setPreviewModel(item.itemModel)
                .setPreviewRot(item.itemPreviewRot[0], item.itemPreviewRot[1], item.itemPreviewRot[2], item.itemPreviewRot[3])
                .show(player);

            currentRow++;
        }

        // Update pagination
        textDraws.pagination?.destroy();
        textDraws.pagination = null;

        if (playerStoreInfo.totalItems > MS_CONFIG.MAX_ITEMS_PER_PAGE) {
            const totalPages = this.getNumberOfPages(player.id);
            textDraws.pagination = new TextDraw({
                player: player,
                x: 232.25,
                y: 388.98,
                text: `${pageId}/${totalPages}`,
                charset: player.charset
            });

            textDraws.pagination
                .create()
                .setLetterSize(0.318, 1.454)
                .setTextSize(0.0, 0.0)
                .setAlignment(2)
                .setColor(MS_COLORS.TEXT_MAIN)
                .setShadow(0)
                .setOutline(0)
                .setFont(2)
                .setProportional(true)
                .show(player);
        }
    }

    private selectRow(player: Player, row: number): void {
        const playerStoreInfo = this.playerInfo.get(player.id);
        const textDraws = this.playerTextDraws.get(player.id);
        if (!playerStoreInfo || !textDraws) return;

        playerStoreInfo.selected = row;
        
        if (textDraws.itemBackground[row]) {
            textDraws.itemBackground[row]!.setBoxColors(MS_COLORS.BACKGROUND_ITEM_SELECTED);
            textDraws.itemBackground[row]!.hide(player);
            textDraws.itemBackground[row]!.show(player);
        }
    }

    private unselectRow(player: Player): void {
        const playerStoreInfo = this.playerInfo.get(player.id);
        const textDraws = this.playerTextDraws.get(player.id);
        if (!playerStoreInfo || !textDraws || playerStoreInfo.selected === -1) return;

        const row = playerStoreInfo.selected;
        if (textDraws.itemBackground[row]) {
            textDraws.itemBackground[row]!.setBoxColors(MS_COLORS.BACKGROUND_ITEM);
            textDraws.itemBackground[row]!.hide(player);
            textDraws.itemBackground[row]!.show(player);
        }

        playerStoreInfo.selected = -1;
    }

    private openDescription(player: Player, index: number): void {
        console.log(`Opening description ${index} for ${player.getName()}`);
        // Basic implementation - can be expanded later
    }

    private closeDescription(player: Player): void {
        console.log(`Closing description for ${player.getName()}`);
        // Basic implementation - can be expanded later
    }

    private createCartRow(player: Player, row: number): void {
        const cart = this.playerCart.get(player.id);
        const textDraws = this.playerTextDraws.get(player.id);
        const playerStoreInfo = this.playerInfo.get(player.id);
        
        if (!cart || !textDraws || !playerStoreInfo) return;

        const cartItem = cart[row];
        if (cartItem.itemID === MSTORE_INVALID_ITEM_ID) return;

        // Calcular la posición visual en la página actual del carrito
        const pageStartIndex = (playerStoreInfo.currentCartPage - 1) * MS_CONFIG.MAX_ITEMS_CART_PER_PAGE;
        const visualRow = row - pageStartIndex;
        
        // Solo crear si está en la página actual
        if (visualRow < 0 || visualRow >= MS_CONFIG.MAX_ITEMS_CART_PER_PAGE) return;

        const baseY = 293.88 + (visualRow * 23.0);

        // Destruir textdraws existentes para esta fila visual
        textDraws.cartItemBackground[visualRow]?.destroy();
        textDraws.cartItemName[visualRow]?.destroy();
        textDraws.cartItemClose[visualRow]?.destroy();

        // Cart item background
        textDraws.cartItemBackground[visualRow] = new TextDraw({
            player: player,
            x: 344.0,
            y: baseY,
            text: "box",
            charset: player.charset
        });

        textDraws.cartItemBackground[visualRow]!
            .create()
            .setLetterSize(0.0, 1.55)
            .setTextSize(505.0, 15.0)
            .setAlignment(1)
            .setColor(0xFFFFFFFF)
            .useBox(true)
            .setBoxColors(MS_COLORS.BACKGROUND_ITEM)
            .setShadow(0)
            .setOutline(0)
            .setFont(1)
            .setProportional(true)
            .setSelectable(true)
            .show(player);

        // Cart item name y cantidad
        const itemName = this.getItemNameByID(player.id, cartItem.itemID);
        const itemTotal = cartItem.itemPrice * cartItem.itemAmount;
        
        textDraws.cartItemName[visualRow] = new TextDraw({
            player: player,
            x: 345.2,
            y: baseY + 0.7,
            text: `${cartItem.itemAmount}x ${itemName} - ${playerStoreInfo.moneySign}${itemTotal}`,
            charset: player.charset
        });

        textDraws.cartItemName[visualRow]!
            .create()
            .setLetterSize(0.18, 1.0)
            .setTextSize(500.0, 0.0)
            .setAlignment(1)
            .setColor(MS_COLORS.TEXT_MAIN)
            .useBox(true)
            .setBoxColors(0xFFFFFF00)
            .setShadow(0)
            .setOutline(0)
            .setFont(2)
            .setProportional(true)
            .show(player);

        // Cart item close button (X)
        textDraws.cartItemClose[visualRow] = new TextDraw({
            player: player,
            x: 502.0,
            y: baseY + 0.7,
            text: "X",
            charset: player.charset
        });

        textDraws.cartItemClose[visualRow]!
            .create()
            .setLetterSize(0.25, 1.2)
            .setTextSize(0.0, 0.0)
            .setAlignment(3)
            .setColor(MS_COLORS.CART_REMOVE_ITEM)
            .setShadow(0)
            .setOutline(0)
            .setFont(1)
            .setProportional(true)
            .show(player);

        console.log(`[MenuStore Debug] Cart row ${visualRow} created for item ${itemName} (${cartItem.itemAmount}x)`);
    }

    private setCartPage(player: Player, pageId: number): void {
        const cart = this.playerCart.get(player.id);
        const textDraws = this.playerTextDraws.get(player.id);
        const playerStoreInfo = this.playerInfo.get(player.id);
        
        if (!cart || !textDraws || !playerStoreInfo) return;

        // Limpiar todos los textdraws del carrito
        for (let i = 0; i < MS_CONFIG.MAX_ITEMS_CART_PER_PAGE; i++) {
            textDraws.cartItemBackground[i]?.destroy();
            textDraws.cartItemName[i]?.destroy();
            textDraws.cartItemClose[i]?.destroy();
            textDraws.cartItemBackground[i] = null;
            textDraws.cartItemName[i] = null;
            textDraws.cartItemClose[i] = null;
        }

        // Calcular índices para esta página
        const startIndex = (pageId - 1) * MS_CONFIG.MAX_ITEMS_CART_PER_PAGE;
        const endIndex = Math.min(startIndex + MS_CONFIG.MAX_ITEMS_CART_PER_PAGE, MS_CONFIG.MAX_ITEMS_CART);
        
        let visualRow = 0;
        
        // Mostrar items de esta página
        for (let i = startIndex; i < endIndex && visualRow < MS_CONFIG.MAX_ITEMS_CART_PER_PAGE; i++) {
            const cartItem = cart[i];
            if (cartItem.itemID !== MSTORE_INVALID_ITEM_ID) {
                const baseY = 293.88 + (visualRow * 23.0);

                // Cart item background
                textDraws.cartItemBackground[visualRow] = new TextDraw({
                    player: player,
                    x: 344.0,
                    y: baseY,
                    text: "box",
                    charset: player.charset
                });

                textDraws.cartItemBackground[visualRow]!
                    .create()
                    .setLetterSize(0.0, 1.55)
                    .setTextSize(505.0, 15.0)
                    .setAlignment(1)
                    .setColor(0xFFFFFFFF)
                    .useBox(true)
                    .setBoxColors(MS_COLORS.BACKGROUND_ITEM)
                    .setShadow(0)
                    .setOutline(0)
                    .setFont(1)
                    .setProportional(true)
                    .setSelectable(true)
                    .show(player);

                // Cart item name y información
                const itemName = this.getItemNameByID(player.id, cartItem.itemID);
                const itemTotal = cartItem.itemPrice * cartItem.itemAmount;
                
                textDraws.cartItemName[visualRow] = new TextDraw({
                    player: player,
                    x: 345.2,
                    y: baseY + 0.7,
                    text: `${cartItem.itemAmount}x ${itemName} - ${playerStoreInfo.moneySign}${itemTotal}`,
                    charset: player.charset
                });

                textDraws.cartItemName[visualRow]!
                    .create()
                    .setLetterSize(0.18, 1.0)
                    .setTextSize(500.0, 0.0)
                    .setAlignment(1)
                    .setColor(MS_COLORS.TEXT_MAIN)
                    .useBox(true)
                    .setBoxColors(0xFFFFFF00)
                    .setShadow(0)
                    .setOutline(0)
                    .setFont(2)
                    .setProportional(true)
                    .show(player);

                // Cart item close button (X)
                textDraws.cartItemClose[visualRow] = new TextDraw({
                    player: player,
                    x: 502.0,
                    y: baseY + 0.7,
                    text: "X",
                    charset: player.charset
                });

                textDraws.cartItemClose[visualRow]!
                    .create()
                    .setLetterSize(0.25, 1.2)
                    .setTextSize(0.0, 0.0)
                    .setAlignment(3)
                    .setColor(MS_COLORS.CART_REMOVE_ITEM)
                    .setShadow(0)
                    .setOutline(0)
                    .setFont(1)
                    .setProportional(true)
                    .show(player);

                visualRow++;
            }
        }

        console.log(`[MenuStore Debug] Cart page ${pageId} set with ${visualRow} visible items`);
    }

    private updateCartPagination(player: Player, pageId: number): void {
        // Only destroy if exists, but DO NOT create a new one
        const textDraws = this.playerTextDraws.get(player.id);
        if (!textDraws) return;

        textDraws.cartPagination?.destroy();
        textDraws.cartPagination = null;
    }

    private processPurchase(player: Player): void {
        const cart = this.playerCart.get(player.id);
        const playerStoreInfo = this.playerInfo.get(player.id);
        if (!cart || !playerStoreInfo) return;

        let totalPrice = 0;
        const purchasedItems: Array<{itemID: number, model: number, amount: number, price: number, name: string}> = [];

        // Calculate total and prepare purchase data
        for (const item of cart) {
            if (item.itemID !== MSTORE_INVALID_ITEM_ID) {
                const itemTotal = item.itemPrice * item.itemAmount;
                totalPrice += itemTotal;
                
                purchasedItems.push({
                    itemID: item.itemID,
                    model: this.getItemModelByID(player.id, item.itemID),
                    amount: item.itemAmount,
                    price: itemTotal,
                    name: this.getItemNameByID(player.id, item.itemID)
                });
            }
        }

        // Execute callback for each purchased item
        const callback = this.storeCallbacks.get(playerStoreInfo.storeID);
        if (callback) {
            for (const item of purchasedItems) {
                callback(player, true, item.itemID, item.model, item.price, item.amount, item.name);
            }
        }

        // Clear cart
        this.clearCart(player);
    }

    private clearCart(player: Player): void {
        const cart = this.playerCart.get(player.id);
        if (!cart) return;

        for (let i = 0; i < cart.length; i++) {
            cart[i].itemID = MSTORE_INVALID_ITEM_ID;
            cart[i].itemPrice = 0;
            cart[i].itemAmount = 0;
        }
    }

    public closeStore(player: Player): void {
        const playerStoreInfo = this.playerInfo.get(player.id);
        const textDraws = this.playerTextDraws.get(player.id);
        
        if (!playerStoreInfo || !textDraws) return;

        playerStoreInfo.isOpen = false;
        playerStoreInfo.toggleControll = false;

        // Hide and destroy all player textdraws
        for (let i = 0; i < MS_CONFIG.MAX_ITEMS_PER_PAGE; i++) {
            textDraws.itemBackground[i]?.hide(player);
            textDraws.itemBackground[i]?.destroy();
            textDraws.itemName[i]?.hide(player);
            textDraws.itemName[i]?.destroy();
            textDraws.itemPrice[i]?.hide(player);
            textDraws.itemPrice[i]?.destroy();
            textDraws.itemModel[i]?.hide(player);
            textDraws.itemModel[i]?.destroy();
            textDraws.itemBackground[i] = null;
            textDraws.itemName[i] = null;
            textDraws.itemPrice[i] = null;
            textDraws.itemModel[i] = null;
        }

        for (let i = 0; i < MS_CONFIG.MAX_ITEMS_CART_PER_PAGE; i++) {
            textDraws.cartItemBackground[i]?.hide(player);
            textDraws.cartItemBackground[i]?.destroy();
            textDraws.cartItemName[i]?.hide(player);
            textDraws.cartItemName[i]?.destroy();
            textDraws.cartItemClose[i]?.hide(player);
            textDraws.cartItemClose[i]?.destroy();
            textDraws.cartItemBackground[i] = null;
            textDraws.cartItemName[i] = null;
            textDraws.cartItemClose[i] = null;
        }

        // Hide and destroy other player textdraws
        textDraws.storeName?.hide(player);
        textDraws.storeName?.destroy();
        textDraws.pagination?.hide(player);
        textDraws.pagination?.destroy();
        textDraws.cartPagination?.hide(player);
        textDraws.cartPagination?.destroy();
        textDraws.descriptionItemName?.hide(player);
        textDraws.descriptionItemName?.destroy();
        textDraws.descriptionItemText?.hide(player);
        textDraws.descriptionItemText?.destroy();
        textDraws.descriptionItemModel?.hide(player);
        textDraws.descriptionItemModel?.destroy();
        textDraws.cartBuyName?.hide(player);
        textDraws.cartBuyName?.destroy();
        textDraws.cartTotal?.hide(player);
        textDraws.cartTotal?.destroy();

        for (let i = 0; i < 2; i++) {
            textDraws.descriptionBackground[i]?.hide(player);
            textDraws.descriptionBackground[i]?.destroy();
            textDraws.descriptionBackground[i] = null;
        }

        // Hide global textdraws
        this.globalTextDraws?.backgrounds[0]?.hide(player);
        this.globalTextDraws?.backgrounds[1]?.hide(player);
        this.globalTextDraws?.next?.hide(player);
        this.globalTextDraws?.previous?.hide(player);
        this.globalTextDraws?.cartBackgrounds[0]?.hide(player);
        this.globalTextDraws?.cartBackgrounds[1]?.hide(player);
        this.globalTextDraws?.cartBackgroundConfirm?.hide(player);
        this.globalTextDraws?.cartCartName?.hide(player);
        this.globalTextDraws?.cartNext?.hide(player);
        this.globalTextDraws?.cartPrevious?.hide(player);

        // Reset player state
        playerStoreInfo.currentPage = 1;
        playerStoreInfo.currentCartPage = 1;
        playerStoreInfo.selected = -1;
        playerStoreInfo.doubleClick = 0;
        playerStoreInfo.doubleClickRow = -1;
        playerStoreInfo.toggleControll = true;

        // Clear cart
        this.clearCart(player);

        // Cancelar modo de selección de TextDraw
        player.cancelSelectTextDraw();
    }

    public addItem(
        player: Player,
        itemID: number,
        modelID: number,
        name: string,
        price: number,
        description: string = "",
        descriptionSize: number = MS_CONFIG.MAX_SIZE_DESCRIPTION,
        descriptionLineJump: boolean = true,
        stack: number = 1,
        rotX: number = 0.0,
        rotY: number = 0.0,
        rotZ: number = 0.0,
        zoom: number = 1.0
    ): boolean {
        const items = this.playerItems.get(player.id);
        const playerStoreInfo = this.playerInfo.get(player.id);
        
        if (!items || !playerStoreInfo) return false;

        // Find empty slot
        for (let i = 0; i < MS_CONFIG.MAX_ITEMS; i++) {
            if (items[i].itemID === MSTORE_INVALID_ITEM_ID) {
                items[i].itemID = itemID;
                items[i].itemModel = modelID;
                items[i].itemName = name;
                items[i].itemPrice = price;
                items[i].itemDescription = description;
                items[i].itemDescriptionBonus = descriptionSize;
                items[i].itemLineJump = descriptionLineJump;
                items[i].itemStack = stack;
                items[i].itemPreviewRot = [rotX, rotY, rotZ, zoom];
                
                playerStoreInfo.totalItems++;
                return true;
            }
        }
        
        return false;
    }

    public openStore(
        player: Player,
        storeID: string,
        storeName: string,
        callback: StoreCallback,
        moneySign: string = MS_CONFIG.DEFAULT_MONEY_SIGN,
        buttonConfirm: string = MS_CONFIG.DEFAULT_CONFIRM
    ): boolean {
        const playerStoreInfo = this.playerInfo.get(player.id);
        const textDraws = this.playerTextDraws.get(player.id);
        
        if (!playerStoreInfo || !textDraws || playerStoreInfo.isOpen) return false;

        // Store callback
        this.storeCallbacks.set(storeID, callback);

        // Set store info
        playerStoreInfo.isOpen = true;
        playerStoreInfo.storeID = storeID;
        playerStoreInfo.moneySign = moneySign;
        playerStoreInfo.currentPage = 1;
        playerStoreInfo.currentCartPage = 1;
        playerStoreInfo.selected = -1;
        playerStoreInfo.toggleControll = true;

        // Show global textdraws
        this.globalTextDraws?.backgrounds[0]?.show(player);
        this.globalTextDraws?.backgrounds[1]?.show(player);
        this.globalTextDraws?.next?.show(player);
        this.globalTextDraws?.previous?.show(player);
        this.globalTextDraws?.cartBackgrounds[0]?.show(player);
        this.globalTextDraws?.cartBackgrounds[1]?.show(player);
        this.globalTextDraws?.cartBackgroundConfirm?.show(player);
        this.globalTextDraws?.cartCartName?.show(player);

        // --- Restaurar posición y estilo originales de los textos clave ---

        // Título de la tienda
        textDraws.storeName = new TextDraw({
            player: player,
            x: 150.84,
            y: 129.85,
            text: storeName,
            charset: player.charset
        });

        textDraws.storeName
            .create()
            .setLetterSize(0.31, 1.435)
            .setTextSize(315.0, 0.0)
            .setAlignment(1)
            .setColor(MS_COLORS.TEXT_MAIN)
            .useBox(true)
            .setBoxColors(0x00000000)
            .setShadow(0)
            .setOutline(0)
            .setFont(2)
            .setProportional(true)
            .show(player);

        // Texto del total
        textDraws.cartTotal = new TextDraw({
            player: player,
            x: 339.200012,
            y: 386.949951,
            text: `${MS_CONFIG.WORD_TOTAL}: ${playerStoreInfo.moneySign}0`,
            charset: player.charset
        });

        textDraws.cartTotal
            .create()
            .setLetterSize(0.219999, 1.331665)
            .setTextSize(437.000000, 0.0)
            .setAlignment(1)
            .setColor(MS_COLORS.TEXT_MAIN)
            .useBox(true)
            .setBoxColors(0xFFFFFF00)
            .setShadow(0)
            .setOutline(0)
            .setFont(2)
            .setProportional(true)
            .show(player);

        // Botón "comprar"
        textDraws.cartBuyName = new TextDraw({
            player: player,
            x: 476.0,
            y: 388.5,
            text: buttonConfirm,
            charset: player.charset
        });

        textDraws.cartBuyName
            .create()
            .setLetterSize(0.282, 1.2)
            .setTextSize(0.0, 61.0)
            .setAlignment(2)
            .setColor(MS_COLORS.TEXT_MAIN)
            .useBox(false)
            .setShadow(0)
            .setOutline(0)
            .setFont(2)
            .setProportional(true)
            .show(player);

        // Set initial page and cart
        this.setPage(player, 1);
        this.setCartPage(player, 1);
        this.updateCartTotalValue(player);

        // Activar modo de selección de TextDraw
        player.selectTextDraw(MS_COLORS.SELECT_TD);
        return true;
    }

    public isStoreOpen(player: Player): boolean {
        const playerStoreInfo = this.playerInfo.get(player.id);
        return playerStoreInfo ? playerStoreInfo.isOpen : false;
    }
}

// Export singleton instance
export const menuStoreManager = new MenuStoreManager();

// Exported functions for initialization
export function MenuStore_InitializeGameMode(): void {
    menuStoreManager.initializeGameModeEvents();
}

export function MenuStore_InitializePlayerEvents(): void {
    menuStoreManager.initializePlayerEvents();
}

export function MenuStore_InitializePlayer(player: Player): void {
    menuStoreManager.initializePlayerData(player);
}

// Exported functions for easy use
export function MenuStore_AddItem(
    player: Player,
    itemID: number,
    modelID: number,
    name: string,
    price: number,
    description?: string,
    descriptionSize?: number,
    descriptionLineJump?: boolean,
    stack?: number,
    rotX?: number,
    rotY?: number,
    rotZ?: number,
    zoom?: number
): boolean {
    return menuStoreManager.addItem(
        player, itemID, modelID, name, price, 
        description, descriptionSize, descriptionLineJump, 
        stack, rotX, rotY, rotZ, zoom
    );
}

export function MenuStore_Open(
    player: Player,
    storeID: string,
    storeName: string,
    callback: StoreCallback,
    moneySign?: string,
    buttonConfirm?: string
): boolean {
    return menuStoreManager.openStore(player, storeID, storeName, callback, moneySign, buttonConfirm);
}

export function MenuStore_Close(player: Player): void {
    menuStoreManager.closeStore(player);
}

export function MenuStore_IsOpen(player: Player): boolean {
    return menuStoreManager.isStoreOpen(player);
}

export function MenuStore_CleanupPlayer(player: Player): void {
    menuStoreManager.cleanupPlayerData(player);
}