-- Chat History

StefansLootTracker.loadedChatStartIndex = 1
StefansLootTracker.loadedChatEndIndex = StefansLootTracker.itemsChatPerLoad or 30
StefansLootTracker.itemsChatPerLoad = 30

StefansLootTracker.frameChatPool = {}
StefansLootTracker.visibleChatFrames = {}
StefansLootTracker.frameChatHeight = 15

function StefansLootTracker:HandleChatMessage(chatMessage)
    -- Debug: Log the received chat message
    if self.db.profile.qDebug then
        print("Debug: Received chat string: " .. chatMessage)
    end

    -- Parse the chat message
    local rarity = self:getRarity(chatMessage)

    -- Debug: Log the parsed details
    if self.db.profile.qDebug then
        print("Debug: Parsed rarity: " .. (rarity or "Unknown"))
    end

    -- Check if the item meets the rarity filter
    if rarity < self.db.profile.rarityFilter then
        if self.db.profile.qDebug then 
            self:Print("CHAT DOESN'T MEET RARITY FILTER")
        end
        return
    end

    -- Get the current timestamp
    local timestamp = date("%Y-%m-%d %H:%M:%S")

    -- Update the data structure
    if not self.db.profile.chathist then
        self.db.profile.chathist = {}
    end

    -- Insert a new chat event with its timestamp and modified message
    table.insert(self.db.profile.chathist, {
        message = chatMessage,
        timestamp = timestamp
    })

    -- Update the window only if it's open
    self:UpdateChatHistoryIfOpen()
end

function StefansLootTracker:HandleChatRollMessage(chatrollMessage)
    -- Debug: Log the received chat roll message
    if self.db.profile.qDebug then
        print("Debug: Received roll string: " .. chatrollMessage)
    end

    local rollmatch = chatrollMessage:match("(.+) rolls .*")
    if not rollmatch then
        if self.db.profile.qDebug then 
            self:Print("CHAT DOESN'T MATCH ROLL PATTERN")
        end
        return
    end

    -- Get the current timestamp
    local timestamp = date("%Y-%m-%d %H:%M:%S")

    -- Insert a new chatroll event with its timestamp and message
    table.insert(self.db.profile.chathist, {
        message = chatrollMessage,
        timestamp = timestamp
    })

    -- Update the window only if it's open
    self:UpdateChatHistoryIfOpen()
end

function StefansLootTracker:ClearChatHistory()
    self.db.profile.chathist = {} -- Chat History Database
    self:Print("Chat History has been cleared.")
    if self.chatHistoryFrame and self.chatHistoryFrame:IsShown() then
        self:UpdateChatHistoryWindow()  -- Update the chat history window if it's open
    end
end

local searchChatDebounceTimer
function StefansLootTracker:ChatDebouncedSearch(searchChatTerm)
    if searchChatDebounceTimer then
        searchChatDebounceTimer:Cancel()
    end
    searchChatDebounceTimer = C_Timer.After(0.5, function()
        self:UpdateChatHistoryWindow(searchChatTerm)
    end)
end

local loadChatMoreTimer
function StefansLootTracker:DebouncedChatLoadMoreResults()
    if loadChatMoreTimer then
        loadChatMoreTimer:Cancel()
    end
    loadChatMoreTimer = C_Timer.NewTimer(0.2, function()
        self:ChatLoadMoreResults()
    end)
end

