local addonName, NS = ...
local GR = _G["GRS_MainFrame"] or CreateFrame("Frame", "GRS_MainFrame", UIParent)

-- =========================================================================
-- 1. ASSETS & CONSTANTS
-- =========================================================================
local CreateBg = NS.CreateBg
local SkinButton = NS.SkinButton

local MACRO_DB_KEY = "macroProfiles"
local MAX_MACROS = 10
local PANEL_WIDTH = 260
local PANEL_HEIGHT = 460
local COLLAPSED_WIDTH = 30
local ROW_HEIGHT = 30

-- FALLBACK DATA
local FALLBACK_RAID_DATA = {
    ["The Dreamrift"] = { { name = "Chimaerus the Undreamt God" } },
    ["The Voidspire"] = { { name = "Imperator Averzian" }, { name = "Vorasius" }, { name = "Fallen-King Salhadaar" }, { name = "Vaelgor & Ezzorak" }, { name = "Lightblinded Vanguard" }, { name = "Crown of the Cosmos" } },
    ["March on Quel'Danas"] = { { name = "Belo'ren, Child of Al'ar" }, { name = "Midnight Falls" } },
}
local FALLBACK_RAID_ORDER = { "The Dreamrift", "The Voidspire", "March on Quel'Danas" }

-- DATA ACCESSORS
local function GetRaidData() return GR.RAID_MAP_DATA or FALLBACK_RAID_DATA end
local function GetRaidOrder() return GR.RAID_ORDER or FALLBACK_RAID_ORDER end

local RAID_ICONS = {
    { text = "{rt1}", icon = "Interface\\TargetingFrame\\UI-RaidTargetingIcon_1" },
    { text = "{rt2}", icon = "Interface\\TargetingFrame\\UI-RaidTargetingIcon_2" },
    { text = "{rt3}", icon = "Interface\\TargetingFrame\\UI-RaidTargetingIcon_3" },
    { text = "{rt4}", icon = "Interface\\TargetingFrame\\UI-RaidTargetingIcon_4" },
    { text = "{rt5}", icon = "Interface\\TargetingFrame\\UI-RaidTargetingIcon_5" },
    { text = "{rt6}", icon = "Interface\\TargetingFrame\\UI-RaidTargetingIcon_6" },
    { text = "{rt7}", icon = "Interface\\TargetingFrame\\UI-RaidTargetingIcon_7" },
    { text = "{rt8}", icon = "Interface\\TargetingFrame\\UI-RaidTargetingIcon_8" },
}

-- =========================================================================
-- 2. CORE INITIALIZATION
-- =========================================================================
local EventFrame = CreateFrame("Frame")
EventFrame:RegisterEvent("ADDON_LOADED")
EventFrame:RegisterEvent("PLAYER_LOGIN")
EventFrame:RegisterEvent("PLAYER_REGEN_ENABLED")

local function InitDatabase()
    if not DB_Rmap_Tools then
        DB_Rmap_Tools = {
            sessions = {},
            lastRaid = GetRaidOrder()[1],
            lastBoss = nil,
            canvasData = {},
            saves = {},
            macroProfiles = {},
            settings = {
                brushSize = 2, opacity = 1.0, isMenuHidden = false,
                disableHelpFlash = false, strategists = {},
                isMacroPanelOpen = true,
                macroPanelPos = nil -- [ADDED] Position container
            }
        }
    end
    
    if not DB_Rmap_Tools.macroProfiles then DB_Rmap_Tools.macroProfiles = {} end
    if not DB_Rmap_Tools.settings then DB_Rmap_Tools.settings = {} end
    if DB_Rmap_Tools.settings.isMacroPanelOpen == nil then DB_Rmap_Tools.settings.isMacroPanelOpen = true end
    
    if not DB_Rmap_Tools.lastBoss then
        local firstRaidData = GetRaidData()[GetRaidOrder()[1]]
        if firstRaidData and firstRaidData[1] then
            DB_Rmap_Tools.lastBoss = firstRaidData[1].name
        end
    end
