--[[
    MedaUI SearchBox Widget
    EditBox with search icon, clear button, and debounced search
]]

local MedaUI = LibStub("MedaUI-2.0")
---@cast MedaUI MedaUILibrary
local Pixel = LibStub("MedaUI-2.0").Pixel

--- Create a search box
--- @param parent Frame Parent frame
--- @param width number Search box width
--- @return Frame The search box frame
function MedaUI.CreateSearchBox(library, parent, width)
    local searchBox = CreateFrame("Frame", nil, parent, "BackdropTemplate")
    Pixel.SetSize(searchBox, width, 24)
    searchBox:SetBackdrop(library:CreateBackdrop(true))

    searchBox.OnSearch = nil
    searchBox.debounceTime = 0.3
    searchBox.debounceTimer = nil
    searchBox._hasFocus = false

    -- Search icon (use texture instead of emoji)
    searchBox.icon = searchBox:CreateTexture(nil, "OVERLAY")
    Pixel.SetSize(searchBox.icon, 14, 14)
    Pixel.SetPoint(searchBox.icon, "LEFT", 8, 0)
    searchBox.icon:SetAtlas("common-search-magnifyingglass")
    searchBox.icon:SetDesaturated(true)

    -- Edit box for input
    searchBox.editBox = CreateFrame("EditBox", nil, searchBox)
    Pixel.SetPoint(searchBox.editBox, "LEFT", 26, 0)
    Pixel.SetPoint(searchBox.editBox, "RIGHT", -24, 0)
    Pixel.SetHeight(searchBox.editBox, 20)
    searchBox.editBox:SetFontObject(GameFontNormalSmall)
    searchBox.editBox:SetAutoFocus(false)
    searchBox.editBox:SetMaxLetters(100)

    -- Placeholder text
    searchBox.placeholder = searchBox:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    Pixel.SetPoint(searchBox.placeholder, "LEFT", searchBox.editBox, "LEFT", 2, 0)
    searchBox.placeholder:SetText("Search...")

    -- Clear button
    searchBox.clearBtn = CreateFrame("Button", nil, searchBox)
    Pixel.SetSize(searchBox.clearBtn, 16, 16)
    Pixel.SetPoint(searchBox.clearBtn, "RIGHT", -6, 0)
    searchBox.clearBtn:Hide()

    searchBox.clearBtn.text = searchBox.clearBtn:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    Pixel.SetPoint(searchBox.clearBtn.text, "CENTER", 0, 1)
    searchBox.clearBtn.text:SetText("x")

    -- Apply theme colors
    local function ApplyTheme()
        local theme = MedaUI.Theme
        searchBox:SetBackdropColor(unpack(theme.input))
        if searchBox._hasFocus then
            searchBox:SetBackdropBorderColor(unpack(theme.gold))
        else
            searchBox:SetBackdropBorderColor(unpack(theme.border))
        end
        searchBox.icon:SetVertexColor(unpack(theme.textDim))
        searchBox.editBox:SetTextColor(unpack(theme.text))
        searchBox.placeholder:SetTextColor(unpack(theme.textDim))
        searchBox.clearBtn.text:SetTextColor(unpack(theme.textDim))
    end
    searchBox._ApplyTheme = ApplyTheme

    -- Register for theme updates
    searchBox._themeHandle = MedaUI:RegisterThemedWidget(searchBox, ApplyTheme)

    -- Initial theme application
    ApplyTheme()

    searchBox.clearBtn:SetScript("OnEnter", function(button)
        local theme = MedaUI.Theme
        button.text:SetTextColor(unpack(theme.text))
    end)

    searchBox.clearBtn:SetScript("OnLeave", function(button)
        local theme = MedaUI.Theme
        button.text:SetTextColor(unpack(theme.textDim))
    end)

    searchBox.clearBtn:SetScript("OnClick", function()
        searchBox:Clear()
    end)

    -- Debounced search function
    local function TriggerSearch()
        if searchBox.OnSearch then
            searchBox:OnSearch(searchBox.editBox:GetText())
        end
    end

    local function DebouncedSearch()
        if searchBox.debounceTimer then
            searchBox.debounceTimer:Cancel()
        end
        searchBox.debounceTimer = C_Timer.NewTimer(searchBox.debounceTime, TriggerSearch)
    end

    -- EditBox scripts
    searchBox.editBox:SetScript("OnTextChanged", function(self, userInput)
        local text = self:GetText()
        if text and text ~= "" then
            searchBox.placeholder:Hide()
            searchBox.clearBtn:Show()
        else
            searchBox.placeholder:Show()
            searchBox.clearBtn:Hide()
        end

        if userInput then
            DebouncedSearch()
        end
    end)

    searchBox.editBox:SetScript("OnEnterPressed", function(self)
        -- Immediate search on enter
        if searchBox.debounceTimer then
            searchBox.debounceTimer:Cancel()
        end
        TriggerSearch()
        self:ClearFocus()
    end)

    searchBox.editBox:SetScript("OnEscapePressed", function(self)
        self:ClearFocus()
    end)

    searchBox.editBox:SetScript("OnEditFocusGained", function()
        searchBox._hasFocus = true
        local theme = MedaUI.Theme
        searchBox:SetBackdropBorderColor(unpack(theme.gold))
    end)

    searchBox.editBox:SetScript("OnEditFocusLost", function()
        searchBox._hasFocus = false
        local theme = MedaUI.Theme
        searchBox:SetBackdropBorderColor(unpack(theme.border))
    end)

    -- Click on container focuses editbox
    searchBox:SetScript("OnMouseDown", function()
        searchBox.editBox:SetFocus()
    end)

    --- Get the current search text
    --- @return string The search text
    function searchBox:GetText()
        return self.editBox:GetText()
    end

    --- Set the search text
    --- @param text string The text to set
    function searchBox:SetText(text)
        self.editBox:SetText(text or "")
    end

    --- Clear the search box
    function searchBox:Clear()
        self.editBox:SetText("")
        self.editBox:ClearFocus()
        if self.OnSearch then
            self:OnSearch("")
        end
    end

    --- Set the placeholder text
    --- @param text string The placeholder text
    function searchBox:SetPlaceholder(text)
        self.placeholder:SetText(text)
    end

    --- Set the debounce time
    --- @param seconds number Debounce delay in seconds
    function searchBox:SetDebounceTime(seconds)
        self.debounceTime = seconds
    end

    --- Focus the search box
    function searchBox:SetFocus()
        self.editBox:SetFocus()
    end

    --- Clear focus from the search box
    function searchBox:ClearFocus()
        self.editBox:ClearFocus()
    end

    return searchBox
end