function StefansLootTracker:CreateChatHistoryWindow()
    -- Check if the frame already exists to avoid creating duplicates
    if self.chatHistoryFrame then
        self.chatHistoryFrame:Show()
        return
    end

    local f = CreateFrame("Frame", "StefansLootTrackerChatHistoryFrame", UIParent, "BackdropTemplate")
    local pos = self.db.profile.chatHistorywindowPosition
    local size = self.db.profile.chatHistorywindowSize
    f:SetSize(size.width, size.height)
    f:SetPoint(pos.point, UIParent, pos.relativePoint, pos.x, pos.y)
    f:SetMovable(true)
    f:SetResizable(true)
    f:SetResizeBounds(300, 200) -- Set minimum size
    f:EnableMouse(true)
    f:RegisterForDrag("LeftButton")
    f:SetScript("OnDragStart", f.StartMoving)
    f:SetScript("OnDragStop", f.StopMovingOrSizing)
    f:SetHyperlinksEnabled(true)
    f:SetScript("OnHyperlinkClick", ChatFrame_OnHyperlinkShow)
    f:Hide()

    f:SetBackdrop({
        bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
        edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
        tile = true,
        tileSize = 32,
        edgeSize = 32,
        insets = { left = 8, right = 8, top = 8, bottom = 8 }
    })

    -- Create the title frame
    local titleFrame = CreateFrame("Frame", nil, f)
    titleFrame:SetSize(f:GetWidth(), 30)
    titleFrame:SetPoint("TOP", f, "TOP", 0, 10)

    local titleText = titleFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
    titleText:SetPoint("CENTER", titleFrame, "CENTER")
    titleText:SetText("Chat History")

    -- Create the close button
    local closeButton = CreateFrame("Button", nil, f, "UIPanelCloseButton")
    closeButton:SetPoint("TOPRIGHT", f, "TOPRIGHT", -5, -5)
    closeButton:SetScript("OnClick", function()
        f:Hide()
        StefansLootTracker.isChatHistoryWindowOpen = false
        StefansLootTracker:ResetChatLazyLoading()
    end)

    -- Create the refresh button
    local refreshButton = self:CreateRefreshButton(f)
    refreshButton:SetScript("OnClick", function()
        self:UpdateChatHistoryWindow()
    end)

    -- Create search box
    local searchBox = CreateFrame("EditBox", nil, f, "InputBoxTemplate")
    searchBox:SetPoint("TOPLEFT", f, "TOPLEFT", 15, -50)
    searchBox:SetPoint("RIGHT", f, "RIGHT", -15, 0)
    searchBox:SetHeight(20)
    searchBox:SetFontObject("GameFontNormal")
    searchBox:SetAutoFocus(false)
    searchBox:SetScript("OnEscapePressed", function(self) self:ClearFocus() end)
    searchBox:SetTextInsets(22, 10, 2, 2)

    local bg = searchBox:CreateTexture(nil, "BACKGROUND")
    bg:SetAllPoints()
    bg:SetColorTexture(0, 0, 0, 0.1)

    local searchIcon = f:CreateTexture(nil, "ARTWORK")
    searchIcon:SetTexture("Interface\\Common\\UI-Searchbox-Icon")
    searchIcon:SetSize(14, 14)
    searchIcon:SetPoint("LEFT", searchBox, "LEFT", 6, 0)

    searchBox.placeholderText = searchBox:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
    searchBox.placeholderText:SetPoint("LEFT", searchIcon, "RIGHT", 10, 0)
    searchBox.placeholderText:SetText("Search")
    searchBox.placeholderText:SetTextColor(0.6, 0.6, 0.6)

    searchBox:SetScript("OnTextChanged", function(self)
        local text = self:GetText()
        if text == "" then
            self.placeholderText:Show()
        else
            self.placeholderText:Hide()
        end
        StefansLootTracker:ChatDebouncedSearch(text)
    end)

    searchBox:SetScript("OnEditFocusGained", function(self)
        self.placeholderText:Hide()
    end)

    searchBox:SetScript("OnEditFocusLost", function(self)
        if self:GetText() == "" then
            self.placeholderText:Show()
        end
    end)

    f.searchBox = searchBox

    -- Create the scroll frame
    local scrollFrame = CreateFrame("ScrollFrame", nil, f, "UIPanelScrollFrameTemplate")
    scrollFrame:SetPoint("TOPLEFT", f, "TOPLEFT", 10, -80)
    scrollFrame:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -30, 10)
    scrollFrame:SetScript("OnVerticalScroll", function(self, offset)
        self.ScrollBar:SetValue(offset)
        StefansLootTracker:UpdateChatHistoryDisplay()
    end)

    local scrollChild = CreateFrame("Frame", nil, scrollFrame)
    scrollChild:SetWidth(scrollFrame:GetWidth() - 16)  -- Subtract scrollbar width
    scrollFrame:SetScrollChild(scrollChild)
    f.scrollFrame = scrollFrame
    f.scrollChild = scrollChild

    f.noResultsText = f:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
    f.noResultsText:SetPoint("CENTER", f.scrollChild, "CENTER")
    f.noResultsText:SetText("No results found")
    f.noResultsText:Hide()

    f.UpdateNoResults = function(self, noResults)
        if noResults then
            self.noResultsText:Show()
        else
            self.noResultsText:Hide()
        end
    end

    -- Create resize handle
    local resizeHandle = CreateFrame("Button", nil, f)
    resizeHandle:SetPoint("BOTTOMRIGHT")
    resizeHandle:SetSize(16, 16)
    resizeHandle:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Up")
    resizeHandle:SetHighlightTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Highlight")
    resizeHandle:SetPushedTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Down")
    
    resizeHandle:SetScript("OnMouseDown", function(self, button)
        f:StartSizing("BOTTOMRIGHT")
    end)
    
    resizeHandle:SetScript("OnMouseUp", function(self, button)
        f:StopMovingOrSizing()
        StefansLootTracker:UpdateChatHistoryLayout()
        -- Save the new size
        StefansLootTracker.db.profile.chatHistorywindowSize = { width = f:GetWidth(), height = f:GetHeight() }
    end)

    self.chatHistoryFrame = f

    self.frameChatPool = {}
    self.visibleChatFrames = {}

    self:UpdateChatHistoryWindow()