end

-- =========================================================================
-- 3. UI BUILDER: CONFIG POPUP
-- =========================================================================
local function CreateConfigPopup()
    local f = CreateFrame("Frame", "GRS_Macro_Config", UIParent, "BackdropTemplate")
    f:SetSize(650, 550); f:SetPoint("CENTER"); f:SetFrameStrata("FULLSCREEN_DIALOG"); f:EnableMouse(true)
    
    f:SetBackdrop({
        bgFile = "Interface\\Buttons\\WHITE8x8", 
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", 
        tile = false, tileSize = 16, edgeSize = 16, 
        insets = { left = 4, right = 4, top = 4, bottom = 4 }
    })
    f:SetBackdropColor(0, 0, 0, 0.95); f:SetBackdropBorderColor(0, 0, 0, 1)
    f:Hide()

    local title = f:CreateFontString(nil, "OVERLAY", "GameFontNormalHuge")
    title:SetPoint("TOP", 0, -15); title:SetText("Macro Configuration"); title:SetTextColor(0.6, 0.8, 1, 1)

    f.rows = {}; local startY = -60
    for i = 1, MAX_MACROS do
        local row = CreateFrame("Frame", nil, f)
        row:SetSize(620, 36); row:SetPoint("TOP", 0, startY)
        
        local labelInput = CreateFrame("EditBox", nil, row, "InputBoxTemplate")
        labelInput:SetSize(120, 24); labelInput:SetPoint("LEFT", 10, 0); labelInput:SetAutoFocus(false); labelInput:SetMaxLetters(15)
        local lTitle = labelInput:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall"); lTitle:SetPoint("BOTTOMLEFT", labelInput, "TOPLEFT", 0, 2); lTitle:SetText("Label " .. i)
        row.labelInput = labelInput

        local scroll = CreateFrame("ScrollFrame", nil, row, "UIPanelScrollFrameTemplate")
        scroll:SetSize(320, 32); scroll:SetPoint("LEFT", labelInput, "RIGHT", 20, 0)
        local bg = scroll:CreateTexture(nil, "BACKGROUND"); bg:SetAllPoints(); bg:SetColorTexture(0.1, 0.1, 0.1, 0.5)
        local macroEdit = CreateFrame("EditBox", nil, scroll)
        macroEdit:SetSize(310, 32); macroEdit:SetMultiLine(true); macroEdit:SetFontObject("GameFontHighlightSmall"); macroEdit:SetAutoFocus(false)
        scroll:SetScrollChild(macroEdit); row.macroEdit = macroEdit

        local charCount = row:CreateFontString(nil, "OVERLAY", "GameFontRedSmall")
        charCount:SetPoint("BOTTOMRIGHT", scroll, "TOPRIGHT", 0, 2); charCount:SetText("0/255")
        
        macroEdit:SetScript("OnTextChanged", function(self)
            local len = string.len(self:GetText()); charCount:SetText(len .. "/255")
            if len > 255 then charCount:SetTextColor(1, 0, 0) else charCount:SetTextColor(0, 1, 0) end
            f.CheckSaveState()
        end)

        local iconFrame = CreateFrame("Frame", nil, row)
        iconFrame:SetSize(80, 32); iconFrame:SetPoint("LEFT", scroll, "RIGHT", 25, 0)
        for k, iconData in ipairs(RAID_ICONS) do
            local col = (k - 1) % 4; local r = math.floor((k - 1) / 4)
            local btn = CreateFrame("Button", nil, iconFrame); btn:SetSize(16, 16); btn:SetPoint("TOPLEFT", col * 18, -r * 18); btn:SetNormalTexture(iconData.icon)
            btn:SetScript("OnClick", function() macroEdit:Insert(iconData.text) end)
        end

        local test = CreateFrame("Button", nil, row, "UIPanelButtonTemplate")
        test:SetSize(40, 20); test:SetPoint("LEFT", iconFrame, "RIGHT", 5, 0); test:SetText("Test")
        test:SetScript("OnClick", function() local msg = macroEdit:GetText(); RaidNotice_AddMessage(RaidWarningFrame, msg, ChatTypeInfo["RAID_WARNING"]); print("|cff00ccff[A.X.I.O.M.] Output:|r " .. msg) end)

        startY = startY - 40; f.rows[i] = row
    end

    local btnSave = CreateFrame("Button", nil, f); btnSave:SetSize(100, 30); btnSave:SetPoint("BOTTOMLEFT", 150, 20)
    CreateBg(btnSave, 0, 0, 0, 1)
    local sT = btnSave:CreateFontString(nil, "OVERLAY", "GameFontHighlight"); sT:SetPoint("CENTER"); sT:SetText("Save"); btnSave:SetFontString(sT)

    local btnCancel = CreateFrame("Button", nil, f); btnCancel:SetSize(100, 30); btnCancel:SetPoint("BOTTOMRIGHT", -150, 20)
    CreateBg(btnCancel, 0, 0, 0, 1)
    local cT = btnCancel:CreateFontString(nil, "OVERLAY", "GameFontHighlight"); cT:SetPoint("CENTER"); cT:SetText("Cancel"); btnCancel:SetFontString(cT)
    btnCancel:SetScript("OnClick", function() f:Hide() end)

    f.CheckSaveState = function()
        local valid = true
        for _, r in ipairs(f.rows) do if string.len(r.macroEdit:GetText()) > 255 then valid = false break end end
        if valid then btnSave:Enable(); sT:SetTextColor(1,1,1) else btnSave:Disable(); sT:SetTextColor(0.5,0.5,0.5) end
    end

    btnSave:SetScript("OnClick", function()
        if InCombatLockdown() then print("|cffff0000[A.X.I.O.M.] Cannot Save in Combat!|r") return end
        local boss = DB_Rmap_Tools.lastBoss; if not boss then return end
        if not DB_Rmap_Tools[MACRO_DB_KEY] then DB_Rmap_Tools[MACRO_DB_KEY] = {} end
        local data = {}
        for i, r in ipairs(f.rows) do data[i] = { label = r.labelInput:GetText(), macro = r.macroEdit:GetText() } end
        DB_Rmap_Tools[MACRO_DB_KEY][boss] = data
        print("|cff00ccff[A.X.I.O.M.]|r Macros Saved for " .. boss); GR:UpdateMacroPanel(boss); f:Hide()
    end)
    return f
