local Classes = MyCollection.Internals.Classes
local Constants = MyCollection.Internals.Constants
local Dependencies = MyCollection.Internals.Dependencies
local Extensions = MyCollection.Internals.Functions.Extensions

Classes.Item = {}
Classes.Item.__index = Classes.Item

local Item = Classes.Item

-- Constructor
function Item.New(characterId, bagId, slotId, setId, equipType, traitType, armorType, weaponType, link)
    local instance = {}
    setmetatable(instance, Item)

    instance:Initialize(characterId, bagId, slotId, setId, equipType, traitType, armorType, weaponType, link)

    if Extensions.Constants.IsEquipment(instance.equipType) then
        return instance
    else
        return nil
    end
end

-- Properties
Item.equipType = nil
Item.armorType = nil
Item.weaponType = nil
Item.traitType = nil
Item.setId = nil
Item.bagId = nil
Item.slotId = nil
Item.characterId = nil
Item.link = nil

-- Functions
function Item:Equals(setId, equipType, traitType, armorType, weaponType)
    if
        setId == self.setId and
        equipType == self.equipType and
        (traitType == nil or traitType == 0 or traitType == self.traitType) and
        (armorType == nil or armorType == 0 or armorType == self.armorType) and
        (weaponType == nil or weaponType == 0 or weaponType == self.weaponType)
    then
        return true
    end

    return false
end

function Item:GetLink()
    return self.link
end

function Item:GetId()
    if self.characterId == nil then
        return "account_".. tostring(self.bagId) .. "_".. tostring(self.slotId)
    else
        return tostring(self.characterId) .. "_" .. tostring(self.bagId) .. "_".. tostring(self.slotId)
    end
end

function Item:Initialize(characterId, bagId, slotId, setId, equipType, traitType, armorType, weaponType, link)
    self.bagId = bagId
    self.slotId = slotId
    self.characterId = characterId

    if link == nil then
        self.link = Dependencies.Officials.GetItemLink(self.bagId, self.slotId)
    else
        self.link = link
    end

    if setId == nil then
        _, _, self.setId, _, _, _ = Dependencies.LibSets.IsSetByItemLink(self.link)
    else
        self.setId = setId
    end

    if equipType == nil then
        _, _, _, _, _, self.equipType, _, _ = Dependencies.Officials.GetItemInfo(self.bagId, self.slotId)
    else
        self.equipType = equipType
    end

    -- Skip further read if not equipment
    if not Extensions.Constants.IsEquipment(self.equipType) then
        return
    end

    if traitType == nil then
        self.traitType = Dependencies.Officials.GetItemTrait(self.bagId, self.slotId)
    else
        self.traitType = traitType
    end

    if Extensions.Constants.IsWeaponOrShield(self.equipType) then
        if weaponType == nil then
            self.weaponType = Dependencies.Officials.GetItemWeaponType(self.bagId, self.slotId)
        else
            self.weaponType = weaponType
        end
        self.equipType = Extensions.Constants.GetEquipTypeOfWeapon(self.weaponType)
    else
        if Extensions.Constants.IsArmor(self.equipType) then
            if armorType == nil then
                self.armorType = Dependencies.Officials.GetItemArmorType(self.bagId, self.slotId)
            else
                self.armorType = armorType
            end
        end
    end
end

-- For saving purpose
function Item:CopyForSave()
    return {
        setId = self.setId,
        equipType = self.equipType,
        traitType = self.traitType,
        armorType = self.armorType,
        weaponType = self.weaponType,
        link = self.link
    }
end