end

function StefansLootTracker:UpdateChatHistoryLayout()
    local f = self.chatHistoryFrame
    if not f then return end

    -- Update search box width
    f.searchBox:SetWidth(f:GetWidth() - 30)

    -- Update scroll frame size
    f.scrollFrame:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -30, 10)

    -- Update scroll child width
    f.scrollChild:SetWidth(f.scrollFrame:GetWidth() - 16)  -- Subtract scrollbar width

    -- Update visible frames width
    for _, frame in ipairs(self.visibleChatFrames) do
        frame:SetWidth(f.scrollChild:GetWidth() - 10)
        frame.messageButton:SetPoint("RIGHT", frame, "RIGHT", 0, 0)
    end

    -- Update the display
    self:UpdateChatHistoryDisplay()
end

function StefansLootTracker:UpdateChatHistoryWindow(searchChatTerm)
    local frame = self.chatHistoryFrame
    if not frame then return end

    searchChatTerm = searchChatTerm or ""

    if searchChatTerm ~= self.lastsearchChatTerm then
        self:ResetChatLazyLoading()
        self.lastsearchChatTerm = searchChatTerm
    end

    -- Initialize FilteredChatIndices
    self.FilteredChatIndices = {}
    for i = #self.db.profile.chathist, 1, -1 do
        local entry = self.db.profile.chathist[i]
        if searchChatTerm == "" or entry.message:lower():find(searchChatTerm:lower(), 1, true) then
            table.insert(self.FilteredChatIndices, i)
        end
    end

    local totalFilteredChatItems = #self.FilteredChatIndices
    local displayedHeight = totalFilteredChatItems * self.frameChatHeight
    frame.scrollChild:SetHeight(displayedHeight)

    self:UpdateChatHistoryLayout()
    self:UpdateChatHistoryDisplay()

    frame:UpdateNoResults(totalFilteredChatItems == 0)
end

function StefansLootTracker:UpdateChatHistoryDisplay()
    local frame = self.chatHistoryFrame
    local scrollFrame = frame.scrollFrame
    local scrollOffset = scrollFrame:GetVerticalScroll()
    local visibleHeight = scrollFrame:GetHeight()
    
    if not self.FilteredChatIndices then
        self:UpdateChatHistoryWindow()
    end

    local totalItems = #self.FilteredChatIndices
    local itemsPerPage = math.floor(visibleHeight / self.frameChatHeight)
    
    local startIndex = math.floor(scrollOffset / self.frameChatHeight) + 1
    local endIndex = math.min(startIndex + itemsPerPage - 1, totalItems)

    for i = 1, itemsPerPage do
        local dataIndex = startIndex + i - 1
        local entryFrame = self.visibleChatFrames[i] or self:CreateChatEntryFrame(frame.scrollChild)
        
        if dataIndex <= totalItems then
            local entry = self.db.profile.chathist[self.FilteredChatIndices[dataIndex]]
            
            entryFrame:SetPoint("TOPLEFT", frame.scrollChild, "TOPLEFT", 5, -((dataIndex-1) * self.frameChatHeight))
            entryFrame:SetPoint("RIGHT", frame.scrollChild, "RIGHT", -5, 0)
            entryFrame:SetHeight(self.frameChatHeight)

            entryFrame.timestampText:SetText(string.format("[%s]", entry.timestamp))
            entryFrame.messageButton.text:SetText(entry.message)

            entryFrame:Show()
            self.visibleChatFrames[i] = entryFrame
        else
            entryFrame:Hide()
        end
    end

    -- Hide any extra frames
    for i = itemsPerPage + 1, #self.visibleChatFrames do
        self.visibleChatFrames[i]:Hide()
    end

    -- Update scroll child height
    local newHeight = totalItems * self.frameChatHeight
    if frame.scrollChild:GetHeight() ~= newHeight then
        frame.scrollChild:SetHeight(newHeight)
        scrollFrame.ScrollBar:SetMinMaxValues(0, max(newHeight - scrollFrame:GetHeight(), 0))
    end
