using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;

public class SimpleShopManager : MonoBehaviour
{
    [Header("Shop Settings")]
    public string shopName = "General Store";

    [Header("Available Items (Simple Version)")]
    public List<SimpleShopItem> weapons = new List<SimpleShopItem>();
    public List<SimpleShopItem> armor = new List<SimpleShopItem>();
    public List<SimpleShopItem> miscItems = new List<SimpleShopItem>();

    private UIDocument uiDocument;
    private TeamCharacter currentCustomer;

    // Callback for when character data changes
    public System.Action<TeamCharacter> OnCharacterDataChanged;

    // UI Elements
    private VisualElement shopContainer;
    private TextField searchField;
    private DropdownField categoryFilter;
    private ScrollView itemList;
    private Label shopTitle;
    private Label playerMoney;
    private Button closeButton;

    // Current filter state
    private string currentCategory = "All";
    private string currentSearchTerm = "";

    void Awake()
    {
        // Initialize default items first
        InitializeDefaultItems();
    }

    void Start()
    {
        // Initialize UI in Start() to ensure UIDocument is ready
        uiDocument = GetComponent<UIDocument>();
        if (uiDocument == null)
        {
            Debug.LogError("SimpleShopManager requires a UIDocument component");
            return;
        }

        if (uiDocument.visualTreeAsset == null)
        {
            Debug.LogError("SimpleShopManager: UIDocument needs a Visual Tree Asset assigned! Please assign ShopUI.uxml");
            return;
        }

        InitializeUI();
    }

    void InitializeDefaultItems()
    {
        // Initialize with some default items if lists are empty
        if (weapons.Count == 0)
        {
            weapons.Add(new SimpleShopItem("Simple Sword", "A basic sword for beginners.", ShopItemType.Weapon, 10, 0, 0, "sword,melee,blade,basic",
                new ItemStats { damageBonus = 1 }));
            weapons.Add(new SimpleShopItem("Simple Bow", "A basic bow for shooting arrows.", ShopItemType.Weapon, 15, 0, 0, "bow,ranged,arrow,basic",
                new ItemStats { damageBonus = 1 }));
            weapons.Add(new SimpleShopItem("Iron Sword", "A well-crafted iron sword.", ShopItemType.Weapon, 25, 0, 0, "sword,melee,blade,iron",
                new ItemStats { damageBonus = 2 }));
            weapons.Add(new SimpleShopItem("Composite Bow", "A bow made of multiple materials.", ShopItemType.Weapon, 35, 0, 0, "bow,ranged,arrow,composite",
                new ItemStats { damageBonus = 2 }));
        }

        if (armor.Count == 0)
        {
            armor.Add(new SimpleShopItem("Leather Helmet", "Basic head protection.", ShopItemType.Armor, 5, 0, 0, "helmet,head,leather,light"));
            armor.Add(new SimpleShopItem("Leather Vest", "Simple chest protection.", ShopItemType.Armor, 12, 0, 0, "vest,chest,leather,light",
                new ItemStats { acBonus = 1 }));
            armor.Add(new SimpleShopItem("Iron Chainmail", "Chainmail made of iron rings.", ShopItemType.Armor, 30, 0, 0, "chainmail,chest,iron,medium",
                new ItemStats { acBonus = 2 }));
        }

        if (miscItems.Count == 0)
        {
            miscItems.Add(new SimpleShopItem("Health Potion", "Restores 15 health points.", ShopItemType.Miscellaneous, 3, 0, 0, "potion,health,healing,consumable",
                new ItemStats { healthBonus = 15 }));
            miscItems.Add(new SimpleShopItem("Hemp Rope", "50 feet of sturdy rope.", ShopItemType.Miscellaneous, 0, 8, 0, "rope,hemp,utility,tool"));
            miscItems.Add(new SimpleShopItem("Torch", "Provides light in dark places.", ShopItemType.Miscellaneous, 0, 2, 0, "torch,light,utility"));
        }
    }

