local addonName, addon = ...

local UI = addon.UI
local LT = addon.LootTracker
local LootDB = LT.DB
local Query = LT.Query
local Data = LT.Data
local UpgradeTracks = LT.UpgradeTracks
local Upgrade = LT.Upgrade

local PRIORITY_TEXT = {
    WANTED = "WANTED",
    HIGH = "HIGH",
    BIS = "BIS",
}

local function ClearTooltip()
    GameTooltip:Hide()
end

function UI:CreateTrackedLootRow(
    parent,
    item,
    y
)
    local row =
        CreateFrame(
            "Frame",
            nil,
            parent,
            "BackdropTemplate"
        )

    row:SetSize(
        math.max(760, (parent:GetWidth() or 1060) - 4),
        self:Metric(58, 54, 86)
    )

    row:SetPoint(
        "TOPLEFT",
        parent,
        "TOPLEFT",
        0,
        y
    )

    row:SetBackdrop({
        bgFile =
            "Interface\\Buttons\\WHITE8X8",

        edgeFile =
            "Interface\\Buttons\\WHITE8X8",

        edgeSize = 1,
    })

    row:SetBackdropColor(
        unpack(self.COLORS.card)
    )

    row:SetBackdropBorderColor(
        unpack(
            item.obtained
            and self.COLORS.muted
            or self.COLORS.borderBright
        )
    )

    --------------------------------------------------------
    -- CHECK
    --------------------------------------------------------

    local check =
        CreateFrame(
            "CheckButton",
            nil,
            row,
            "UICheckButtonTemplate"
        )

    check:SetSize(self:Metric(28, 24, 38), self:Metric(28, 24, 38))

    check:SetPoint(
        "LEFT",
        row,
        "LEFT",
        8,
        0
    )

    check:SetChecked(
        item.obtained == true
    )

    check:SetScript(
        "OnClick",
        function(button)
            if item.isVoidCoreVariant then
                LootDB:SetVoidCoreObtained(
                    self.LootCharacterKey, self.LootSpecID, item.itemID, button:GetChecked()
                )
            else
                LootDB:SetObtained(
                    self.LootCharacterKey, self.LootSpecID, item.itemID, button:GetChecked()
                )
            end
            self:RefreshLootTracker()
        end
    )

    --------------------------------------------------------
    -- SLOT COLUMN
    --------------------------------------------------------

    local slotText =
        row:CreateFontString(
            nil,
            "OVERLAY"
        )

    slotText:SetFontObject(
        GameFontNormalSmall
    )

    slotText:SetPoint(
        "LEFT",
        check,
        "RIGHT",
        6,
        0
    )

    slotText:SetWidth(95)
    slotText:SetJustifyH("LEFT")
    slotText:SetWordWrap(false)

    slotText:SetText(
        Data.SLOT_NAMES[
            tonumber(
                item.slotID
            )
            or 14
        ]
        or "OTHER"
    )

    slotText:SetTextColor(
        unpack(self.COLORS.gold)
    )

    --------------------------------------------------------
    -- ITEM ICON
    --------------------------------------------------------

    local itemInfo =
        Query:GetItemInfo(
            item.itemID
        )

    local icon =
        row:CreateTexture(
            nil,
            "ARTWORK"
        )

    icon:SetSize(self:Metric(38, 34, 54), self:Metric(38, 34, 54))

    icon:SetPoint(
        "LEFT",
        slotText,
        "RIGHT",
        4,
        0
    )

    icon:SetTexture(
        itemInfo.icon
    )

    icon:SetTexCoord(
        0.08,
        0.92,
        0.08,
        0.92
    )

    --------------------------------------------------------
    -- ITEM NAME
    --------------------------------------------------------

    local name =
        row:CreateFontString(
            nil,
            "OVERLAY"
        )

    name:SetFontObject(
        GameFontNormal
    )

    name:SetPoint(
        "TOPLEFT",
        icon,
        "TOPRIGHT",
        8,
        -2
    )

    name:SetPoint(
        "RIGHT",
        row,
        "RIGHT",
        -235,
        0
    )

    name:SetHeight(self:Metric(20, 18, 34))
    name:SetJustifyH("LEFT")
    name:SetWordWrap(false)

    name:SetText(
        Query:GetItemDisplayName(
            item.itemID,
            itemInfo.name
        )
    )

    if item.obtained then

        name:SetTextColor(
            unpack(self.COLORS.muted)
        )

    else

        name:SetTextColor(
            unpack(self.COLORS.text)
        )

    end

    --------------------------------------------------------
    -- SECONDARY INFO
    --------------------------------------------------------

    local details =
        row:CreateFontString(
            nil,
            "OVERLAY"
        )

    details:SetFontObject(
        GameFontNormalSmall
    )

    details:SetPoint(
        "BOTTOMLEFT",
        icon,
        "BOTTOMRIGHT",
        8,
        2
    )

    details:SetPoint(
        "RIGHT",
        row,
        "RIGHT",
        -235,
        0
    )

    details:SetHeight(self:Metric(18, 16, 30))
    details:SetJustifyH("LEFT")
    details:SetWordWrap(false)

    local detailsText = ""

    if item.bossName
        and item.bossName ~= ""
    then
        detailsText =
            item.bossName
    end

    if item.trackLabel
        and item.trackLabel ~= ""
    then

        if detailsText ~= "" then
            detailsText =
                detailsText
                .. " | "
        end

        detailsText =
            detailsText
            .. item.trackLabel

    elseif item.itemLevel then

        if detailsText ~= "" then
            detailsText =
                detailsText
                .. " | "
        end

        detailsText =
            detailsText
            .. "ilvl "
            .. tostring(
                item.itemLevel
            )

    end

    details:SetText(
        detailsText
    )

    details:SetTextColor(
        unpack(self.COLORS.muted)
    )

    --------------------------------------------------------
    -- PRIORITY
    --------------------------------------------------------

    local priority =
        CreateFrame(
            "Button",
            nil,
            row,
            "UIPanelButtonTemplate"
        )

    priority:SetSize(
        110,
        26
    )

    priority:SetPoint(
        "RIGHT",
        row,
        "RIGHT",
        -55,
        0
    )

    local priorityLabel = PRIORITY_TEXT[item.priority] or item.priority or "WANTED"
    if item.isVoidCoreVariant then
        priorityLabel = priorityLabel .. (" • " .. UI:T("VOID_CORE", "VOID CORE"))
    elseif item.voidCore then
        priorityLabel = priorityLabel .. " + CORE"
    end
    priority:SetText(priorityLabel)

    priority:SetScript(
        "OnClick",
        function()

            self:OpenLootPriorityMenu(
                priority,
                item.itemID,
                {
                    sourceType =
                        item.sourceType,

                    sourceID =
                        item.sourceID,

                    name =
                        item.sourceName,
                },
                item.bossID
                and {
                    bossID =
                        item.bossID,

                    name =
                        item.bossName,
                }
                or nil,
                item.trackType
                and {
                    type =
                        item.trackType,

                    key =
                        item.trackKey,

                    rank =
                        item.trackRank,

                    entry = {
                        ilvl =
                            item.itemLevel,

                        bonusId =
                            item.trackBonusID,

                        groupLabel =
                            item.trackLabel
                            or "",

                        label =
                            item.itemLevel
                            and tostring(
                                item.itemLevel
                            )
                            or "",
                    },
                }
                or nil
            )

        end
    )

    --------------------------------------------------------
    -- REMOVE
    --------------------------------------------------------

    local remove =
        CreateFrame(
            "Button",
            nil,
            row,
            "UIPanelButtonTemplate"
        )

    remove:SetSize(
        34,
        26
    )

    remove:SetPoint(
        "RIGHT",
        row,
        "RIGHT",
        -10,
        0
    )

    remove:SetText("X")

    remove:SetScript(
        "OnClick",
        function()

            LootDB:UntrackItem(
                self.LootCharacterKey,
                self.LootSpecID,
                item.itemID
            )

            self:RefreshLootTracker()

        end
    )

    --------------------------------------------------------
    -- TOOLTIP
    --------------------------------------------------------

    row:SetScript(
        "OnEnter",
        function()

            -- My Loot has its own TARGET ILVL / TRACK selector.
            -- That selector is authoritative for the tooltip preview in this view,
            -- exactly like the Equipment Test selector is authoritative there.
            -- Never mix the item's saved bonusIDs with a different selected preview.
            local selectedTrack = self:GetSelectedLootTrackData()
            local tooltipLink, tooltipEntry

            if selectedTrack and selectedTrack.entry and Upgrade.BuildPreviewItemLink then
                tooltipEntry = selectedTrack.entry
                tooltipLink = Upgrade:BuildPreviewItemLink(
                    item.itemID,
                    self.LootSpecID,
                    tooltipEntry
                )
            else
                tooltipLink, tooltipEntry =
                    Upgrade:BuildTrackedItemLink(
                        item.itemID,
                        self.LootSpecID,
                        item
                    )
            end

            self:ShowLootItemTooltip(
                row,
                tooltipLink,
                item,
                tooltipEntry
            )

        end
    )

    row:SetScript(
        "OnLeave",
        ClearTooltip
    )

    return row
