local RUI = LibStub("RUI-1.0")
if not RUI then return end

-- RUI.Widget.SoundDropdown(parent, label, x, y, width, get, set, lsm [,ddName])
-- → Button, Refresh()
-- Rows include a speaker icon button to preview the sound without changing selection.
-- Total height consumed: LABEL_H(14) + DD_H(24) + CONTROL_GAP(4) = 42px.
local MENU_ROW_H   = 22
local MENU_MAX_VIS = 10

function RUI.Widget.SoundDropdown(parent, label, x, y, width, get, set, lsm, ddName)
    local lbl = RUI.Draw.MakeLabel(parent)
    lbl:SetTextColor(RUI.C.TEXT.r, RUI.C.TEXT.g, RUI.C.TEXT.b)
    lbl:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)
    lbl:SetWidth(width)
    lbl:SetJustifyH("LEFT")
    lbl:SetText(label)

    local btn = RUI.Draw.MakeDropdownButton(parent, ddName, width)
    btn:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y - RUI.LABEL_H)

    local menuFrame, scrollFrame, scrollChild = RUI.Draw.MakeMenuFrame()

    local rowW = width - 22
    local rows = {}

    local function UpdateButtonText()
        btn.Text:SetText(get() or "None")
    end

    local function BuildRows()
        for _, r in ipairs(rows) do r:Hide(); r:SetParent(nil) end
        wipe(rows)

        local entries = RUI.Media.BuildSoundMenuValues(lsm)
        local curVal  = get() or "None"
        local n       = #entries
        local visRows = math.min(n, MENU_MAX_VIS)

        menuFrame:SetHeight(visRows * MENU_ROW_H + 4)
        scrollChild:SetSize(rowW, n * MENU_ROW_H)

        if scrollFrame.ScrollBar then
            if n > MENU_MAX_VIS then scrollFrame.ScrollBar:Show()
            else scrollFrame.ScrollBar:Hide() end
        end

        for i, entry in ipairs(entries) do
            local row = CreateFrame("Button", nil, scrollChild)
            row:SetPoint("TOPLEFT", 0, -(i - 1) * MENU_ROW_H)
            row:SetSize(rowW, MENU_ROW_H)

            local hl = row:CreateTexture(nil, "HIGHLIGHT")
            hl:SetAllPoints()
            hl:SetColorTexture(RUI.C.ACCENT.r, RUI.C.ACCENT.g, RUI.C.ACCENT.b, 0.3)

            -- Speaker preview button for non-None entries (on the right)
            local playBtn
            if entry.value ~= "None" then
                playBtn = CreateFrame("Button", nil, row)
                playBtn:SetSize(16, 16)
                playBtn:SetPoint("RIGHT", -4, 0)
                local tex = playBtn:CreateTexture(nil, "ARTWORK")
                tex:SetAllPoints()
                tex:SetTexture(130979)  -- VoiceChat-Speaker icon
                tex:SetVertexColor(0.8, 0.8, 0.8)
                playBtn:SetScript("OnEnter", function() tex:SetVertexColor(1, 1, 1) end)
                playBtn:SetScript("OnLeave", function() tex:SetVertexColor(0.8, 0.8, 0.8) end)
                local soundName = entry.value
                playBtn:SetScript("OnClick", function()
                    RUI.Media.PlaySound(lsm, soundName)
                end)
            end

            -- Text label (leave room for play button if present)
            local fs = row:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
            fs:SetPoint("LEFT", 8, 0)
            if playBtn then
                fs:SetPoint("RIGHT", playBtn, "LEFT", -4, 0)
            else
                fs:SetPoint("RIGHT", 0, 0)
            end
            fs:SetJustifyH("LEFT")
            row.Text = fs

            if entry.value == curVal then
                fs:SetTextColor(RUI.C.ACCENT.r, RUI.C.ACCENT.g, RUI.C.ACCENT.b)
            else
                fs:SetTextColor(RUI.C.TEXT.r, RUI.C.TEXT.g, RUI.C.TEXT.b)
            end
            fs:SetText(entry.text)

            local val = entry.value
            local txt = entry.text
            row:SetScript("OnClick", function()
                -- Ignore clicks that land on the play button
                if playBtn and playBtn:IsMouseOver() then return end
                set(val)
                btn.Text:SetText(txt)
                menuFrame:Hide()
            end)

            rows[i] = row
        end
    end

    local function OpenMenu()
        RUI.Draw.CloseOpenMenu()
        BuildRows()
        menuFrame:ClearAllPoints()
        menuFrame:SetPoint("TOPLEFT",  btn, "BOTTOMLEFT",  0, -2)
        menuFrame:SetPoint("TOPRIGHT", btn, "BOTTOMRIGHT", 0, -2)
        menuFrame:Show()
        RUI._openMenu = menuFrame

        -- Scroll to the currently selected entry
        local entries = RUI.Media.BuildSoundMenuValues(lsm)
        local curVal  = get() or "None"
        for i, entry in ipairs(entries) do
            if entry.value == curVal then
                local offset = math.max(0, (i - 1) * MENU_ROW_H - math.floor(MENU_MAX_VIS / 2) * MENU_ROW_H)
                scrollFrame:SetVerticalScroll(offset)
                break
            end
        end
    end

    btn:SetScript("OnClick", function()
        if menuFrame:IsShown() then menuFrame:Hide()
        else OpenMenu() end
    end)

    local function Refresh()
        UpdateButtonText()
        if menuFrame:IsShown() then BuildRows() end
    end
    Refresh()
    return btn, Refresh, lbl
end