    void InitializeUI()
    {
        var root = uiDocument.rootVisualElement;
        Debug.Log("SimpleShopManager: Initializing UI elements...");

        shopContainer = root.Q<VisualElement>("ShopContainer");
        searchField = root.Q<TextField>("SearchField");
        categoryFilter = root.Q<DropdownField>("CategoryFilter");
        itemList = root.Q<ScrollView>("ItemList");
        shopTitle = root.Q<Label>("ShopTitle");
        playerMoney = root.Q<Label>("PlayerMoney");
        closeButton = root.Q<Button>("CloseButton");

        // Debug which elements were found
        Debug.Log($"ShopContainer found: {shopContainer != null}");
        Debug.Log($"SearchField found: {searchField != null}");
        Debug.Log($"CategoryFilter found: {categoryFilter != null}");
        Debug.Log($"ItemList found: {itemList != null}");
        Debug.Log($"ShopTitle found: {shopTitle != null}");
        Debug.Log($"PlayerMoney found: {playerMoney != null}");
        Debug.Log($"CloseButton found: {closeButton != null}");

        // Setup category filter
        if (categoryFilter != null)
        {
            categoryFilter.choices = new List<string> { "All", "Weapons", "Armor", "Miscellaneous" };
            categoryFilter.value = "All";
            categoryFilter.RegisterValueChangedCallback(OnCategoryChanged);
        }

        // Setup search field
        if (searchField != null)
        {
            searchField.RegisterValueChangedCallback(OnSearchChanged);
        }

        // Setup close button
        if (closeButton != null)
        {
            closeButton.clicked += CloseShop;
        }

        // Hide shop initially
        if (shopContainer != null)
        {
            shopContainer.style.display = DisplayStyle.None;
            Debug.Log("SimpleShopManager: Shop initially hidden");
        }

        // Debug UI layering information
        DebugUILayering();
    }

    void DebugUILayering()
    {
        if (uiDocument != null)
        {
            var panelSettings = uiDocument.panelSettings;
            if (panelSettings != null)
            {
                Debug.Log($"Shop Panel Settings - sortingOrder: {panelSettings.sortingOrder}");
            }
            else
            {
                Debug.LogWarning("Shop UIDocument has no Panel Settings! This will cause layering issues.");
            }

            Debug.Log($"Shop UIDocument - sortingOrder: {uiDocument.sortingOrder}");
        }

        // Check for other UIDocuments in the scene for comparison
        var allUIDocuments = FindObjectsByType<UIDocument>(FindObjectsSortMode.None);
        Debug.Log($"Found {allUIDocuments.Length} UIDocuments in scene:");

        foreach (var doc in allUIDocuments)
        {
            var panelSort = doc.panelSettings?.sortingOrder ?? -999;
            Debug.Log($"UIDocument '{doc.gameObject.name}' - sortingOrder: {doc.sortingOrder}, PanelSettings sortingOrder: {panelSort}");
        }
    }

    [ContextMenu("Fix UI Layering")]
    public void FixUILayering()
    {
        if (uiDocument != null)
        {
            // Set the UIDocument sortingOrder to a higher value
            uiDocument.sortingOrder = 10;

            // If Panel Settings exist, also set their sortingOrder
            if (uiDocument.panelSettings != null)
            {
                uiDocument.panelSettings.sortingOrder = 10;
                Debug.Log("Updated Panel Settings sortingOrder to 10");
            }

            Debug.Log("Updated Shop UIDocument sortingOrder to 10 - Shop should now render on top!");
        }
        else
        {
            Debug.LogError("No UIDocument found on SimpleShopManager!");
        }
    }

    public void OpenShop(TeamCharacter customer)
    {
        if (customer == null)
        {
            Debug.LogError("Cannot open shop: customer is null");
            return;
        }

        Debug.Log($"SimpleShopManager: Opening shop for {customer.name}");

        if (uiDocument == null)
        {
            Debug.LogError("SimpleShopManager: UIDocument is null!");
            return;
        }

        if (shopContainer == null)
        {
            Debug.LogError("SimpleShopManager: shopContainer is null! Make sure ShopUI.uxml is assigned to the UIDocument.");
            return;
        }

        currentCustomer = customer;

        // Update UI
        if (shopTitle != null)
        {
            shopTitle.text = shopName;
        }

        UpdatePlayerMoney();
        RefreshItemList();

        // Show shop
        if (shopContainer != null)
        {
            shopContainer.style.display = DisplayStyle.Flex;
            Debug.Log("SimpleShopManager: Shop container visibility set to Flex");
        }

        Debug.Log($"Opened {shopName} for {customer.name}");
    }

