VehicleYears = {}

local function vyprint(value)
    if value ~= nil then
        print("VehicleYears: " .. value)
    else
        print("VehicleYears: nil")
    end
end

local function log_dbg(...)
    if VehicleYears.debugEnabled then
        vyprint(...)
    end
end

local function log_dbg_verbose(...)
    if VehicleYears.verboseDebugEnabled then
        vyprint(...)
    end
end

-- Copied and modified from https://stackoverflow.com/a/27028488
local function dump(o)
    if type(o) == 'table' then
        local s = '{ '
        for k, v in pairs(o) do
            if type(k) ~= 'table' then
                if type(k) ~= 'number' then
                    k = '"' .. k .. '"'
                end
                s = s .. '[' .. k .. '] = ' .. tostring(v) .. ','
            end
        end
        return s .. '} '
    else
        return tostring(o)
    end
end

local function logVehiclesWithoutYear()
    log_dbg("logVehiclesWithoutYear")

    local shopItems = g_storeManager:getItems();

    for index, storeItem in pairs(shopItems) do
        if storeItem ~= nil and
           storeItem.showInStore and
           storeItem.specs.year == nil and
           (string.find(storeItem.xmlFilenameLower, "/vehicles/") or
            string.find(storeItem.xmlFilenameLower, "/handtools/")) then
            vyprint(dump(storeItem))
        end
    end
end

local function storeItemIsMod(storeItem)
    if storeItem == nil then
        return false
    end

    -- Mods like TidyShop may modify the storeItem.isMod to be false, but we can still check if the
    -- customEnvironment (the mod name) exist.
    -- customEnvironment is however also used for paid DLCs (pdlc), so we need to ensure that those
    -- are not considered mods by checking their baseDir (all paid DLCs are an a subdirectory called
    -- /pdlc/)
    return storeItem.customEnvironment ~= nil and string.find(storeItem.baseDir, "pdlc") == nil
end

---Returns the year of a vehicle based on category, brand and name
-- The Categories are values such as animalTransport and baleWrappers
-- @return Year of the vehicle if found otherwise nil
local function loadYearFromXML(storeItem)
    log_dbg("loadYearFromXML")

    local xml_file_name = ""
    local year = nil

    if storeItemIsMod(storeItem) then
        xml_file_name = xml_file_name .. storeItem.customEnvironment .. "_"
    end

    xml_file_name = xml_file_name .. storeItem.rawXMLFilename
    xml_file_name = xml_file_name:gsub("/", "_")
    xml_file_name = xml_file_name:gsub("$data", "base_data")

    if VehicleYearsData ~= nil then
        year = VehicleYearsData[xml_file_name]
        if year ~= nil then
            log_dbg(string.format("year: %s", year))
        end
    end

    return year
end

---Returns the year of a vehicle based on the mod's XML file

-- @return Year of the vehicle if found otherwise nil
local function loadYearFromMod(xmlFilePath)
    log_dbg("loadYearFromMod")

    local year = nil

    if xmlFilePath ~= nil then
        local xmlFile = XMLFile.load("TempXML", xmlFilePath)

        if xmlFile ~= nil then
            year = xmlFile:getString("vehicle.storeData.year")

            if year == nil then
                year = xmlFile:getString("handTool.storeData.year")
            end

            if year ~= nil then
                log_dbg("Year loaded from mod: " .. year)

                -- Vehicles with unknown years are stored as "TBD"
                if year == "TBD" or tonumber(year) == nil then
                    -- Treat TBD or invalid values as nil to not apply the year in-game
                    year = nil
                end
            end

            xmlFile:delete()
        end
    end

    return year
end

---Callback for getting the "year" spec
-- This will use the storeItem to lookup the vehicle in our database
-- @return The year of the vehicle if found otherwise nil
local function loadYear(storeItem, realItem)
    log_dbg("loadYear")
    log_dbg_verbose(dump(storeItem))
    if storeItem.specs == nil then
        -- Ensure that the specs are loaded before accessing the year
        StoreItemUtil.loadSpecsFromXML(storeItem)
    end
    log_dbg_verbose(dump(storeItem.specs))

    log_dbg(string.format("Vehicle: category %s, brand %s, name %s",
        storeItem.categoryName, storeItem.brandNameRaw, storeItem.name))

    log_dbg(storeItem.specs.year)

    -- We store the result in the storeItem - If it is non-nil it means that we
    -- have already stored it, and do not need to lookup in the XML file again
    if storeItem.specs.year == nil then
        if storeItemIsMod(storeItem) then
            -- Try to read the year from the mod XML files for the vehicle first
            storeItem.specs.year = loadYearFromMod(storeItem.xmlFilename)
        end

        if storeItem.specs.year == nil then
            storeItem.specs.year = loadYearFromXML(storeItem)
        end
        -- Add vehicle to pack
        if storeItem.specs.year ~= nil then
            -- Convert to year for easier comparison
            local year = tonumber(storeItem.specs.year)

            if year ~= nil then
                if year < 1950 then
                    g_storeManager:addPackItem("VY_PACK_PRE_1950", storeItem.xmlFilename)
                elseif year < 1960 then
                    g_storeManager:addPackItem("VY_PACK_1950S", storeItem.xmlFilename)
                elseif year < 1970 then
                    g_storeManager:addPackItem("VY_PACK_1960S", storeItem.xmlFilename)
                elseif year < 1980 then
                    g_storeManager:addPackItem("VY_PACK_1970S", storeItem.xmlFilename)
                elseif year < 1990 then
                    g_storeManager:addPackItem("VY_PACK_1980S", storeItem.xmlFilename)
                elseif year < 2000 then
                    g_storeManager:addPackItem("VY_PACK_1990S", storeItem.xmlFilename)
                elseif year < 2010 then
                    g_storeManager:addPackItem("VY_PACK_2000S", storeItem.xmlFilename)
                elseif year < 2020 then
                    g_storeManager:addPackItem("VY_PACK_2010S", storeItem.xmlFilename)
                elseif year < 2030 then
                    g_storeManager:addPackItem("VY_PACK_2020S", storeItem.xmlFilename)
                end
            end
        end
    end

    -- If this is nil, it won't show up in the spec list
    return storeItem.specs.year
