local _, ns = ...
local L = ns.L or {}

local UIData = ns.UIData or {}
local PREMIUM = UIData.PREMIUM or {}
local THEME = UIData.THEME or {}
local STATUS_COLORS = UIData.STATUS_COLORS or {}

local BACKDROP_TEMPLATE = BackdropTemplateMixin and "BackdropTemplate" or nil

local UIJournalView = ns.UIJournalView or {}
local UIButtonWidgets = ns.UIButtonWidgets or {}

local JournalRows = {}
ns.UIJournalRows = JournalRows

local getRaidDifficultyLabel = UIJournalView.GetRaidDifficultyLabel or function()
    return L.UNKNOWN or "Unknown"
end
local buildRaidLootMetaLabel = UIJournalView.BuildRaidLootMetaLabel or function()
    return ""
end
local getRaidLootTrackerVisual = UIJournalView.GetRaidLootTrackerVisual or function()
    return PREMIUM.raidTrackerNone, STATUS_COLORS.missing or { 0.45, 0.42, 0.36 }, L.RAID_LOOT_TRACKER_NONE or "Not tracked"
end
local buildRaidLootTrackerSummary = UIJournalView.BuildRaidLootTrackerSummary or function()
    return nil
end
local addRaidLootTrackerSummaryTooltip = UIJournalView.AddRaidLootTrackerSummaryTooltip or function() end
local addWishlistSourcesTooltip = UIJournalView.AddWishlistSourcesTooltip or function() end
local getRaidLootQualityColor = UIJournalView.GetRaidLootQualityColor or function()
    local fallback = THEME.parchment or { 0.93, 0.89, 0.77 }
    return nil, (ITEM_QUALITY_COLORS and ITEM_QUALITY_COLORS.common) or {
        r = fallback[1],
        g = fallback[2],
        b = fallback[3],
    }
end

local createMiniActionButton = UIButtonWidgets.CreateMiniActionButton or function(parent)
    return CreateFrame("Button", nil, parent, BACKDROP_TEMPLATE)
end
local setMiniActionButtonActive = UIButtonWidgets.SetMiniActionButtonActive or function() end

local function createLabel(parent, fontObject, justify)
    local text = parent:CreateFontString(nil, "OVERLAY", fontObject)
    text:SetJustifyH(justify or "LEFT")
    text:SetJustifyV("MIDDLE")
    return text
end

local function setTextureColor(texture, color, alpha)
    if not texture or type(color) ~= "table" then
        return
    end

    texture:SetVertexColor(color[1], color[2], color[3], alpha == nil and 1 or alpha)
end

local function createInsetIconBorder(parent, anchor, inset, thickness)
    local border = {
        inset = inset or 1,
        thickness = thickness or 1,
    }

    local function createEdge()
        return parent:CreateTexture(nil, "OVERLAY", nil, 2)
    end

    border.top = createEdge()
    border.bottom = createEdge()
    border.left = createEdge()
    border.right = createEdge()

    border.top:SetPoint("TOPLEFT", anchor, "TOPLEFT", border.inset, -border.inset)
    border.top:SetPoint("TOPRIGHT", anchor, "TOPRIGHT", -border.inset, -border.inset)
    border.top:SetHeight(border.thickness)

    border.bottom:SetPoint("BOTTOMLEFT", anchor, "BOTTOMLEFT", border.inset, border.inset)
    border.bottom:SetPoint("BOTTOMRIGHT", anchor, "BOTTOMRIGHT", -border.inset, border.inset)
    border.bottom:SetHeight(border.thickness)

    border.left:SetPoint("TOPLEFT", anchor, "TOPLEFT", border.inset, -border.inset)
    border.left:SetPoint("BOTTOMLEFT", anchor, "BOTTOMLEFT", border.inset, border.inset)
    border.left:SetWidth(border.thickness)

    border.right:SetPoint("TOPRIGHT", anchor, "TOPRIGHT", -border.inset, -border.inset)
    border.right:SetPoint("BOTTOMRIGHT", anchor, "BOTTOMRIGHT", -border.inset, border.inset)
    border.right:SetWidth(border.thickness)

    function border:SetColor(r, g, b, a)
        local alpha = a == nil and 1 or a
        self.top:SetColorTexture(r, g, b, alpha)
        self.bottom:SetColorTexture(r, g, b, alpha)
        self.left:SetColorTexture(r, g, b, alpha)
        self.right:SetColorTexture(r, g, b, alpha)
    end

    return border