end

-- =========================================================================
-- 4. MAIN DASHBOARD PANEL
-- =========================================================================
function GR:InitMacroDashboard()
    if self.MacroPanel then self.MacroPanel:Show(); return end

    local f = CreateFrame("Frame", "GRS_Macro_Panel", UIParent, "BackdropTemplate")
    f:SetSize(PANEL_WIDTH, PANEL_HEIGHT)
    
    -- [MODIFIED] Restore Position or Default to Center
    if DB_Rmap_Tools.settings.macroPanelPos then
        local p = DB_Rmap_Tools.settings.macroPanelPos
        f:SetPoint(p[1], UIParent, p[2], p[3], p[4])
    else
        f:SetPoint("CENTER")
    end

    f:SetFrameStrata("MEDIUM")
    f:SetMovable(true); f:EnableMouse(true)
    f:RegisterForDrag("LeftButton")
    f:SetScript("OnDragStart", f.StartMoving)
    
    -- [MODIFIED] Save Position on Drag Stop
    f:SetScript("OnDragStop", function(self)
        self:StopMovingOrSizing()
        local point, _, relativePoint, xOfs, yOfs = self:GetPoint()
        DB_Rmap_Tools.settings.macroPanelPos = { point, relativePoint, xOfs, yOfs }
    end)
    
    f:SetBackdrop({
        bgFile = "Interface\\Buttons\\WHITE8x8", 
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", 
        tile = false, tileSize = 16, edgeSize = 16, 
        insets = { left = 4, right = 4, top = 4, bottom = 4 }
    })
    f:SetBackdropColor(0, 0, 0, 0.8)
    f:SetBackdropBorderColor(0, 0, 0, 1)

    -- Collapse Handler
    f.isCollapsed = false
    
    local collapseBtn = CreateFrame("Button", nil, f)
    collapseBtn:SetSize(20, 20); collapseBtn:SetPoint("TOPLEFT", 5, -5)
    CreateBg(collapseBtn, 0, 0, 0, 1)
    
    local cFs = collapseBtn:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    cFs:SetPoint("CENTER"); cFs:SetText(">>")
    
    -- [REMOVED] Close Button (X) code block deleted here

    local content = CreateFrame("Frame", nil, f)
    content:SetPoint("TOPLEFT", 0, -30); content:SetPoint("BOTTOMRIGHT", 0, 0)
    f.content = content

    local vHeader = CreateFrame("Frame", nil, f)
    vHeader:SetAllPoints(); vHeader:Hide()
    local vText = vHeader:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    vText:SetPoint("CENTER"); vText:SetText("M\na\nc\nr\no\n \nP\na\nn\ne\nl"); vText:SetTextColor(0, 0.8, 1)

    local function UpdateCollapseState()
        local centerX = f:GetCenter(); local screenWidth = GetScreenWidth(); local isRightSide = centerX > (screenWidth / 2)
        if f.isCollapsed then
            f:SetWidth(COLLAPSED_WIDTH); content:Hide(); vHeader:Show(); collapseBtn:SetPoint("TOP", 0, -5)
            if isRightSide then cFs:SetText("<<") else cFs:SetText(">>") end
            
            -- [REMOVED] Close button positioning for collapsed state
        else
            f:SetWidth(PANEL_WIDTH); content:Show(); vHeader:Hide(); collapseBtn:SetPoint("TOPLEFT", 5, -5)
            if isRightSide then cFs:SetText(">>") else cFs:SetText("<<") end
            
             -- [REMOVED] Close button positioning for expanded state
        end
    end
    
    f:SetScript("OnMouseUp", UpdateCollapseState)
    collapseBtn:SetScript("OnClick", function() f.isCollapsed = not f.isCollapsed; UpdateCollapseState() end)
    
    vHeader:SetScript("OnMouseDown", function() f:StartMoving() end)
    
    -- [MODIFIED] Ensure Drag Stop logic is consistent for vHeader as well
    vHeader:SetScript("OnMouseUp", function() 
        f:StopMovingOrSizing()
        local point, _, relativePoint, xOfs, yOfs = f:GetPoint()
        DB_Rmap_Tools.settings.macroPanelPos = { point, relativePoint, xOfs, yOfs }
    end)

    -- BOSS DROPDOWN
    local dropBtn = CreateFrame("Button", nil, content)
    dropBtn:SetSize(PANEL_WIDTH - 20, 24); dropBtn:SetPoint("TOP", 0, -5)
    CreateBg(dropBtn, 0.2, 0.2, 0.2, 1)
    local dTxt = dropBtn:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    dTxt:SetPoint("LEFT", 5, 0); dTxt:SetText(DB_Rmap_Tools.lastBoss or "Select Boss...")
    dropBtn.txt = dTxt
    
    local dropList = CreateFrame("Frame", nil, dropBtn)
    CreateBg(dropList, 0.1, 0.1, 0.1, 1); dropList:SetSize(PANEL_WIDTH - 20, 10); dropList:SetPoint("TOPLEFT", dropBtn, "BOTTOMLEFT", 0, -2); dropList:SetFrameStrata("DIALOG"); dropList:Hide()
    
    dropBtn:SetScript("OnClick", function() 
        if dropList:IsShown() then dropList:Hide() return end
        local kids = {dropList:GetChildren()}; for _, k in ipairs(kids) do k:Hide() end
        local yOff = 0
        
        local DATA = GetRaidData()
        local ORDER = GetRaidOrder()
        
        for _, rName in ipairs(ORDER) do
            local header = CreateFrame("Frame", nil, dropList)
            header:SetSize(PANEL_WIDTH - 20, 18); header:SetPoint("TOPLEFT", 0, yOff)
            local hTxt = header:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall"); hTxt:SetPoint("LEFT", 5, 0); hTxt:SetText(rName)
            yOff = yOff - 18
            
            if DATA[rName] then
                for _, bData in ipairs(DATA[rName]) do
                    local b = CreateFrame("Button", nil, dropList)
                    b:SetSize(PANEL_WIDTH - 20, 20); b:SetPoint("TOPLEFT", 0, yOff)
                    local bT = b:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall"); bT:SetPoint("LEFT", 15, 0); bT:SetText(bData.name); bT:SetWidth(200); bT:SetJustifyH("LEFT")
                    b:SetFontString(bT)
                    b:SetScript("OnClick", function()
                        DB_Rmap_Tools.lastBoss = bData.name
                        GR:UpdateMacroPanel(bData.name)
                        dropList:Hide()
                    end)
                    b:Show(); yOff = yOff - 20
                end
            end
        end
        dropList:SetHeight(math.abs(yOff) + 5); dropList:Show()
    end)
    f.dropBtn = dropBtn

    -- Secure Buttons Generation
    f.buttons = {}
    local y = -45
    for i = 1, MAX_MACROS do
        local lbl = content:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
        lbl:SetPoint("TOPLEFT", 10, y - 5); lbl:SetText("Macro " .. i); lbl:SetWidth(140); lbl:SetJustifyH("LEFT")
        
        local btn = CreateFrame("Button", "GRS_MacroBtn_"..i, content, "SecureActionButtonTemplate, BackdropTemplate")
        btn:SetSize(80, 24); btn:SetPoint("TOPRIGHT", -10, y)
        CreateBg(btn, 0.1, 0.1, 0.1, 1)
        
        local bFs = btn:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
        bFs:SetPoint("CENTER", 0, 0)
        bFs:SetText("Inactive")
        btn.fs = bFs -- Attach to button BEFORE scripts
        
        -- [FIX] Use type1 for Left Click reliability, and register AnyDown
        btn:RegisterForClicks("AnyUp", "AnyDown")
        
        btn:SetScript("OnMouseDown", function(self)
            if self:IsEnabled() then
                local p, r, rp, x, y = self.fs:GetPoint()
                self.fs:SetPoint(p, r, rp, x+1, y-1)
                self:SetBackdropColor(0.2, 0.2, 0.2, 1)
            end
        end)
        btn:SetScript("OnMouseUp", function(self)
            if self:IsEnabled() then
                local p, r, rp, x, y = self.fs:GetPoint()
                self.fs:SetPoint(p, r, rp, 0, 0) 
                self:SetBackdropColor(0, 0, 0, 1)
            end
        end)
        
        btn:SetAttribute("type1", "macro") -- [FIX] Explicit Left Click Type
        f.buttons[i] = { frame = btn, label = lbl, fs = bFs }
        y = y - ROW_HEIGHT - 5
    end

    local cfgBtn = CreateFrame("Button", nil, content)
    cfgBtn:SetSize(PANEL_WIDTH - 20, 24); cfgBtn:SetPoint("BOTTOM", 0, 10)
    CreateBg(cfgBtn, 0, 0, 0, 1)
    local cfgFs = cfgBtn:CreateFontString(nil, "OVERLAY", "GameFontHighlight"); cfgFs:SetPoint("CENTER"); cfgFs:SetText("Configure")
    cfgBtn:SetScript("OnClick", function()
        if InCombatLockdown() then print("|cffff0000[A.X.I.O.M.] Locked in Combat|r") return end
        if not self.ConfigPopup then self.ConfigPopup = CreateConfigPopup() end
        local boss = DB_Rmap_Tools.lastBoss
        local data = (boss and DB_Rmap_Tools[MACRO_DB_KEY] and DB_Rmap_Tools[MACRO_DB_KEY][boss]) or {}
        for i = 1, MAX_MACROS do
            local entry = data[i] or { label = "Macro " .. i, macro = "" }
            self.ConfigPopup.rows[i].labelInput:SetText(entry.label)
            self.ConfigPopup.rows[i].macroEdit:SetText(entry.macro)
        end
        self.ConfigPopup:Show()
    end)

    self.MacroPanel = f
    UpdateCollapseState()
    
    if DB_Rmap_Tools.lastBoss then GR:UpdateMacroPanel(DB_Rmap_Tools.lastBoss) end