    public void CloseShop()
    {
        if (shopContainer != null)
        {
            shopContainer.style.display = DisplayStyle.None;
        }

        currentCustomer = null;
        Debug.Log("Closed shop");
    }

    private void OnCategoryChanged(ChangeEvent<string> evt)
    {
        currentCategory = evt.newValue;
        RefreshItemList();
    }

    private void OnSearchChanged(ChangeEvent<string> evt)
    {
        currentSearchTerm = evt.newValue;
        RefreshItemList();
    }

    private void RefreshItemList()
    {
        if (itemList == null) return;

        itemList.Clear();

        var filteredItems = GetFilteredItems();

        foreach (var item in filteredItems)
        {
            var itemElement = CreateItemElement(item);
            itemList.Add(itemElement);
        }
    }

    private List<SimpleShopItem> GetFilteredItems()
    {
        var allItems = new List<SimpleShopItem>();

        // Add items based on category filter
        if (currentCategory == "All" || currentCategory == "Weapons")
        {
            allItems.AddRange(weapons);
        }
        if (currentCategory == "All" || currentCategory == "Armor")
        {
            allItems.AddRange(armor);
        }
        if (currentCategory == "All" || currentCategory == "Miscellaneous")
        {
            allItems.AddRange(miscItems);
        }

        // Apply search filter
        if (!string.IsNullOrEmpty(currentSearchTerm))
        {
            var searchTerm = currentSearchTerm.ToLower();
            allItems = allItems.FindAll(item =>
                item.name.ToLower().Contains(searchTerm) ||
                item.description.ToLower().Contains(searchTerm) ||
                item.searchTags.ToLower().Contains(searchTerm)
            );
        }

        return allItems;
    }

    private VisualElement CreateItemElement(SimpleShopItem item)
    {
        var container = new VisualElement();
        container.style.flexDirection = FlexDirection.Row;
        container.style.justifyContent = Justify.SpaceBetween;
        container.style.alignItems = Align.Center;
        container.style.paddingLeft = 10;
        container.style.paddingRight = 10;
        container.style.paddingTop = 10;
        container.style.paddingBottom = 10;
        container.style.marginBottom = 5;
        container.style.backgroundColor = new Color(0.95f, 0.95f, 0.95f);
        container.style.borderTopLeftRadius = 5;
        container.style.borderTopRightRadius = 5;
        container.style.borderBottomLeftRadius = 5;
        container.style.borderBottomRightRadius = 5;

        // Item info section
        var infoSection = new VisualElement();
        infoSection.style.flexGrow = 1;

        var nameLabel = new Label(item.name);
        nameLabel.style.fontSize = 16;
        nameLabel.style.unityFontStyleAndWeight = FontStyle.Bold;
        nameLabel.style.color = Color.black;
        infoSection.Add(nameLabel);

        var descriptionLabel = new Label(item.description);
        descriptionLabel.style.fontSize = 12;
        descriptionLabel.style.color = new Color(0.3f, 0.3f, 0.3f);
        infoSection.Add(descriptionLabel);

        container.Add(infoSection);

        // Price and buy section
        var buySection = new VisualElement();
        buySection.style.flexDirection = FlexDirection.Row;
        buySection.style.alignItems = Align.Center;

        var priceLabel = new Label(item.GetCostString());
        priceLabel.style.fontSize = 14;
        priceLabel.style.color = new Color(0, 0.5f, 0);
        priceLabel.style.marginRight = 10;
        buySection.Add(priceLabel);

        var buyButton = new Button(() => PurchaseItem(item));
        buyButton.text = "Buy";
        buyButton.style.width = 60;
        buyButton.style.height = 25;

        // Check if player can afford the item
        bool canAfford = item.CanAfford(currentCustomer);
        buyButton.SetEnabled(canAfford);

        if (!canAfford)
        {
            buyButton.style.backgroundColor = new Color(0.5f, 0.5f, 0.5f);
            buyButton.text = "Can't Afford";
        }
        else
        {
            buyButton.style.backgroundColor = new Color(0, 0.6f, 0);
            buyButton.style.color = Color.white;
        }

        buySection.Add(buyButton);
        container.Add(buySection);

        return container;
    }