end

local function applyRaidLootTrackerButton(button, trackerState)
    if not button then
        return
    end

    local texturePath = getRaidLootTrackerVisual(trackerState)
    button.trackerState = trackerState
    button.label:SetText("")
    if button.glyphIcon then
        button.glyphIcon:SetTexture(texturePath)
        button.glyphIcon:SetVertexColor(1, 1, 1, 1)
        button.glyphIcon:Show()
    end
    setMiniActionButtonActive(button, trackerState ~= nil)
    button:SetAlpha(trackerState and 1 or 0.78)
end

local function createRaidJournalRowButton(parent)
    local button = CreateFrame("Button", nil, parent, BACKDROP_TEMPLATE)
    button:SetHeight(52)

    if button.SetBackdrop then
        button:SetBackdrop({
            bgFile = "Interface\\Buttons\\WHITE8X8",
            edgeFile = "Interface\\Buttons\\WHITE8X8",
            tile = false,
            edgeSize = 1,
            insets = { left = 1, right = 1, top = 1, bottom = 1 },
        })
        button:SetBackdropColor(THEME.metalInset[1], THEME.metalInset[2], THEME.metalInset[3], 0.06)
        button:SetBackdropBorderColor(THEME.goldDim[1], THEME.goldDim[2], THEME.goldDim[3], 0.36)
    end

    button.bg = button:CreateTexture(nil, "BACKGROUND")
    button.bg:SetAllPoints()
    button.bg:SetTexture(PREMIUM.row)
    setTextureColor(button.bg, { 1, 1, 1 }, 0.88)

    button.fill = button:CreateTexture(nil, "BACKGROUND", nil, 1)
    button.fill:SetAllPoints()
    button.fill:SetTexture("Interface\\Buttons\\WHITE8X8")
    button.fill:SetColorTexture(THEME.metalInset[1], THEME.metalInset[2], THEME.metalInset[3], 0.03)

    button.statusLine = button:CreateTexture(nil, "ARTWORK")
    button.statusLine:SetPoint("TOPLEFT", 4, -5)
    button.statusLine:SetPoint("BOTTOMLEFT", 4, 5)
    button.statusLine:SetWidth(2)
    button.statusLine:SetColorTexture(THEME.goldDim[1], THEME.goldDim[2], THEME.goldDim[3], 1)

    button.iconBackplate = button:CreateTexture(nil, "ARTWORK")
    button.iconBackplate:SetSize(36, 36)
    button.iconBackplate:SetPoint("LEFT", 12, 0)
    button.iconBackplate:SetTexture(PREMIUM.classBackplate)

    button.icon = button:CreateTexture(nil, "OVERLAY")
    button.icon:SetSize(30, 30)
    button.icon:SetPoint("CENTER", button.iconBackplate, "CENTER", 0, 0)
    button.icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
    button.icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
    if button.icon.AddMaskTexture then
        button.iconMask = button:CreateMaskTexture()
        button.iconMask:SetTexture("Interface\\CHARACTERFRAME\\TempPortraitAlphaMask", "CLAMPTOBLACKADDITIVE", "CLAMPTOBLACKADDITIVE")
        button.iconMask:SetAllPoints(button.icon)
        button.icon:AddMaskTexture(button.iconMask)
    end

    button.iconRing = button:CreateTexture(nil, "OVERLAY", nil, 1)
    button.iconRing:SetSize(36, 36)
    button.iconRing:SetPoint("CENTER", button.iconBackplate, "CENTER", 0, 0)
    button.iconRing:SetTexture(PREMIUM.classRing)

    button.squareIconFrame = CreateFrame("Frame", nil, button, BACKDROP_TEMPLATE)
    button.squareIconFrame:SetSize(34, 34)
    button.squareIconFrame:SetPoint("CENTER", button.iconBackplate, "CENTER", 0, 0)
    button.squareIconFrame:Hide()
    if button.squareIconFrame.SetBackdrop then
        button.squareIconFrame:SetBackdrop({
            bgFile = "Interface\\Buttons\\WHITE8X8",
            edgeFile = "Interface\\Buttons\\WHITE8X8",
            tile = false,
            edgeSize = 1,
            insets = { left = 1, right = 1, top = 1, bottom = 1 },
        })
        button.squareIconFrame:SetBackdropColor(THEME.shadow[1], THEME.shadow[2], THEME.shadow[3], 0.18)
        button.squareIconFrame:SetBackdropBorderColor(THEME.gold[1], THEME.gold[2], THEME.gold[3], 0.74)
    end

    button.squareIcon = button.squareIconFrame:CreateTexture(nil, "OVERLAY")
    button.squareIcon:SetAllPoints()
    button.squareIcon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
    button.squareIcon:SetTexCoord(0.30, 0.70, 0.30, 0.70)

    button.title = createLabel(button, "GameFontNormal", "LEFT")
    button.title:SetPoint("TOPLEFT", button.iconBackplate, "TOPRIGHT", 10, -6)
    button.title:SetPoint("TOPRIGHT", -74, -10)

    button.meta = createLabel(button, "GameFontHighlightSmall", "LEFT")
    button.meta:SetPoint("TOPLEFT", button.title, "BOTTOMLEFT", 0, -6)
    button.meta:SetPoint("TOPRIGHT", -14, 0)
    if button.meta.SetWordWrap then
        button.meta:SetWordWrap(false)
    end

    button.status = createLabel(button, "GameFontNormalSmall", "RIGHT")
    button.status:SetPoint("TOPRIGHT", -12, -10)
    button.status:SetTextColor(THEME.gold[1], THEME.gold[2], THEME.gold[3])

    button.trackBadge = button:CreateTexture(nil, "OVERLAY")
    button.trackBadge:SetPoint("RIGHT", button.status, "LEFT", -8, 0)
    button.trackBadge:SetSize(14, 14)
    button.trackBadge:Hide()

    button.selection = button:CreateTexture(nil, "HIGHLIGHT")
    button.selection:SetPoint("TOPLEFT", 3, -3)
    button.selection:SetPoint("BOTTOMRIGHT", -3, 3)
    button.selection:SetTexture("Interface\\Buttons\\WHITE8X8")
    button.selection:SetColorTexture(THEME.gold[1], THEME.gold[2], THEME.gold[3], 0.10)
    button.selection:Hide()

    button:SetScript("OnEnter", function(self)
        if self.trackerSummary then
            GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
            GameTooltip:AddLine(L.RAID_LOOT_TRACKER_BADGE or "Tracked loot", THEME.gold[1], THEME.gold[2], THEME.gold[3], true)
            if (self.trackerSummary.wishCount or 0) > 0 then
                GameTooltip:AddLine(
                    string.format(L.RAID_LOOT_TRACKER_WISH_COUNT or "Wishlisted: %d", self.trackerSummary.wishCount),
                    THEME.gold[1],
                    THEME.gold[2],
                    THEME.gold[3],
                    true
                )
            end
            if (self.trackerSummary.obtainedCount or 0) > 0 then
                GameTooltip:AddLine(
                    string.format(L.RAID_LOOT_TRACKER_OBTAINED_COUNT or "Obtained: %d", self.trackerSummary.obtainedCount),
                    STATUS_COLORS.complete[1],
                    STATUS_COLORS.complete[2],
                    STATUS_COLORS.complete[3],
                    true
                )
            end
            GameTooltip:Show()
        end
    end)
    button:SetScript("OnLeave", function()
        GameTooltip:Hide()
    end)

    return button