end

-- =========================================================================
-- 5. UPDATE & VISIBILITY LOGIC
-- =========================================================================
function GR:ToggleMacroDashboard()
    InitDatabase()
    if not self.MacroPanel then GR:InitMacroDashboard() end
    
    if self.MacroPanel:IsShown() then 
        self.MacroPanel:Hide() 
        DB_Rmap_Tools.settings.isMacroPanelOpen = false
    else 
        self.MacroPanel:Show() 
        DB_Rmap_Tools.settings.isMacroPanelOpen = true
    end
end

function GR:UpdateMacroPanel(bossName)
    if InCombatLockdown() then 
        print("|cffff0000[A.X.I.O.M.] Combat: Macros Pending Update|r")
        GR.PendingMacroUpdate = bossName
        return 
    end
    
    if not self.MacroPanel then GR:InitMacroDashboard() end
    local f = self.MacroPanel
    
    if f.dropBtn and f.dropBtn.txt then f.dropBtn.txt:SetText(bossName) end
    
    local data = (DB_Rmap_Tools[MACRO_DB_KEY] and DB_Rmap_Tools[MACRO_DB_KEY][bossName]) 
    
    local function GetSmartPrefix()
        if UnitIsGroupLeader("player") or UnitIsGroupAssistant("player") then return "/rw " else return "/y " end
    end
    local prefix = GetSmartPrefix()
    
    for i = 1, MAX_MACROS do
        local btnObj = f.buttons[i]
        local entry = data and data[i]
        
        if entry and entry.macro ~= "" then
            btnObj.label:SetText(entry.label)
            
            -- [FIX] SMART LOGIC (Trim + Detect /)
            local cleanMacro = entry.macro:gsub("^/rw%s+", ""):gsub("^/y%s+", ""):gsub("^/raid%s+", "")
            cleanMacro = cleanMacro:match("^%s*(.-)%s*$") -- Trim whitespace
            
            if cleanMacro:sub(1,1) == "/" then
                btnObj.frame:SetAttribute("macrotext", cleanMacro)
            else
                btnObj.frame:SetAttribute("macrotext", prefix .. cleanMacro)
            end
            
            btnObj.frame:SetBackdropColor(0, 0, 0, 1)
            btnObj.fs:SetText("Activate"); btnObj.fs:SetTextColor(1, 1, 1); btnObj.frame:Enable()
        else
            btnObj.label:SetText("Macro " .. i)
            btnObj.frame:SetAttribute("macrotext", "")
            btnObj.frame:SetBackdropColor(0.1, 0.1, 0.1, 1)
            btnObj.fs:SetText("Inactive"); btnObj.fs:SetTextColor(0.5, 0.5, 0.5); btnObj.frame:Disable()
        end
    end
    GR.PendingMacroUpdate = nil
end

-- =========================================================================
-- 6. EVENT HANDLER EXECUTION
-- =========================================================================
EventFrame:SetScript("OnEvent", function(self, event, arg1)
    if event == "ADDON_LOADED" and arg1 == addonName then
        InitDatabase()
    elseif event == "PLAYER_LOGIN" then
        InitDatabase()
        GR:InitMacroDashboard()
        
        if DB_Rmap_Tools.settings.isMacroPanelOpen then
            GR.MacroPanel:Show()
        else
            GR.MacroPanel:Hide()
        end
    elseif event == "PLAYER_REGEN_ENABLED" then
        if GR.PendingMacroUpdate then 
            GR:UpdateMacroPanel(GR.PendingMacroUpdate)
            print("|cff00ccff[A.X.I.O.M.]|r Macros Updated after Combat")
        end
    end
end)