    private void PurchaseItem(SimpleShopItem item)
    {
        if (currentCustomer == null || item == null)
        {
            Debug.LogError("Cannot purchase item: missing customer or item");
            return;
        }

        if (!item.CanAfford(currentCustomer))
        {
            Debug.LogWarning($"Cannot afford {item.name}");
            return;
        }

        Debug.Log($"Before purchase: {currentCustomer.name} has {currentCustomer.gold}g {currentCustomer.silver}s {currentCustomer.copper}c");

        // Complete the purchase
        item.Purchase(currentCustomer);

        Debug.Log($"After purchase: {currentCustomer.name} has {currentCustomer.gold}g {currentCustomer.silver}s {currentCustomer.copper}c");

        // Add item to customer's inventory
        if (weapons.Contains(item))
        {
            currentCustomer.weapons.Add(item.name);
            Debug.Log($"Added {item.name} to weapons list. Total weapons: {currentCustomer.weapons.Count}");
        }
        else if (armor.Contains(item))
        {
            currentCustomer.armor.Add(item.name);
            Debug.Log($"Added {item.name} to armor list. Total armor: {currentCustomer.armor.Count}");
        }
        else if (miscItems.Contains(item))
        {
            currentCustomer.miscItems.Add(item.name);
            Debug.Log($"Added {item.name} to misc items list. Total misc items: {currentCustomer.miscItems.Count}");
        }

        // Recalculate all equipment bonuses from inventory (temporary solution)
        currentCustomer.RecalculateEquipmentBonuses();

        if (item.stats != null && !string.IsNullOrEmpty(item.GetStatsString()))
        {
            Debug.Log($"Item {item.name} provides bonuses: {item.GetStatsString()}");
        }

        UpdatePlayerMoney();
        RefreshItemList(); // Refresh to update affordability

        // Notify that character data has changed
        Debug.Log("Triggering OnCharacterDataChanged callback...");
        OnCharacterDataChanged?.Invoke(currentCustomer);

        Debug.Log($"Purchased {item.name} for {currentCustomer.name}");
    }

    private void ApplyItemStats(TeamCharacter character, ItemStats stats)
    {
        if (character == null || stats == null) return;

        // Apply equipment modifiers (these affect final stats calculations)
        character.strengthModifier += stats.strengthBonus;
        character.dexterityModifier += stats.dexterityBonus;
        character.constitutionModifier += stats.constitutionBonus;
        character.wisdomModifier += stats.wisdomBonus;
        character.acModifier += stats.acBonus; // Apply direct AC bonuses

        // Note: AC and HP are calculated properties using Final stats (base + modifiers), 
        // so they will automatically update when the modifiers change.

        // Log what bonuses were applied
        if (stats.acBonus > 0)
        {
            Debug.Log($"Item provides +{stats.acBonus} AC bonus (applied to AC modifier)");
        }
        if (stats.damageBonus > 0)
        {
            Debug.Log($"Item provides +{stats.damageBonus} damage bonus (applied during combat)");
        }
        if (stats.healthBonus > 0)
        {
            Debug.Log($"Item provides +{stats.healthBonus} health bonus (applied through CON bonus)");
        }
        if (stats.movementBonus > 0)
        {
            Debug.Log($"Item provides +{stats.movementBonus} movement bonus");
        }
        if (stats.initiativeBonus != 0)
        {
            Debug.Log($"Item provides {stats.initiativeBonus:+0;-0;0} initiative bonus");
        }
    }

