package com.openosrs.client.core;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * InventoryState - Manages player inventory and equipment state.
 */
public class InventoryState {
    private static final Logger logger = LoggerFactory.getLogger(InventoryState.class);
    private static final int INVENTORY_SIZE = 28;
    private static final int EQUIPMENT_SIZE = 14;

    private final EventSystem eventSystem;
    private final ReadWriteLock inventoryLock = new ReentrantReadWriteLock();
    private final ReadWriteLock equipmentLock = new ReentrantReadWriteLock();

    // Inventory items [slot] = ItemStack
    private final ItemStack[] inventory = new ItemStack[INVENTORY_SIZE];

    // Equipment items [slot] = ItemStack
    private final ItemStack[] equipment = new ItemStack[EQUIPMENT_SIZE];

    public InventoryState(EventSystem eventSystem) {
        this.eventSystem = eventSystem;
        initializeItems();
    }

    private void initializeItems() {
        for (int i = 0; i < INVENTORY_SIZE; i++) {
            inventory[i] = new ItemStack(-1, 0);
        }
        for (int i = 0; i < EQUIPMENT_SIZE; i++) {
            equipment[i] = new ItemStack(-1, 0);
        }
    }

    public void initialize() {
        logger.debug("Initializing InventoryState");
    }

    public void shutdown() {
        logger.debug("Shutting down InventoryState");
    }

    public void tick() {
        // Update inventory state if needed
    }

    // Inventory management
    public void setInventoryItem(int slot, int itemId, int quantity) {
        if (slot < 0 || slot >= INVENTORY_SIZE) {
            logger.warn("Invalid inventory slot: {}", slot);
            return;
        }

        inventoryLock.writeLock().lock();
        try {
            ItemStack oldItem = inventory[slot];
            inventory[slot] = new ItemStack(itemId, quantity);

            if (oldItem.getItemId() != itemId || oldItem.getQuantity() != quantity) {
                eventSystem.fireInventoryChanged(slot, itemId, quantity);
                logger.debug("Inventory slot {} changed: {} x{}", slot, itemId, quantity);
            }
        } finally {
            inventoryLock.writeLock().unlock();
        }
    }

    public ItemStack getInventoryItem(int slot) {
        if (slot < 0 || slot >= INVENTORY_SIZE) {
            return new ItemStack(-1, 0);
        }

        inventoryLock.readLock().lock();
        try {
            return inventory[slot];
        } finally {
            inventoryLock.readLock().unlock();
        }
    }

    public ItemStack[] getInventory() {
        inventoryLock.readLock().lock();
        try {
            ItemStack[] copy = new ItemStack[INVENTORY_SIZE];
            System.arraycopy(inventory, 0, copy, 0, INVENTORY_SIZE);
            return copy;
        } finally {
            inventoryLock.readLock().unlock();
        }
    }

    public boolean hasItem(int itemId) {
        return findItemSlot(itemId) != -1;
    }

    public int getItemQuantity(int itemId) {
        inventoryLock.readLock().lock();
        try {
            int total = 0;
            for (ItemStack item : inventory) {
                if (item.getItemId() == itemId) {
                    total += item.getQuantity();
                }
            }
            return total;
        } finally {
            inventoryLock.readLock().unlock();
        }
    }

    public int findItemSlot(int itemId) {
        inventoryLock.readLock().lock();
        try {
            for (int i = 0; i < INVENTORY_SIZE; i++) {
                if (inventory[i].getItemId() == itemId) {
                    return i;
                }
            }
            return -1;
        } finally {
            inventoryLock.readLock().unlock();
        }
    }

    public int getEmptySlots() {
        inventoryLock.readLock().lock();
        try {
            int empty = 0;
            for (ItemStack item : inventory) {
                if (item.getItemId() == -1 || item.getQuantity() == 0) {
                    empty++;
                }
            }
            return empty;
        } finally {
            inventoryLock.readLock().unlock();
        }
    }

    public boolean isInventoryFull() {
        return getEmptySlots() == 0;
    }

    // Equipment management
    public void setEquipmentItem(int slot, int itemId, int quantity) {
        if (slot < 0 || slot >= EQUIPMENT_SIZE) {
            logger.warn("Invalid equipment slot: {}", slot);
            return;
        }

        equipmentLock.writeLock().lock();
        try {
            ItemStack oldItem = equipment[slot];
            equipment[slot] = new ItemStack(itemId, quantity);

            if (oldItem.getItemId() != itemId || oldItem.getQuantity() != quantity) {
                // Fire equipment changed event
                logger.debug("Equipment slot {} changed: {} x{}", slot, itemId, quantity);
            }
        } finally {
            equipmentLock.writeLock().unlock();
        }
    }

    public ItemStack getEquipmentItem(int slot) {
        if (slot < 0 || slot >= EQUIPMENT_SIZE) {
            return new ItemStack(-1, 0);
        }

        equipmentLock.readLock().lock();
        try {
            return equipment[slot];
        } finally {
            equipmentLock.readLock().unlock();
        }
    }

    public ItemStack[] getEquipment() {
        equipmentLock.readLock().lock();
        try {
            ItemStack[] copy = new ItemStack[EQUIPMENT_SIZE];
            System.arraycopy(equipment, 0, copy, 0, EQUIPMENT_SIZE);
            return copy;
        } finally {
            equipmentLock.readLock().unlock();
        }
    }

    /**
     * Represents an item stack (item ID + quantity).
     */
    public static class ItemStack {
        private final int itemId;
        private final int quantity;

        public ItemStack(int itemId, int quantity) {
            this.itemId = itemId;
            this.quantity = quantity;
        }

        public int getItemId() { return itemId; }
        public int getQuantity() { return quantity; }
        public boolean isEmpty() { return itemId == -1 || quantity == 0; }

        @Override
        public String toString() {
            return isEmpty() ? "Empty" : String.format("Item[%d] x%d", itemId, quantity);
        }
    }

    /**
     * Equipment slot constants.
     */
    public static class EquipmentSlots {
        public static final int HAT = 0;
        public static final int CAPE = 1;
        public static final int AMULET = 2;
        public static final int WEAPON = 3;
        public static final int BODY = 4;
        public static final int SHIELD = 5;
        public static final int LEGS = 7;
        public static final int HANDS = 9;
        public static final int FEET = 10;
        public static final int RING = 12;
        public static final int AMMO = 13;
    }
}

// ClientConfiguration moved to separate file
