local addonName, ns = ...
local L = ns.L

local cache = {}
local W = ns.Widgets
local C = ns.COLORS

local function PlaceSlider(slider, parent, x, y)
    local frame = slider:GetParent()
    frame:ClearAllPoints()
    frame:SetPoint("TOPLEFT", parent, "TOPLEFT", x, y)
    return slider
end

function ns:InitRangeCheck()
    local p = ns.MainFrame.Content
    local db = BrightQoL.rangeCheck
    local rangeDisplay = ns.RangeCheckRangeFrame

    W:CachedPanel(cache, "rcFrame", p, function(f)
        local sf, sc = W:CreateScrollFrame(f, 800)

        W:CreatePageHeader(sc,
            {{"RANGE ", C.BLUE}, {"CHECK", C.ORANGE}},
            W.Colorize(L["RANGE_SUBTITLE"], C.GRAY))

        local function refreshRange()
            if rangeDisplay then
                rangeDisplay.initialized = false
                rangeDisplay:UpdateDisplay()
            end
        end

        -- Master enable area
        local killArea = CreateFrame("Frame", nil, sc, "BackdropTemplate")
        killArea:SetSize(460, 62)
        killArea:SetPoint("TOPLEFT", 10, -75)
        killArea:SetBackdrop({ bgFile = [[Interface\Buttons\WHITE8x8]] })
        killArea:SetBackdropColor(0.01, 0.56, 0.91, 0.08)

        local masterCB = W:CreateCheckbox(killArea, {
            label = L["RANGE_ENABLE"],
            db = db, key = "enabled",
            x = 15, y = -8,
            isMaster = true,
        })

        local unlockCB = W:CreateCheckbox(killArea, {
            label = L["COMMON_UNLOCK"],
            db = db, key = "rangeUnlock",
            x = 15, y = -38,
            template = "ChatConfigCheckButtonTemplate",
            onChange = refreshRange
        })
        unlockCB:SetShown(db.enabled)

        -- Section container
        local sectionContainer = CreateFrame("Frame", nil, sc)
        sectionContainer:SetPoint("TOPLEFT", killArea, "BOTTOMLEFT", 0, -10)
        sectionContainer:SetPoint("RIGHT", sc, "RIGHT", -10, 0)
        sectionContainer:SetHeight(400)

        local RelayoutSections

        -- BEHAVIOR section
        local behWrap, behContent = W:CreateCollapsibleSection(sectionContainer, {
            text = L["COMMON_SECTION_BEHAVIOR"],
            startOpen = false,
            onCollapse = function() if RelayoutSections then RelayoutSections() end end,
        })

        W:CreateCheckbox(behContent, {
            label = L["RANGE_COMBAT_ONLY"],
            db = db, key = "rangeCombatOnly",
            x = 10, y = -5,
            template = "ChatConfigCheckButtonTemplate",
            onChange = refreshRange
        })
        behContent:SetHeight(35)
        behWrap:RecalcHeight()

        -- APPEARANCE section
        local appWrap, appContent = W:CreateCollapsibleSection(sectionContainer, {
            text = L["COMMON_SECTION_APPEARANCE"],
            startOpen = false,
            onCollapse = function() if RelayoutSections then RelayoutSections() end end,
        })

        W:CreateFontPicker(appContent, 10, -5, db.rangeFont, function(path)
            db.rangeFont = path
            refreshRange()
        end)

        if not db.rangeColors then
            db.rangeColors = {
                [0]  = {r = 0.01, g = 0.91, b = 0.15},
                [5]  = {r = 0.01, g = 0.91, b = 0.15},
                [10] = {r = 0.91, g = 0.91, b = 0.01},
                [15] = {r = 0.91, g = 0.56, b = 0.01},
                [20] = {r = 0.91, g = 0.56, b = 0.01},
                [25] = {r = 0.91, g = 0.20, b = 0.01},
                [30] = {r = 0.91, g = 0.01, b = 0.01},
                [35] = {r = 0.91, g = 0.01, b = 0.01},
                [40] = {r = 0.91, g = 0.01, b = 0.01},
            }
        end

        local brackets = {0, 5, 10, 15, 20, 25, 30, 35, 40}
        local yOffset = -50
        for i, bracket in ipairs(brackets) do
            local nextBracket = brackets[i + 1] or (bracket + 5)
            local label = bracket .. "-" .. (nextBracket - 1) .. " yd"
            if not db.rangeColors[bracket] then
                db.rangeColors[bracket] = {r = 0.01, g = 0.56, b = 0.91}
            end
            local colorBtn = CreateFrame("Button", nil, appContent)
            colorBtn:SetSize(20, 20)
            colorBtn:SetPoint("TOPLEFT", 10, yOffset)

            local border = colorBtn:CreateTexture(nil, "BACKGROUND")
            border:SetPoint("TOPLEFT", -1, 1)
            border:SetPoint("BOTTOMRIGHT", 1, -1)
            border:SetColorTexture(0.3, 0.3, 0.3)

            local tex = colorBtn:CreateTexture(nil, "ARTWORK")
            tex:SetAllPoints()
            tex:SetColorTexture(db.rangeColors[bracket].r, db.rangeColors[bracket].g, db.rangeColors[bracket].b)
            colorBtn.tex = tex

            local lbl = appContent:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
            lbl:SetPoint("LEFT", colorBtn, "RIGHT", 8, 0)
            lbl:SetText(label)

            colorBtn:SetScript("OnClick", function()
                local c = db.rangeColors[bracket]
                ColorPickerFrame:SetupColorPickerAndShow({
                    r = c.r, g = c.g, b = c.b,
                    hasOpacity = false,
                    swatchFunc = function()
                        local r, g, b = ColorPickerFrame:GetColorRGB()
                        db.rangeColors[bracket] = {r = r, g = g, b = b}
                        tex:SetColorTexture(r, g, b)
                        refreshRange()
                    end,
                    cancelFunc = function(prev)
                        db.rangeColors[bracket] = {r = prev.r, g = prev.g, b = prev.b}
                        tex:SetColorTexture(prev.r, prev.g, prev.b)
                        refreshRange()
                    end,
                })
            end)
            yOffset = yOffset - 28
        end

        appContent:SetHeight(50 + (#brackets * 28) + 10)
        appWrap:RecalcHeight()

        -- MELEE INDICATOR section
        local mlWrap, mlContent = W:CreateCollapsibleSection(sectionContainer, {
            text = L["RANGE_MELEE_ENABLE"] or "MELEE INDICATOR",
            startOpen = true,
            onCollapse = function() if RelayoutSections then RelayoutSections() end end,
        })

        local meleeSubElements = {}

        local function updateMeleeSubVisibility()
            local show = db.displayMode == "melee"
            for _, el in ipairs(meleeSubElements) do
                el:SetShown(show)
            end
            mlContent:SetHeight(show and 340 or 35)
            mlWrap:RecalcHeight()
            if RelayoutSections then RelayoutSections() end
        end

        -- Mode toggle checkbox
        local modeCheckbox = W:CreateCheckbox(mlContent, {
            label = L["RANGE_MELEE_ENABLE"] or "Enable Melee Indicator",
            checked = db.displayMode == "melee",
            x = 10, y = -5,
            template = "ChatConfigCheckButtonTemplate",
            onChange = function(checked)
                db.displayMode = checked and "melee" or "text"
                refreshRange()
                updateMeleeSubVisibility()
            end,
        })

        -- Indicator text input
        local textLabel = mlContent:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
        textLabel:SetPoint("TOPLEFT", 10, -38)
        textLabel:SetText(L["RANGE_MELEE_TEXT"] or "Indicator Text:")
        meleeSubElements[#meleeSubElements + 1] = textLabel

        local textInput = CreateFrame("EditBox", nil, mlContent, "BackdropTemplate")
        textInput:SetSize(200, 22)
        textInput:SetPoint("TOPLEFT", 10, -58)
        textInput:SetBackdrop({
            bgFile   = [[Interface\Buttons\WHITE8x8]],
            edgeFile = [[Interface\Buttons\WHITE8x8]],
            edgeSize = 1,
        })
        textInput:SetBackdropColor(0.08, 0.08, 0.12, 0.95)
        textInput:SetBackdropBorderColor(0, 207/255, 1.0, 0.6)
        textInput:SetFontObject("GameFontHighlightSmall")
        textInput:SetTextInsets(6, 4, 0, 0)
        textInput:SetTextColor(1, 1, 1, 1)
        textInput:SetAutoFocus(false)
        textInput:SetMaxLetters(64)
        textInput:SetText(db.meleeText or "- OUT OF RANGE -")
        textInput:SetScript("OnEnterPressed", function(self)
            db.meleeText = self:GetText()
            refreshRange()
            self:ClearFocus()
        end)
        textInput:SetScript("OnEscapePressed", function(self)
            self:SetText(db.meleeText or "- OUT OF RANGE -")
            self:ClearFocus()
        end)
        meleeSubElements[#meleeSubElements + 1] = textInput

        -- Color picker
        local colorBtn, colorPreview = W:CreateColorPicker(mlContent, {
            label = L["RANGE_MELEE_COLOR"] or "Text Color",
            db = db,
            rKey = "meleeColorR", gKey = "meleeColorG", bKey = "meleeColorB",
            noClassColor = true,
            x = 10, y = -88,
            onChange = refreshRange,
        })

        W:CreateColorPicker(mlContent, {
            label    = "Border Color",
            x = 220, y = -88,
            db       = db,
            rKey     = "borderColorR", gKey = "borderColorG", bKey = "borderColorB", classColorKey = "borderUseClassColor",
            onChange = function() if ns.RangeCheck then ns.RangeCheck:ApplySettings() end end,
        })
        meleeSubElements[#meleeSubElements + 1] = colorBtn
        meleeSubElements[#meleeSubElements + 1] = colorPreview

        -- Sound enable
        local soundCB = W:CreateCheckbox(mlContent, {
            label = L["CROSSHAIR_SOUND_ENABLE"] or "Enable Sound Alert",
            db = db, key = "meleeSoundEnabled",
            x = 10, y = -125,
            template = "ChatConfigCheckButtonTemplate",
            onChange = refreshRange,
        })
        meleeSubElements[#meleeSubElements + 1] = soundCB

        -- Sound picker
        local soundPicker = W:CreateSoundPicker(mlContent, 10, -155, db.meleeSoundID or 8959,
            function(id) db.meleeSoundID = id end)
        meleeSubElements[#meleeSubElements + 1] = soundPicker

        -- Repeat interval slider
        local intervalSlider = W:CreateAdvancedSlider(mlContent,
            W.Colorize(L["CROSSHAIR_SOUND_INTERVAL"] or "Repeat Interval (sec)", C.BLUE),
            0, 15, -195, 1, false,
            function(val) db.meleeSoundInterval = val end,
            { db = db, key = "meleeSoundInterval", moduleName = "rangeCheck" })
        PlaceSlider(intervalSlider, mlContent, 0, -195)
        meleeSubElements[#meleeSubElements + 1] = intervalSlider:GetParent()

        -- Spell ID override
        local spellLabel = mlContent:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
        spellLabel:SetPoint("TOPLEFT", 10, -255)
        spellLabel:SetText(W.Colorize(L["CROSSHAIR_SPELL_ID"] or "Range Check Spell ID", C.WHITE))
        meleeSubElements[#meleeSubElements + 1] = spellLabel

        local spellStatusText = mlContent:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
        spellStatusText:SetPoint("TOPLEFT", 10, -272)
        spellStatusText:SetTextColor(0.6, 0.6, 0.6)
        meleeSubElements[#meleeSubElements + 1] = spellStatusText

        local spellInputContainer = CreateFrame("Frame", nil, mlContent)
        spellInputContainer:SetSize(250, 25)
        spellInputContainer:SetPoint("TOPLEFT", 10, -290)
        meleeSubElements[#meleeSubElements + 1] = spellInputContainer

        local spellInput = CreateFrame("EditBox", nil, spellInputContainer, "BackdropTemplate")
        spellInput:SetSize(100, 22)
        spellInput:SetPoint("LEFT", 0, 0)
        spellInput:SetBackdrop({
            bgFile   = [[Interface\Buttons\WHITE8x8]],
            edgeFile = [[Interface\Buttons\WHITE8x8]],
            edgeSize = 1,
        })
        spellInput:SetBackdropColor(0.08, 0.08, 0.12, 0.95)
        spellInput:SetBackdropBorderColor(0, 207/255, 1.0, 0.6)
        spellInput:SetFontObject("GameFontHighlightSmall")
        spellInput:SetJustifyH("LEFT")
        spellInput:SetTextInsets(6, 4, 0, 0)
        spellInput:SetTextColor(1, 1, 1, 1)
        spellInput:SetAutoFocus(false)
        spellInput:SetNumeric(true)
        spellInput:SetMaxLetters(9)

        local function UpdateSpellDisplay()
            local info = ns.MeleeRangeInfo
            if not info then
                spellStatusText:SetText("Crosshair module not loaded")
                spellStatusText:SetTextColor(1, 0.5, 0.5)
                return
            end
            -- Check for range-check-specific override
            local key = info.GetSpellKey and info.GetSpellKey()
            local override = key and db.meleeSpellOverrides and db.meleeSpellOverrides[key]
            local current = override or (info.GetCurrentSpell and info.GetCurrentSpell())
            local default = info.GetDefaultSpell and info.GetDefaultSpell()

            if current then
                spellInput:SetText(tostring(current))
                local spellInfo = C_Spell.GetSpellInfo(current)
                local spellName = spellInfo and spellInfo.name or "Unknown"
                spellStatusText:SetText(string.format(L["CROSSHAIR_SPELL_CURRENT"] or "Current: %s", spellName))
                spellStatusText:SetTextColor(0.5, 1, 0.5)
            elseif default == nil then
                spellInput:SetText("")
                spellStatusText:SetText(L["CROSSHAIR_SPELL_UNSUPPORTED"] or "Not supported for this spec")
                spellStatusText:SetTextColor(1, 0.5, 0.5)
            else
                spellInput:SetText("")
                spellStatusText:SetText(L["CROSSHAIR_SPELL_NONE"] or "No spell set")
                spellStatusText:SetTextColor(1, 0.5, 0.5)
            end
        end

        spellInput:SetScript("OnEnterPressed", function(self)
            local info = ns.MeleeRangeInfo
            if not info then return end
            local key = info.GetSpellKey and info.GetSpellKey()
            if not key then return end
            local val = tonumber(self:GetText())
            if val and val > 0 then
                db.meleeSpellOverrides = db.meleeSpellOverrides or {}
                db.meleeSpellOverrides[key] = val
            end
            UpdateSpellDisplay()
            refreshRange()
            self:ClearFocus()
        end)

        spellInput:SetScript("OnEscapePressed", function(self)
            UpdateSpellDisplay()
            self:ClearFocus()
        end)

        local resetSpellBtn = W:CreateButton(spellInputContainer, {
            text = L["CROSSHAIR_RESET_SPELL"] or "Reset to Default",
            width = 120, height = 22,
            onClick = function()
                local info = ns.MeleeRangeInfo
                if not info then return end
                local key = info.GetSpellKey and info.GetSpellKey()
                if key and db.meleeSpellOverrides then
                    db.meleeSpellOverrides[key] = nil
                end
                UpdateSpellDisplay()
                refreshRange()
            end
        })
        resetSpellBtn:SetPoint("LEFT", spellInput, "RIGHT", 10, 0)

        -- Register for spec changes
        ns.SpecUtil.RegisterCallback("RangeCheckConfig", function()
            UpdateSpellDisplay()
        end)

        UpdateSpellDisplay()
        updateMeleeSubVisibility()

        mlContent:SetHeight(db.displayMode == "melee" and 340 or 35)
        mlWrap:RecalcHeight()

        -- Layout
        local allSections = { behWrap, appWrap, mlWrap }

        RelayoutSections = function()
            for i, section in ipairs(allSections) do
                section:ClearAllPoints()
                if i == 1 then
                    section:SetPoint("TOPLEFT", sectionContainer, "TOPLEFT", 0, 0)
                else
                    section:SetPoint("TOPLEFT", allSections[i - 1], "BOTTOMLEFT", 0, -12)
                end
                section:SetPoint("RIGHT", sectionContainer, "RIGHT", 0, 0)
            end

            local totalH = 75 + 62 + 10
            if db.enabled then
                for _, s in ipairs(allSections) do
                    totalH = totalH + s:GetHeight() + 12
                end
            end
            sc:SetHeight(math.max(totalH + 40, 800))
        end

        -- Master enable click
        masterCB:HookScript("OnClick", function(self)
            db.enabled = self:GetChecked() and true or false
            db.rangeEnabled = db.enabled
            refreshRange()
            unlockCB:SetShown(db.enabled)
            sectionContainer:SetShown(db.enabled)
            RelayoutSections()
        end)

        -- Restore defaults button
        local restoreBtn = W:CreateRestoreDefaultsButton({
            moduleName = "rangeCheck",
            parent = sc,
            fixedParent = killArea,
            initFunc = function() ns:InitRangeCheck() end,
            onRestore = function()
                if cache.rcFrame then
                    cache.rcFrame:Hide()
                    cache.rcFrame:SetParent(nil)
                    cache.rcFrame = nil
                end
                if rangeDisplay then rangeDisplay:UpdateDisplay() end
            end
        })

        -- Initial visibility
        sectionContainer:SetShown(db.enabled)
        RelayoutSections()
    end)
end