    private void UpdatePlayerMoney()
    {
        if (playerMoney != null && currentCustomer != null)
        {
            string moneyString = "";
            if (currentCustomer.gold > 0) moneyString += $"{currentCustomer.gold}g ";
            if (currentCustomer.silver > 0) moneyString += $"{currentCustomer.silver}s ";
            if (currentCustomer.copper > 0) moneyString += $"{currentCustomer.copper}c";

            playerMoney.text = moneyString.Trim();
        }
    }
}

[System.Serializable]
public class SimpleShopItem
{
    [Header("Basic Info")]
    public string name;
    public string description;
    public ShopItemType itemType;

    [Header("Price")]
    public int goldCost;
    public int silverCost;
    public int copperCost;

    [Header("Item Properties")]
    public ItemStats stats = new ItemStats();
    public string searchTags;

    public SimpleShopItem(string itemName, string itemDescription, ShopItemType type, int gold, int silver, int copper, string tags, ItemStats itemStats = null)
    {
        name = itemName;
        description = itemDescription;
        itemType = type;
        goldCost = gold;
        silverCost = silver;
        copperCost = copper;
        searchTags = tags;
        stats = itemStats ?? new ItemStats();
    }

    public bool CanAfford(TeamCharacter customer)
    {
        if (customer == null) return false;

        int totalCopperCost = goldCost * 100 + silverCost * 10 + copperCost;
        int totalCopperAvailable = customer.gold * 100 + customer.silver * 10 + customer.copper;
        return totalCopperAvailable >= totalCopperCost;
    }

    public void Purchase(TeamCharacter customer)
    {
        if (!CanAfford(customer))
        {
            Debug.LogWarning($"Cannot afford {name}");
            return;
        }

        // Convert everything to copper for easier calculation
        int totalCopperCost = goldCost * 100 + silverCost * 10 + copperCost;
        int totalCopperAvailable = customer.gold * 100 + customer.silver * 10 + customer.copper;

        int remainingCopper = totalCopperAvailable - totalCopperCost;

        // Convert back to gold, silver, copper
        customer.gold = remainingCopper / 100;
        remainingCopper %= 100;
        customer.silver = remainingCopper / 10;
        customer.copper = remainingCopper % 10;

        Debug.Log($"Purchased {name} for {goldCost}g {silverCost}s {copperCost}c");
    }

    public string GetCostString()
    {
        string cost = "";
        if (goldCost > 0) cost += $"{goldCost}g ";
        if (silverCost > 0) cost += $"{silverCost}s ";
        if (copperCost > 0) cost += $"{copperCost}c";
        return cost.Trim();
    }

    public string GetStatsString()
    {
        var statStrings = new List<string>();

        if (stats.damageBonus != 0) statStrings.Add($"Damage: +{stats.damageBonus}");
        if (stats.acBonus != 0) statStrings.Add($"AC: +{stats.acBonus}");
        if (stats.strengthBonus != 0) statStrings.Add($"STR: +{stats.strengthBonus}");
        if (stats.dexterityBonus != 0) statStrings.Add($"DEX: +{stats.dexterityBonus}");
        if (stats.constitutionBonus != 0) statStrings.Add($"CON: +{stats.constitutionBonus}");
        if (stats.wisdomBonus != 0) statStrings.Add($"WIS: +{stats.wisdomBonus}");
        if (stats.movementBonus != 0) statStrings.Add($"Move: +{stats.movementBonus}");
        if (stats.healthBonus != 0) statStrings.Add($"HP: +{stats.healthBonus}");

        return statStrings.Count > 0 ? string.Join(", ", statStrings) : "";
    }
}

[System.Serializable]
public class ItemStats
{
    [Header("Combat Stats")]
    public int damageBonus = 0;
    public int acBonus = 0;

    [Header("Attribute Bonuses")]
    public int strengthBonus = 0;
    public int dexterityBonus = 0;
    public int constitutionBonus = 0;
    public int wisdomBonus = 0;

    [Header("Other Bonuses")]
    public int movementBonus = 0;
    public int healthBonus = 0;
    public int initiativeBonus = 0;
}

[System.Serializable]
public enum ShopItemType
{
    Weapon,
    Armor,
    Miscellaneous
}