end

function UI:BuildMyLoot()
    local content =
        self.LootContent

    local obtained, total =
        LootDB:GetProgress(
            self.LootCharacterKey,
            self.LootSpecID
        )

    --------------------------------------------------------
    -- OVERALL PROGRESS
    --------------------------------------------------------

    local progressFrame =
        CreateFrame(
            "Frame",
            nil,
            content,
            "BackdropTemplate"
        )

    progressFrame:SetSize(
        1060,
        54
    )

    progressFrame:SetPoint(
        "TOPLEFT",
        content,
        "TOPLEFT",
        0,
        0
    )

    progressFrame:SetBackdrop({
        bgFile =
            "Interface\\Buttons\\WHITE8X8",
    })

    progressFrame:SetBackdropColor(
        unpack(self.COLORS.panelAlt)
    )

    local progressTitle =
        progressFrame:CreateFontString(
            nil,
            "OVERLAY"
        )

    progressTitle:SetFontObject(
        GameFontNormalLarge
    )

    progressTitle:SetPoint(
        "TOPLEFT",
        progressFrame,
        "TOPLEFT",
        12,
        -8
    )

    progressTitle:SetText(
        string.format(
            "GEAR PROGRESS   %d / %d",
            obtained,
            total
        )
    )

    progressTitle:SetTextColor(
        unpack(self.COLORS.gold)
    )

    local bar =
        CreateFrame(
            "StatusBar",
            nil,
            progressFrame
        )

    bar:SetStatusBarTexture(
        "Interface\\TargetingFrame\\UI-StatusBar"
    )

    bar:SetPoint(
        "BOTTOMLEFT",
        progressFrame,
        "BOTTOMLEFT",
        12,
        8
    )

    bar:SetPoint(
        "BOTTOMRIGHT",
        progressFrame,
        "BOTTOMRIGHT",
        -12,
        8
    )

    bar:SetHeight(9)

    bar:SetMinMaxValues(
        0,
        math.max(
            total,
            1
        )
    )

    bar:SetValue(
        obtained
    )

    local y = -64

    local baseItems = LootDB:GetTrackedItems(self.LootCharacterKey, self.LootSpecID)
    local items = {}
    for _, item in ipairs(baseItems) do
        table.insert(items, item)
        if item.voidCore then
            local coreCopy = {}
            for key, value in pairs(item) do coreCopy[key] = value end
            coreCopy.isVoidCoreVariant = true
            coreCopy.sourceType = "VOID_CORE"
            coreCopy.sourceName = UI:T("VOID_CORE_ROLL", "Void Core Roll")
            coreCopy.obtained = item.voidCoreObtained == true
            coreCopy.obtainedAt = item.voidCoreObtainedAt
            table.insert(items, coreCopy)
        end
    end

    if #items == 0 then

        local empty =
            content:CreateFontString(
                nil,
                "OVERLAY"
            )

        empty:SetFontObject(
            GameFontNormal
        )

        empty:SetPoint(
            "TOPLEFT",
            content,
            "TOPLEFT",
            6,
            y
        )

        empty:SetWidth(1040)
        empty:SetJustifyH("LEFT")

        empty:SetText(
            self:T("NO_TRACKED", "NO TRACKED ITEMS. OPEN LOOT BROWSER AND CHOOSE A PRIORITY.")
        )

        empty:SetTextColor(
            unpack(self.COLORS.muted)
        )

        content:SetHeight(
            120
        )

        return
    end

    --------------------------------------------------------
    -- GROUP:
    -- RAID / KEYS
    --   specific raid / dungeon
    --     SLOT + ITEM
    --------------------------------------------------------

    local sourceTypeOrder = {
        "RAID",
        "KEYS",
        "CRAFTED",
        "VOID_CORE",
        "OTHER",
    }

    local sourceTypeLabels = {
        RAID = "RAID",
        KEYS = "KEYS",
        CRAFTED = "CRAFTED",
        VOID_CORE = UI:T("VOID_CORE_ROLL", "VOID CORE"),
        OTHER = "OTHER",
    }

    local grouped = {
        RAID = {},
        KEYS = {},
        CRAFTED = {},
        OTHER = {},
    }

    for _, item in ipairs(
        items
    ) do

        local sourceType =
            item.sourceType
            or "OTHER"

        if sourceType ~= "RAID"
            and sourceType ~= "KEYS"
            and sourceType ~= "CRAFTED"
        then
            sourceType =
                "OTHER"
        end

        local sourceName =
            item.sourceName

        if not sourceName
            or sourceName == ""
        then

            sourceName =
                sourceType == "RAID"
                and "UNKNOWN RAID"
                or (
                    sourceType == "KEYS"
                    and "UNKNOWN DUNGEON"
                    or (
                        sourceType == "CRAFTED"
                        and "CRAFTING"
                        or "OTHER"
                    )
                )

        end

        grouped[sourceType][sourceName] =
            grouped[sourceType][sourceName]
            or {}

        table.insert(
            grouped[sourceType][sourceName],
            item
        )

    end

    --------------------------------------------------------
    -- SOURCE TYPE HEADER
    --------------------------------------------------------

    local function CountItems(
        sourceGroups
    )
        local done = 0
        local count = 0

        for _, sourceItems in pairs(
            sourceGroups
        ) do

            for _, item in ipairs(
                sourceItems
            ) do

                count =
                    count + 1

                if item.obtained then
                    done =
                        done + 1
                end

            end

        end

        return done, count
    end

    local function CreateSourceTypeHeader(
        sourceType,
        sourceGroups
    )
        local done, count =
            CountItems(
                sourceGroups
            )

        local header =
            CreateFrame(
                "Frame",
                nil,
                content,
                "BackdropTemplate"
            )

        header:SetSize(
            1060,
            38
        )

        header:SetPoint(
            "TOPLEFT",
            content,
            "TOPLEFT",
            0,
            y
        )

        header:SetBackdrop({
            bgFile =
                "Interface\\Buttons\\WHITE8X8",

            edgeFile =
                "Interface\\Buttons\\WHITE8X8",

            edgeSize = 1,
        })

        header:SetBackdropColor(
            0.055,
            0.025,
            0.08,
            0.95
        )

        header:SetBackdropBorderColor(
            unpack(
                self.COLORS.borderBright
            )
        )

        local title =
            header:CreateFontString(
                nil,
                "OVERLAY"
            )

        title:SetFontObject(
            GameFontNormalLarge
        )

        title:SetPoint(
            "LEFT",
            header,
            "LEFT",
            12,
            0
        )

        title:SetText(
            sourceTypeLabels[
                sourceType
            ]
            or sourceType
        )

        title:SetTextColor(
            unpack(self.COLORS.gold)
        )

        local progress =
            header:CreateFontString(
                nil,
                "OVERLAY"
            )

        progress:SetFontObject(
            GameFontNormal
        )

        progress:SetPoint(
            "RIGHT",
            header,
            "RIGHT",
            -12,
            0
        )

        progress:SetText(
            string.format(
                "%d / %d",
                done,
                count
            )
        )

        progress:SetTextColor(
            unpack(self.COLORS.muted)
        )

        y = y - 46
    end

    --------------------------------------------------------
    -- SPECIFIC RAID / DUNGEON HEADER
    --------------------------------------------------------

    local function CreateInstanceHeader(
        sourceName,
        sourceItems
    )
        local done = 0

        for _, item in ipairs(
            sourceItems
        ) do
            if item.obtained then
                done =
                    done + 1
            end
        end

        local header =
            CreateFrame(
                "Frame",
                nil,
                content,
                "BackdropTemplate"
            )

        header:SetSize(
            1060,
            32
        )

        header:SetPoint(
            "TOPLEFT",
            content,
            "TOPLEFT",
            0,
            y
        )

        header:SetBackdrop({
            bgFile =
                "Interface\\Buttons\\WHITE8X8",
        })

        header:SetBackdropColor(
            0.03,
            0.03,
            0.045,
            0.90
        )

        local title =
            header:CreateFontString(
                nil,
                "OVERLAY"
            )

        title:SetFontObject(
            GameFontNormal
        )

        title:SetPoint(
            "LEFT",
            header,
            "LEFT",
            12,
            0
        )

        title:SetPoint(
            "RIGHT",
            header,
            "RIGHT",
            -100,
            0
        )

        title:SetJustifyH(
            "LEFT"
        )

        title:SetWordWrap(
            false
        )

        title:SetText(
            sourceName
        )

        title:SetTextColor(
            unpack(self.COLORS.text)
        )

        local progress =
            header:CreateFontString(
                nil,
                "OVERLAY"
            )

        progress:SetFontObject(
            GameFontNormalSmall
        )

        progress:SetPoint(
            "RIGHT",
            header,
            "RIGHT",
            -12,
            0
        )

        progress:SetText(
            string.format(
                "%d / %d",
                done,
                #sourceItems
            )
        )

        progress:SetTextColor(
            unpack(self.COLORS.muted)
        )

        y = y - 38
    end

    --------------------------------------------------------
    -- SORT ITEMS INSIDE INSTANCE BY SLOT
    --------------------------------------------------------

    local function SortInstanceItems(
        sourceItems
    )
        table.sort(
            sourceItems,
            function(a, b)

                local aSlot =
                    tonumber(
                        a.slotID
                    )
                    or 99

                local bSlot =
                    tonumber(
                        b.slotID
                    )
                    or 99

                if aSlot ~= bSlot then
                    return aSlot < bSlot
                end

                return (
                    tonumber(
                        a.itemID
                    )
                    or 0
                ) < (
                    tonumber(
                        b.itemID
                    )
                    or 0
                )

            end
        )
    end

    --------------------------------------------------------
    -- BUILD
    --------------------------------------------------------

    for _, sourceType in ipairs(
        sourceTypeOrder
    ) do

        local sourceGroups =
            grouped[sourceType]

        local hasItems = false

        for _, sourceItems in pairs(
            sourceGroups
        ) do

            if #sourceItems > 0 then
                hasItems = true
                break
            end

        end

        if hasItems then

            CreateSourceTypeHeader(
                sourceType,
                sourceGroups
            )

            local sourceNames = {}

            for sourceName in pairs(
                sourceGroups
            ) do
                table.insert(
                    sourceNames,
                    sourceName
                )
            end

            table.sort(
                sourceNames,
                function(a, b)
                    return tostring(a)
                        < tostring(b)
                end
            )

            for _, sourceName in ipairs(
                sourceNames
            ) do

                local sourceItems =
                    sourceGroups[
                        sourceName
                    ]

                SortInstanceItems(
                    sourceItems
                )

                CreateInstanceHeader(
                    sourceName,
                    sourceItems
                )

                for _, item in ipairs(
                    sourceItems
                ) do

                    self:CreateTrackedLootRow(
                        content,
                        item,
                        y
                    )

                    y = y - 64

                end

                y = y - 8

            end

            y = y - 12

        end

    end

    content:SetHeight(
        math.max(
            math.abs(y) + 20,
            100
        )
    )
end