end

local function createRaidJournalLootRow(parent)
    local row = CreateFrame("Frame", nil, parent, BACKDROP_TEMPLATE)
    row:SetHeight(60)
    row:EnableMouse(true)

    if row.SetBackdrop then
        row:SetBackdrop({
            bgFile = "Interface\\Buttons\\WHITE8X8",
            edgeFile = "Interface\\Buttons\\WHITE8X8",
            tile = false,
            edgeSize = 1,
            insets = { left = 1, right = 1, top = 1, bottom = 1 },
        })
        row:SetBackdropColor(THEME.metalInset[1], THEME.metalInset[2], THEME.metalInset[3], 0.04)
        row:SetBackdropBorderColor(THEME.goldDim[1], THEME.goldDim[2], THEME.goldDim[3], 0.30)
    end

    row.bg = row:CreateTexture(nil, "BACKGROUND")
    row.bg:SetAllPoints()
    row.bg:SetTexture(PREMIUM.row)
    row.bg:SetTexCoord(0.03, 0.97, 0, 1)
    setTextureColor(row.bg, { 1, 1, 1 }, 0.56)

    row.hover = row:CreateTexture(nil, "ARTWORK")
    row.hover:SetPoint("TOPLEFT", 3, -3)
    row.hover:SetPoint("BOTTOMRIGHT", -3, 3)
    row.hover:SetTexture("Interface\\Buttons\\WHITE8X8")
    row.hover:SetColorTexture(THEME.gold[1], THEME.gold[2], THEME.gold[3], 0.08)
    row.hover:Hide()

    row.icon = row:CreateTexture(nil, "ARTWORK")
    row.icon:SetPoint("LEFT", 8, 0)
    row.icon:SetSize(32, 32)
    row.icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
    row.icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
    row.iconBorder = createInsetIconBorder(row, row.icon, 0, 1)

    row.trackButton = createMiniActionButton(row, "+", 22)
    row.trackButton:SetPoint("RIGHT", -8, 0)
    row.trackButton:SetScript("OnClick", function(selfButton)
        if selfButton.itemID and selfButton.characterKey and ns.CycleRaidLootTrackerState then
            ns:CycleRaidLootTrackerState(selfButton.characterKey, selfButton.difficultyKey, selfButton.itemID)
        end
    end)
    row.trackButton:SetScript("OnEnter", function(selfButton)
        if selfButton.SetBackdropBorderColor then
            selfButton:SetBackdropBorderColor(THEME.gold[1], THEME.gold[2], THEME.gold[3], 0.92)
        end
        selfButton.hover:SetAlpha(1)
        local _, color, stateLabel = getRaidLootTrackerVisual(selfButton.trackerState)
        GameTooltip:SetOwner(selfButton, "ANCHOR_CURSOR_RIGHT")
        GameTooltip:AddLine(stateLabel or (L.RAID_LOOT_TRACKER_NONE or "Not tracked"), color[1], color[2], color[3], true)
        GameTooltip:AddLine(
            string.format(
                L.RAID_LOOT_TRACKER_CONTEXT or "For %s on %s",
                selfButton.characterName or (L.UNKNOWN or "Unknown"),
                getRaidDifficultyLabel(selfButton.difficultyKey or "normal")
            ),
            0.86,
            0.86,
            0.82,
            true
        )
        GameTooltip:AddLine(L.RAID_LOOT_TRACKER_CLICK or "Left click: cycle status", 0.72, 0.78, 0.88, true)
        GameTooltip:Show()
    end)
    row.trackButton:SetScript("OnLeave", function(selfButton)
        if selfButton.SetBackdropBorderColor then
            if selfButton.vlActive then
                selfButton:SetBackdropBorderColor(THEME.gold[1], THEME.gold[2], THEME.gold[3], 0.88)
            else
                selfButton:SetBackdropBorderColor(THEME.goldDim[1], THEME.goldDim[2], THEME.goldDim[3], 0.70)
            end
        end
        selfButton.hover:SetAlpha(selfButton.vlActive and 0.55 or 0)
        GameTooltip:Hide()
    end)

    row.name = createLabel(row, "GameFontHighlightSmall", "LEFT")
    row.name:SetPoint("TOPLEFT", 48, -6)
    row.name:SetPoint("TOPRIGHT", row.trackButton, "TOPLEFT", -8, -6)
    if row.name.SetWordWrap then
        row.name:SetWordWrap(true)
    end
    if row.name.SetMaxLines then
        row.name:SetMaxLines(2)
    end

    row.meta = createLabel(row, "GameFontNormalSmall", "LEFT")
    row.meta:SetPoint("TOPLEFT", row.name, "BOTTOMLEFT", 0, -3)
    row.meta:SetPoint("TOPRIGHT", row.trackButton, "TOPLEFT", -8, 0)
    if row.meta.SetWordWrap then
        row.meta:SetWordWrap(false)
    end

    row:SetScript("OnEnter", function(self)
        self.hover:Show()
        GameTooltip:SetOwner(self, "ANCHOR_CURSOR_RIGHT")
        if self.itemLink and self.itemLink ~= "" then
            GameTooltip:SetHyperlink(self.itemLink)
        elseif self.itemID and GameTooltip.SetItemByID then
            GameTooltip:SetItemByID(self.itemID)
        else
            GameTooltip:AddLine(L.RAID_JOURNAL_TOOLTIP_NO_ITEM or "No item tooltip available yet.", 0.9, 0.9, 0.9, true)
        end
        if self.trackSummary then
            addRaidLootTrackerSummaryTooltip(self.trackSummary)
        end
        if self.wishlistSources then
            addWishlistSourcesTooltip(self.wishlistSources)
        end
        GameTooltip:Show()
        if self.itemID and C_Item and C_Item.RequestLoadItemDataByID and not self.itemLink then
            pcall(C_Item.RequestLoadItemDataByID, self.itemID)
        end
    end)
    row:SetScript("OnLeave", function(self)
        self.hover:Hide()
        GameTooltip:Hide()
    end)

    return row
