local PT = AhUI
if not PT then return end

PT.ProfessionGuides_Shopping = {}
local S = PT.ProfessionGuides_Shopping

S.session = {
    active   = false,
    listName = nil,
	listReady  = false,
}
S._pendingPurchase = nil
local ADDON_ID  = "AhUI ProfessionGuide"
local LIST_NAME = "AhUI: Profession Guide"
S.OnShoppingDataChanged = nil

local function IsAuctionatorAvailable()
    return Auctionator
       and Auctionator.API
       and Auctionator.API.v1
end

local function EnsureItemInfoLoaded(materials, onReady)
    if not C_Item or not C_Item.RequestLoadItemDataByID then
        onReady()
        return
    end

    local pending = {}

    for itemID in pairs(materials) do
        if materials[itemID] and materials[itemID] > 0 then
            local name = GetItemInfo(itemID)
            if not name then
                pending[itemID] = true
                C_Item.RequestLoadItemDataByID(itemID)
            end
        end
    end

    if not next(pending) then
        onReady()
        return
    end

    local tries = 0
    local function Poll()
        tries = tries + 1

        for itemID in pairs(pending) do
            if GetItemInfo(itemID) then
                pending[itemID] = nil
            end
        end

        if not next(pending) then
            onReady()
            return
        end

        if tries >= 20 then
            onReady()
            return
        end

        C_Timer.After(0.1, Poll)
    end

    Poll()
end

function S:CreateShoppingSession(materials)
    if not materials or not next(materials) then
        return false, "empty"
    end

    if not IsAuctionatorAvailable() then
        return false, "no_auctionator"
    end

    self:EndShoppingSession()

    self.session.active   = true
    self.session.listName = LIST_NAME
	self.session.listReady = false
	
    EnsureItemInfoLoaded(materials, function()
        local searchStrings = {}

        for itemID, needCount in pairs(materials) do
            local itemName = GetItemInfo(itemID)
            if itemName then
                table.insert(
                    searchStrings,
                    Auctionator.API.v1.ConvertToSearchString(
                        ADDON_ID,
                        {
                            searchString = itemName,
                            quantity     = needCount,
                            isExact      = true,
                        }
                    )
                )
            end
        end

		if #searchStrings > 0 then
			Auctionator.API.v1.CreateShoppingList(
				ADDON_ID,
				LIST_NAME,
				searchStrings
			)
			print("AhUI: |cff00ff00Создан список покупок в Auctionator|r")
			S.session.listReady = true
		else
			S.session.listReady = true
		end
    end)

    return true
end

function S:EndShoppingSession()
    self.session.active    = false
    self.session.listName  = nil
    self.session.listReady = false
    self._pendingPurchase  = nil
end

function S:IsAvailable()
    return IsAuctionatorAvailable()
end

S.isAuctionHouseOpen = false

local f = CreateFrame("Frame")
f:RegisterEvent("AUCTION_HOUSE_SHOW")
f:RegisterEvent("AUCTION_HOUSE_CLOSED")

f:SetScript("OnEvent", function(_, event)
    S.isAuctionHouseOpen = (event == "AUCTION_HOUSE_SHOW")

    if event == "AUCTION_HOUSE_CLOSED" then
        S:EndShoppingSession()
    end

    if S.OnAuctionStateChanged then
        S:OnAuctionStateChanged(S.isAuctionHouseOpen)
    end
end)

function S:CanBuy(skillLineID)
    return skillLineID ~= nil
       and IsAuctionatorAvailable()
end

hooksecurefunc(C_AuctionHouse, "ConfirmCommoditiesPurchase", function(itemID, quantity)
    if not S.session.active then return end

    S._pendingPurchase = {
        itemID = itemID,
        quantity = quantity,
    }
end)

function S:UpdateShoppingListAfterPurchase()
    if not self.session.active then return end
    if not self.session.listReady then return end
    if not self._pendingPurchase then return end
    if not IsAuctionatorAvailable() then return end

    local itemID   = self._pendingPurchase.itemID
    local bought   = self._pendingPurchase.quantity
    self._pendingPurchase = nil

    local items =
        Auctionator.API.v1.GetShoppingListItems(
            ADDON_ID,
            self.session.listName
        )

    if not items then return end

    local itemName = GetItemInfo(itemID)
    if not itemName then return end

    for _, searchString in ipairs(items) do
        local terms =
            Auctionator.API.v1.ConvertFromSearchString(
                ADDON_ID,
                searchString
            )

        if terms and terms.searchString == itemName then
            local newQty = (terms.quantity or 0) - bought

            if newQty > 0 then
                local newSearch =
                    Auctionator.API.v1.ConvertToSearchString(
                        ADDON_ID,
                        {
                            searchString = itemName,
                            quantity     = newQty,
                            isExact      = true,
                        }
                    )

                Auctionator.API.v1.AlterShoppingListItem(
                    ADDON_ID,
                    self.session.listName,
                    searchString,
                    newSearch
                )
            else
                Auctionator.API.v1.DeleteShoppingListItem(
                    ADDON_ID,
                    self.session.listName,
                    searchString
                )
            end

            break
        end
    end
end

local ahWatcher = CreateFrame("Frame")
ahWatcher:RegisterEvent("COMMODITY_PURCHASE_SUCCEEDED")

ahWatcher:SetScript("OnEvent", function()
    S:UpdateShoppingListAfterPurchase()
end)