EbonholdHub.EchoPicker = {}

local UI = EbonholdHub.UI
local C  = UI.Colors

local QUALITY_COLOR = {
    [0] = "ffffff",
    [1] = "19ff19",
    [2] = "0066ff",
    [3] = "cc66ff",
    [4] = "ff8000",
}

local ROW_HEIGHT = 28

local frame, searchBox, listScroll, scrollFrame, scrollChild
local allEntries   = {}
local filtered     = {}
local rowPool      = {}
local onPick
local searchText   = ""


local function BuildEntries()
    local best = EbonholdHub.EchoTableRows.BuildBestByName()
    local list = {}
    for name, entry in pairs(best) do
        list[#list + 1] = {
            spellId = entry.spellId,
            name    = name,
            quality = entry.quality,
        }
    end
    table.sort(list, function(a, b) return a.name < b.name end)
    return list
end

local function ApplySearch()
    filtered = {}
    if searchText == "" then
        for i = 1, #allEntries do filtered[i] = allEntries[i] end
        return
    end
    for i = 1, #allEntries do
        local e = allEntries[i]
        if e.name:lower():find(searchText, 1, true) then
            filtered[#filtered + 1] = e
        end
    end
end

local function UpdateScrollWidth()
    if not scrollFrame or not scrollChild then return end
    local w = scrollFrame:GetWidth()
    if w and w > 0 then
        scrollChild:SetWidth(math.max(1, w))
    end
end


local function CreateRow(parent)
    local row = CreateFrame("Button", nil, parent)
    row:SetHeight(ROW_HEIGHT)

    local bg = UI.Fill(row, C.elementBg)
    row._bg = bg
    row._spellId = nil

    row:SetScript("OnEnter", function(self)
        self._bg:SetVertexColor(unpack(C.elementHov))
        if self._spellId and EbonholdHub.EchoTableRows then
            EbonholdHub.EchoTableRows.ShowSpellTooltip(self, self._spellId)
        end
    end)
    row:SetScript("OnLeave", function(self)
        self._bg:SetVertexColor(unpack(C.elementBg))
        GameTooltip:Hide()
    end)

    local iconBtn = UI.CreateIconButton(row, 22)
    iconBtn:SetPoint("LEFT", row, "LEFT", 4, 0)
    iconBtn:EnableMouse(false)
    row._iconBtn = iconBtn

    local label = row:CreateFontString(nil, "OVERLAY")
    UI.SetFont(label, UI.FONT_SIZE_NORMAL, C.text)
    label:SetPoint("LEFT", iconBtn, "RIGHT", 8, 0)
    label:SetPoint("RIGHT", row, "RIGHT", -6, 0)
    label:SetJustifyH("LEFT")
    row._label = label
    return row
end

local function PopulateRow(row, index, entry)
    row:ClearAllPoints()
    row:SetPoint("LEFT",  scrollChild, "LEFT",  0, 0)
    row:SetPoint("RIGHT", scrollChild, "RIGHT", 0, 0)
    row:SetPoint("TOP",   scrollChild, "TOP",   0, -(index - 1) * ROW_HEIGHT)

    row._spellId = entry.spellId
    row._iconBtn.icon:SetTexture(select(3, GetSpellInfo(entry.spellId)))
    row._iconBtn.icon:SetVertexColor(1, 1, 1)
    if row._iconBtn._empty then row._iconBtn._empty:Hide() end
    UI.SetIconButtonQuality(row._iconBtn, entry.quality)

    local color = QUALITY_COLOR[entry.quality] or "ffffff"
    row._label:SetText("|cff" .. color .. entry.name .. "|r")
    row:SetScript("OnClick", function()
        if onPick then onPick(entry.spellId, entry.quality, entry.name) end
        frame:Hide()
    end)
    row:Show()
end

local function Render()
    UpdateScrollWidth()
    for i = 1, #filtered do
        if not rowPool[i] then rowPool[i] = CreateRow(scrollChild) end
        PopulateRow(rowPool[i], i, filtered[i])
    end
    for i = #filtered + 1, #rowPool do rowPool[i]:Hide() end
    scrollChild:SetHeight(math.max(1, #filtered * ROW_HEIGHT))
    if listScroll and listScroll.UpdateThumb then
        listScroll.UpdateThumb()
    end
end


local function BuildFrame()
    frame = UI.CreateWindow("EbonholdHubEchoPicker", 400, 500, "Pick an Echo", {
        strata = "FULLSCREEN_DIALOG",
        toplevel = true,
    })
    local content = frame.content

    local hint = UI.CreateLabel(content, "Search echoes by name", UI.FONT_SIZE_SMALL, C.textDim)
    hint:SetPoint("TOPLEFT", content, "TOPLEFT", 0, 0)

    local searchHolder = UI.CreateEditBox(content, 360, 22, false)
    searchHolder:SetPoint("TOPLEFT", hint, "BOTTOMLEFT", 0, -4)
    searchBox = searchHolder.editBox
    searchBox:SetScript("OnTextChanged", function(self)
        searchText = (self:GetText() or ""):lower()
        ApplySearch()
        Render()
    end)

    listScroll = UI.CreateScrollFrame(content)
    listScroll:SetPoint("TOPLEFT", searchHolder, "BOTTOMLEFT", 0, -8)
    listScroll:SetPoint("BOTTOMRIGHT", content, "BOTTOMRIGHT", 0, 0)
    scrollFrame = listScroll.scrollFrame
    scrollChild = listScroll.scrollChild

    scrollFrame:SetScript("OnSizeChanged", function()
        UpdateScrollWidth()
        Render()
    end)

    frame:Hide()
    return frame
end


function EbonholdHub.EchoPicker.Show(callback, dataSource)
    if not frame then
        frame = BuildFrame()
    end
    if type(dataSource) == "table" then
        allEntries = dataSource
    elseif dataSource then
        allEntries = EbonholdHub.EchoTableRows.BuildAllQualitiesList()
    else
        allEntries = BuildEntries()
    end
    onPick = callback
    searchBox:SetText("")
    searchText = ""
    ApplySearch()
    Render()
    frame:Show()
    searchBox:SetFocus()
end

function EbonholdHub.EchoPicker.Hide()
    if frame then frame:Hide() end
end