end

function JournalRows.ApplyLootRow(row, loot)
    local icon = loot and loot.icon
    if (not icon) and loot and loot.itemID and C_Item and C_Item.GetItemIconByID then
        icon = C_Item.GetItemIconByID(loot.itemID)
    end
    row.icon:SetTexture(icon or "Interface\\Icons\\INV_Misc_QuestionMark")
    row.name:SetText((loot and loot.name) or (L.UNKNOWN or "Unknown"))
    row.itemID = loot and loot.itemID or nil
    row.itemLink = loot and loot.link or nil

    local _, qualityColor = getRaidLootQualityColor(loot)
    local nameColor = qualityColor
    if nameColor then
        row.name:SetTextColor(nameColor.r, nameColor.g, nameColor.b)
    else
        row.name:SetTextColor(THEME.parchment[1], THEME.parchment[2], THEME.parchment[3])
    end

    if row.iconBorder and row.iconBorder.SetColor then
        if qualityColor then
            row.iconBorder:SetColor(qualityColor.r, qualityColor.g, qualityColor.b, 0.96)
        else
            row.iconBorder:SetColor(THEME.goldDim[1], THEME.goldDim[2], THEME.goldDim[3], 0.76)
        end
    end

    local metaParts = {}
    local metaLabel = buildRaidLootMetaLabel(loot)
    if metaLabel and metaLabel ~= "" then
        metaParts[#metaParts + 1] = metaLabel
    end
    if loot and loot.isVeryRare then
        metaParts[#metaParts + 1] = EJ_ITEM_CATEGORY_VERY_RARE or "Very rare"
    elseif loot and loot.isExtremelyRare then
        metaParts[#metaParts + 1] = EJ_ITEM_CATEGORY_EXTREMELY_RARE or "Extremely rare"
    end
    row.meta:SetText(table.concat(metaParts, "  |  "))

    local trackerState = (row.characterKey and row.itemID and ns.GetRaidLootTrackerState)
        and ns:GetRaidLootTrackerState(row.characterKey, row.difficultyKey, row.itemID)
        or nil
    row.trackSummary = buildRaidLootTrackerSummary(row.characterKey, row.difficultyKey, { loot })
    row.trackButton.itemID = row.itemID
    row.trackButton.characterKey = row.characterKey
    row.trackButton.characterName = row.characterName
    row.trackButton.difficultyKey = row.difficultyKey
    applyRaidLootTrackerButton(row.trackButton, trackerState)
    row.trackButton:SetShown(row.itemID ~= nil)
end

JournalRows.CreateRowButton = createRaidJournalRowButton
JournalRows.CreateLootRow = createRaidJournalLootRow