end

function VehicleYears.getYear(storeItem)
    log_dbg("VehicleYears.getYear")
    -- If this is nil, it won't show up in the spec list
    return storeItem.specs.year
end

function VehicleYears:processAttributeData(storeItem, vehicle, saleItem)
    log_dbg("processAttributeData")

    local year = VehicleYears.getYear(storeItem)

    if  year ~= nil then
        local itemElement = self.attributeItem:clone(self.attributesLayout)
        local iconElement = itemElement:getDescendantByName("icon")
        local textElement = itemElement:getDescendantByName("text")
        -- local slice = g_overlayManager:getSliceInfoById("gui.icon_calendar")

        iconElement:applyProfile("shopConfigAttributeIconDate")
        -- iconElement:applyProfile(ShopConfigScreen.GUI_PROFILE.CAPACITY)
        -- iconElement:setImageFilename(slice.filename)
        iconElement:setVisible(true)
        textElement:setText(year)

        self.attributesLayout:invalidateLayout()
    end
end

ShopConfigScreen.processAttributeData = Utils.appendedFunction(
    ShopConfigScreen.processAttributeData, VehicleYears.processAttributeData)

function VehicleYears:onFinishedLoading()
    log_dbg("onFinishedLoading")

    -- Load model year data
    local shopItems = g_storeManager:getItems();
    for _, storeItem in pairs(shopItems) do
        loadYear(storeItem, nil)
    end

    -- Enable to log all vehicles without a year assigned
    -- logVehiclesWithoutYear()
end

local function generateStorePacks()
    log_dbg("generateStorePacks")

    -- Create packs for each decade. This has to be done before StoreManager:loadMapData.
    -- Since done before that, no vehicles has been loaded and we cannot check if any
    -- vehicles actually is going to be added to any of the packs
    g_storeManager:addModStorePack(
        "VY_PACK_PRE_1950", "< 1950", "icons/pack_pre_1950.dds", g_currentModDirectory)
    g_storeManager:addModStorePack(
        "VY_PACK_1950S", "1950s", "icons/pack_1950s.dds", g_currentModDirectory)
    g_storeManager:addModStorePack(
        "VY_PACK_1960S", "1960s", "icons/pack_1960s.dds", g_currentModDirectory)
    g_storeManager:addModStorePack(
        "VY_PACK_1970S", "1970s", "icons/pack_1970s.dds", g_currentModDirectory)
    g_storeManager:addModStorePack(
        "VY_PACK_1980S", "1980s", "icons/pack_1980s.dds", g_currentModDirectory)
    g_storeManager:addModStorePack(
        "VY_PACK_1990S", "1990s", "icons/pack_1990s.dds", g_currentModDirectory)
    g_storeManager:addModStorePack(
        "VY_PACK_2000S", "2000s", "icons/pack_2000s.dds", g_currentModDirectory)
    g_storeManager:addModStorePack(
        "VY_PACK_2010S", "2010s", "icons/pack_2010s.dds", g_currentModDirectory)
    g_storeManager:addModStorePack(
        "VY_PACK_2020S", "2020s", "icons/pack_2020s.dds", g_currentModDirectory)
end

-- We have to wait until the map has finished before we can initialize populate the packs
FSBaseMission.onFinishedLoading = Utils.appendedFunction(
    FSBaseMission.onFinishedLoading, VehicleYears.onFinishedLoading)

-- Do initialization if not already done - Ensured to only run once
if VehicleYears.modActivated == nil then
    g_gui:loadProfiles(g_currentModDirectory .. "guiProfiles.xml")

    -- Adding year as a spec allows us to show the value when browsing vehicles
    g_storeManager:addSpecType("year", "shopListAttributeIconDate", nil, loadYear,
        StoreSpecies.VEHICLE)

    -- Adding year as a spec allows us to show the value when browsing vehicles
    g_storeManager:addSpecType("handtool_year", "shopListAttributeIconDate", nil, loadYear,
        StoreSpecies.HANDTOOL)

    VehicleYears.modActivated = true
    VehicleYears.debugEnabled = false
    VehicleYears.verboseDebugEnabled = false
    generateStorePacks()
    log_dbg("initialized")
end