end

function StefansLootTracker:CreateChatEntryFrame(parent)
    local frame = CreateFrame("Frame", nil, parent)
    frame:SetSize(parent:GetWidth() - 10, self.frameChatHeight)

    frame.timestampText = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    frame.timestampText:SetPoint("LEFT", frame, "LEFT", 0, 0)

    -- Create a Button instead of a FontString for the message
    frame.messageButton = CreateFrame("Button", nil, frame)
    frame.messageButton:SetPoint("LEFT", frame.timestampText, "RIGHT", 5, 0)
    frame.messageButton:SetPoint("RIGHT", frame, "RIGHT", 0, 0)
    frame.messageButton:SetHeight(self.frameChatHeight)
    
    frame.messageButton.text = frame.messageButton:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    frame.messageButton.text:SetAllPoints()
    frame.messageButton.text:SetJustifyH("LEFT")

    -- Enable hyperlinks on the button
    frame.messageButton:SetHyperlinksEnabled(true)
    frame.messageButton:SetScript("OnHyperlinkClick", ChatFrame_OnHyperlinkShow)
    frame.messageButton:SetScript("OnHyperlinkEnter", function(self, link, text)
        GameTooltip:SetOwner(self, "ANCHOR_CURSOR")
        GameTooltip:SetHyperlink(link)
        GameTooltip:Show()
    end)
    frame.messageButton:SetScript("OnHyperlinkLeave", function(self)
        GameTooltip:Hide()
    end)

    return frame
end

function StefansLootTracker:ToggleChatHistoryWindow()
    if not self.chatHistoryFrame then
        self:CreateChatHistoryWindow()
    end

    if self.isChatHistoryWindowOpen then
        self.chatHistoryFrame:Hide()
        self.isChatHistoryWindowOpen = false
        self:ResetChatLazyLoading()
    else
        -- Reset the lazy loading and search box
        if self.chatHistoryFrame.searchBox then
            self.chatHistoryFrame.searchBox:SetText("")
            self.chatHistoryFrame.searchBox.placeholderText:Show()
        end

        self:ResetChatLazyLoading()

        -- Update the layout and window, then show it
        self:UpdateChatHistoryLayout()
        self:UpdateChatHistoryWindow()
        self.chatHistoryFrame:Show()
        self.isChatHistoryWindowOpen = true

        -- Ensure the scroll is at the top
        C_Timer.After(0, function()
            self.chatHistoryFrame.scrollFrame:SetVerticalScroll(0)
            self:UpdateChatHistoryDisplay()
        end)
    end
end

function StefansLootTracker:UpdateChatHistoryIfOpen()
    if self.isChatHistoryWindowOpen then
        self:UpdateChatHistoryWindow()
    end
end

function StefansLootTracker:ChatOnScroll()
    local frame = self.chatHistoryFrame
    local scrollFrame = frame.scrollFrame
    local scrollOffset = scrollFrame:GetVerticalScroll()
    local scrollHeight = scrollFrame:GetHeight()
    local childHeight = frame.scrollChild:GetHeight()

    -- Check if we're near the bottom of the scroll frame
    if (scrollOffset + scrollHeight) >= (childHeight - 20) then
        -- Prevent multiple triggers
        if self.loadingChatMore then return end
        self.loadingChatMore = true

        -- Load more results
        self:ChatLoadMoreResults()
    end
end

function StefansLootTracker:ChatLoadMoreResults()
    if self.loadingChatMore then return end
    self.loadingChatMore = true

    -- Increase the loaded chat range for the next batch
    self.loadedChatStartIndex = math.max(self.loadedChatStartIndex - self.itemsChatPerLoad, 1)

    -- Update the window with the current search term
    self:UpdateChatHistoryWindow(self.lastsearchChatTerm)
    
    self.loadingChatMore = false
end

function StefansLootTracker:ResetChatLazyLoading()
    self.loadedChatStartIndex = 1
    self.loadedChatEndIndex = math.min(self.itemsChatPerLoad, #self.db.profile.chathist)
    self.FilteredChatIndices = nil  -- Reset FilteredChatIndices
    self.lastsearchChatTerm = nil
end
