local PT = AhUI
if not PT or not PT.FarmTracker then return end

local FT = PT.FarmTracker
FT.Prices = FT.Prices or {}
local P = FT.Prices

local function SafeCall(fn, ...)
    if type(fn) ~= "function" then return nil end
    local ok, a, b, c = pcall(fn, ...)
    if ok then return a, b, c end
    return nil
end

function P:Init()
    self.available = nil
end

function P:GetAvailableSources()
    local out = {
        AUTO = "Auto",
        VENDOR = "Vendor",
    }

    if Auctionator and Auctionator.API and Auctionator.API.v1 and Auctionator.API.v1.GetAuctionPriceByItemID then
        out.AUCTIONATOR = "Auctionator"
    end

    if TSM_API then
        out.TSM = "TSM"
    end

    self.available = out
    return out
end

function P:IsSourceAvailable(source)
    local sources = self.available or self:GetAvailableSources()
    return sources[source] ~= nil
end

function P:GetVendorPrice(itemID)
    local _, _, _, _, _, _, _, _, _, _, sellPrice = GetItemInfo(itemID)
    return tonumber(sellPrice) or 0
end

function P:GetAuctionatorPrice(itemID)
    if not (Auctionator and Auctionator.API and Auctionator.API.v1 and Auctionator.API.v1.GetAuctionPriceByItemID) then
        return nil
    end
    return SafeCall(Auctionator.API.v1.GetAuctionPriceByItemID, "AhUI", itemID)
end

function P:GetTSMPrice(itemID, itemLink)
    if not TSM_API then return nil end

    local itemString = itemLink or ("i:" .. tostring(itemID))

    if type(TSM_API.GetCustomPriceValue) == "function" then
        local v = SafeCall(TSM_API.GetCustomPriceValue, "dbmarket", itemString)
        if tonumber(v) and tonumber(v) > 0 then
            return tonumber(v)
        end
        v = SafeCall(TSM_API.GetCustomPriceValue, "dbregionmarketavg", itemString)
        if tonumber(v) and tonumber(v) > 0 then
            return tonumber(v)
        end
    end

    if type(TSM_API.GetItemValue) == "function" then
        local v = SafeCall(TSM_API.GetItemValue, itemString, "DBMarket")
        if tonumber(v) and tonumber(v) > 0 then
            return tonumber(v)
        end
    end

    return nil
end

function P:GetSelectedSource()
    local db = FT.Data:GetDB()
    return db.config.priceSource or "AUCTIONATOR"
end

function P:GetPriceBySource(source, itemID, itemLink)
    source = source or self:GetSelectedSource()

    if source == "AUCTIONATOR" then
        local v = self:GetAuctionatorPrice(itemID)
        if tonumber(v) and tonumber(v) > 0 then
            return tonumber(v), "AUCTIONATOR"
        end
    elseif source == "TSM" then
        local v = self:GetTSMPrice(itemID, itemLink)
        if tonumber(v) and tonumber(v) > 0 then
            return tonumber(v), "TSM"
        end
    elseif source == "VENDOR" then
        local v = self:GetVendorPrice(itemID)
        if tonumber(v) and tonumber(v) > 0 then
            return tonumber(v), "VENDOR"
        end
    elseif source == "AUTO" then
        local v = self:GetAuctionatorPrice(itemID)
        if tonumber(v) and tonumber(v) > 0 then
            return tonumber(v), "AUCTIONATOR"
        end

        v = self:GetTSMPrice(itemID, itemLink)
        if tonumber(v) and tonumber(v) > 0 then
            return tonumber(v), "TSM"
        end
    end

    return nil, nil
end

function P:GetItemPrice(itemID, itemLink)
    local db = FT.Data:GetDB()
    local selected = db.config.priceSource or "AUCTIONATOR"
    local price, source = self:GetPriceBySource(selected, itemID, itemLink)
    if price and price > 0 then
        return price, source
    end

    if db.config.autoFallback ~= false then
        local order = { "AUCTIONATOR", "TSM", "VENDOR" }
        for _, src in ipairs(order) do
            if src ~= selected then
                price, source = self:GetPriceBySource(src, itemID, itemLink)
                if price and price > 0 then
                    return price, source
                end
            end
        end
    end

    if db.config.includeVendorFallback ~= false then
        price = self:GetVendorPrice(itemID)
        return price or 0, "VENDOR"
    end

    return 0, selected
end
