local ADDON_NAME = "GroupForge"
local GF = _G[ADDON_NAME]

GF.UI = {}
local UI = GF.UI

local GOLD  = "|cffFAC800"
local WHITE = "|cffffffff"
local GREEN = "|cff00ff00"
local RED   = "|cffff4444"
local GREY  = "|cff888888"
local RESET = "|r"

local mainFrame

-- Frame dimensions
local FRAME_W         = 370
local HOME_H          = 160
local STATUS_FRAME_CHROME_H = 158
local ROSTER_LINE_H         = 25
local ROSTER_PADDING_Y      = 18
local STATUS_BUTTON_GAP     = 12

local CLASS_COLORS = {
    [1]  = "c69b6d",
    [2]  = "f48cba",
    [3]  = "aad372",
    [4]  = "fff468",
    [5]  = "ffffff",
    [6]  = "c41e3a",
    [7]  = "0070dd",
    [8]  = "3fc7eb",
    [9]  = "8788ee",
    [10] = "00ff98",
    [11] = "ff7c0a",
    [12] = "a330c9",
    [13] = "33937f",
}

local ROLE_ICONS = {
    tank   = "|TInterface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES:16:16:0:0:64:64:0:19:22:41|t",
    healer = "|TInterface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES:16:16:0:0:64:64:20:39:1:20|t",
    dps    = "|TInterface\\LFGFrame\\UI-LFG-ICON-PORTRAITROLES:16:16:0:0:64:64:20:39:22:41|t",
}

-- ── Helpers ───────────────────────────────────────────────────────────────────

local function MakeBackdropFrame(name, parent, w, h)
    local f = CreateFrame("Frame", name, parent, "BackdropTemplate")
    f:SetSize(w, h)
    f:SetBackdrop({
        bgFile   = "Interface\\ChatFrame\\ChatFrameBackground",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = false, tileSize = 16, edgeSize = 16,
        insets = { left = 4, right = 4, top = 4, bottom = 4 },
    })
    f:SetBackdropColor(0.08, 0.08, 0.12, 0.95)
    f:SetBackdropBorderColor(0.98, 0.78, 0.0, 0.8)
    f:SetMovable(true)
    f:EnableMouse(true)
    f:RegisterForDrag("LeftButton")
    f:SetScript("OnDragStart", f.StartMoving)
    f:SetScript("OnDragStop",  f.StopMovingOrSizing)
    return f
end

local function MakeButton(parent, w, h, text)
    local btn = CreateFrame("Button", nil, parent, "UIPanelButtonTemplate")
    btn:SetSize(w, h)
    btn:SetText(text)
    return btn
end

function UI:GetRosterHeight()
    local count = GF.rosterList and #GF.rosterList or 1
    count = math.max(1, math.min(count, 5))
    return (count * ROSTER_LINE_H) + ROSTER_PADDING_Y
end

function UI:GetStatusHeight()
    return STATUS_FRAME_CHROME_H + self:GetRosterHeight()
end

-- ── View switcher ─────────────────────────────────────────────────────────────

function UI:ShowView(name)
    if not mainFrame then return end
    mainFrame.homeView:Hide()
    mainFrame.statusView:Hide()

    if name == "home" then
        mainFrame:SetSize(FRAME_W, HOME_H)
        mainFrame.homeView:Show()

    elseif name == "status" then
        mainFrame:SetSize(FRAME_W, self:GetStatusHeight())
        mainFrame.statusView:Show()
    end
end

-- ── Main frame construction ───────────────────────────────────────────────────

function UI:BuildMainFrame()
    mainFrame = MakeBackdropFrame("GroupForgeMainFrame", UIParent, FRAME_W, HOME_H)
    mainFrame:SetPoint("CENTER", UIParent, "CENTER", 0, 100)
    mainFrame:SetFrameStrata("DIALOG")
    mainFrame:Hide()

    -- Header background
    local headerBg = mainFrame:CreateTexture(nil, "BACKGROUND", nil, 1)
    headerBg:SetPoint("TOPLEFT",  4,  -4)
    headerBg:SetPoint("TOPRIGHT", -4, -4)
    headerBg:SetHeight(38)
    headerBg:SetColorTexture(0.12, 0.12, 0.18, 0.9)

    local headerLine = mainFrame:CreateTexture(nil, "OVERLAY")
    headerLine:SetPoint("BOTTOMLEFT",  headerBg, "BOTTOMLEFT")
    headerLine:SetPoint("BOTTOMRIGHT", headerBg, "BOTTOMRIGHT")
    headerLine:SetHeight(1)
    headerLine:SetColorTexture(0.98, 0.78, 0.0, 0.4)

    local headerIcon = mainFrame:CreateTexture(nil, "OVERLAY")
    headerIcon:SetTexture("Interface\\AddOns\\GroupForge\\icon.png")
    headerIcon:SetSize(22, 22)
    headerIcon:SetPoint("TOPLEFT", mainFrame, "TOPLEFT", 10, -9)

    local header = mainFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    header:SetPoint("LEFT", headerIcon, "RIGHT", 7, 0)
    header:SetText(GOLD .. "GroupForge" .. RESET)

    local closeBtn = CreateFrame("Button", nil, mainFrame, "UIPanelCloseButton")
    closeBtn:SetPoint("TOPRIGHT", -4, -4)

    -- ── HOME VIEW ─────────────────────────────────────────────────────────────
    -- Anchored below header, fills rest of frame
    local hv = CreateFrame("Frame", nil, mainFrame)
    hv:SetPoint("TOPLEFT",     mainFrame, "TOPLEFT",     0, -46)
    hv:SetPoint("BOTTOMRIGHT", mainFrame, "BOTTOMRIGHT", 0,   0)
    mainFrame.homeView = hv

    local pasteLabel = hv:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    pasteLabel:SetPoint("TOPLEFT", hv, "TOPLEFT", 18, -14)
    pasteLabel:SetText(GOLD .. "Paste your group code from the website" .. RESET)

    local ebBg = CreateFrame("Frame", nil, hv, "BackdropTemplate")
    ebBg:SetSize(332, 32)
    ebBg:SetPoint("TOPLEFT", pasteLabel, "BOTTOMLEFT", 0, -6)
    ebBg:SetBackdrop({
        bgFile   = "Interface\\ChatFrame\\ChatFrameBackground",
        edgeFile = "Interface\\Buttons\\WHITE8X8",
        edgeSize = 1,
        insets   = { left = 1, right = 1, top = 1, bottom = 1 }
    })
    ebBg:SetBackdropColor(0, 0, 0, 0.6)
    ebBg:SetBackdropBorderColor(0.3, 0.3, 0.3, 0.8)

    local editBox = CreateFrame("EditBox", nil, ebBg)
    editBox:SetFontObject("ChatFontNormal")
    editBox:SetPoint("TOPLEFT",     ebBg, "TOPLEFT",     8,  -6)
    editBox:SetPoint("BOTTOMRIGHT", ebBg, "BOTTOMRIGHT", -8,  6)
    editBox:SetAutoFocus(false)
    editBox:SetScript("OnEscapePressed", function(self) self:ClearFocus() end)
    mainFrame.pasteBox = editBox

    local homeStatus = hv:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    homeStatus:SetPoint("TOPLEFT", ebBg, "BOTTOMLEFT", 2, -5)
    homeStatus:SetText("")
    mainFrame.homeStatus = homeStatus

    editBox:SetScript("OnTextChanged", function(self)
        local text = self:GetText()
        if not text or #text < 50 then return end
        if text:find("%s") then return end
        local dotCount = select(2, text:gsub("%.", ""))
        if dotCount ~= 1 then return end
        self:ClearFocus()
        self:SetText("")
        local ok, msg = GF:ParsePayload(text)
        if not ok then
            mainFrame.homeStatus:SetText(RED .. msg .. RESET)
        end
    end)

    -- ── STATUS VIEW ───────────────────────────────────────────────────────────
    local sv = CreateFrame("Frame", nil, mainFrame)
    sv:SetPoint("TOPLEFT",     mainFrame, "TOPLEFT",     0, -46)
    sv:SetPoint("BOTTOMRIGHT", mainFrame, "BOTTOMRIGHT", 0,   0)
    sv:Hide()
    mainFrame.statusView = sv

    local groupLabel = sv:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    groupLabel:SetPoint("TOPLEFT", sv, "TOPLEFT", 18, -12)
    groupLabel:SetTextColor(0.98, 0.78, 0.0, 0.45)
    groupLabel:SetText("CURRENT GROUP")

    mainFrame.dungeonText = sv:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    mainFrame.dungeonText:SetPoint("TOPLEFT", groupLabel, "BOTTOMLEFT", 0, -4)
    mainFrame.dungeonText:SetText("")

    mainFrame.keyLevelText = sv:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    mainFrame.keyLevelText:SetPoint("LEFT", mainFrame.dungeonText, "RIGHT", 6, 0)
    mainFrame.keyLevelText:SetText("")

    local rosterBg = CreateFrame("Frame", nil, sv, "BackdropTemplate")
    rosterBg:SetSize(332, 140)
    rosterBg:SetPoint("TOPLEFT", mainFrame.dungeonText, "BOTTOMLEFT", 0, -10)
    rosterBg:SetBackdrop({
        bgFile   = "Interface\\ChatFrame\\ChatFrameBackground",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = false, tileSize = 16, edgeSize = 12,
        insets = { left = 3, right = 3, top = 3, bottom = 3 },
    })
    rosterBg:SetBackdropColor(0, 0, 0, 0.4)
    rosterBg:SetBackdropBorderColor(0.5, 0.5, 0.5, 0.3)
    mainFrame.rosterBg = rosterBg

    mainFrame.rosterLines = {}
    for i = 1, 5 do
        local line = rosterBg:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        line:SetPoint("TOPLEFT", rosterBg, "TOPLEFT", 10, -((i - 1) * ROSTER_LINE_H) - 9)
        line:SetText("")
        mainFrame.rosterLines[i] = line
    end

    -- Re-invite (leader only) — manual fallback, bottom-left
    local startBtn = MakeButton(sv, 148, 26, "Re-invite All")
    startBtn:SetPoint("TOPLEFT", rosterBg, "BOTTOMLEFT", 0, -STATUS_BUTTON_GAP)
    startBtn:Disable()
    startBtn:SetScript("OnClick", function() GF:StartGroup() end)
    mainFrame.startBtn = startBtn

    -- Cancel Readiness — primary button, bottom-right
    local cancelBtn = MakeButton(sv, 148, 26, "Cancel")
    cancelBtn:SetPoint("TOPRIGHT", rosterBg, "BOTTOMRIGHT", 0, -STATUS_BUTTON_GAP)
    cancelBtn:SetScript("OnClick", function() GF:CancelGroup() end)
    mainFrame.cancelBtn = cancelBtn

    self.frame = mainFrame
end

-- ── Refresh logic ─────────────────────────────────────────────────────────────

function UI:RefreshRoster()
    if not self.frame then return end

    if not GF.activeGroupId then
        self:ShowView("home")
        return
    end

    self:ShowView("status")
    if mainFrame.rosterBg then
        mainFrame.rosterBg:SetHeight(self:GetRosterHeight())
    end

    mainFrame.dungeonText:SetText(WHITE .. (GF.contentName or "Unknown") .. RESET)
    if GF.contentType == "mplus" then
        mainFrame.keyLevelText:SetText(GOLD .. "+" .. (GF.contentModifier or "0") .. RESET)
    else
        mainFrame.keyLevelText:SetText(GOLD .. (GF.contentModifier or "") .. RESET)
    end

    local READY_ICON   = "|TInterface\\RAIDFRAME\\ReadyCheck-Ready:14|t"
    local WAITING_ICON = "|TInterface\\RAIDFRAME\\ReadyCheck-NotReady:14|t"
    local LEADER_ICON  = "|TInterface\\GroupFrame\\UI-Group-LeaderIcon:14|t"

    local allReady  = true
    local count     = 0
    local readyCount = 0

    for i, name in ipairs(GF.rosterList) do
        local isReady = GF.roster[name]
        local info    = (GF.rosterInfo and GF.rosterInfo[name]) or { role = "dps", classId = 0 }
        local line    = mainFrame.rosterLines[i]
        if line then
            local roleIcon = ROLE_ICONS[info.role] or ROLE_ICONS.dps
            if info.reserved then
                line:SetText(roleIcon .. " " .. GREY .. "Reserved (friend)" .. RESET)
                readyCount = readyCount + 1
            else
                local statusIcon = isReady and READY_ICON or WAITING_ICON
                local leaderMark = (name == GF.leaderCharacter) and (" " .. LEADER_ICON) or ""
                local hex        = CLASS_COLORS[info.classId] or "aaaaaa"
                line:SetText(roleIcon .. " |cff" .. hex .. name .. RESET .. leaderMark .. "  " .. statusIcon)
                if isReady then readyCount = readyCount + 1 end
            end
        end
        if not isReady and not (info and info.reserved) then allReady = false end
        count = count + 1
    end

    for i = count + 1, 5 do
        if mainFrame.rosterLines[i] then mainFrame.rosterLines[i]:SetText("") end
    end

    if GF.isLeader then
        mainFrame.startBtn:Show()
        if count > 1 then
            mainFrame.startBtn:Enable()
            if allReady then
                mainFrame.startBtn:SetText("Re-invite All")
            else
                mainFrame.startBtn:SetText("Re-invite (" .. readyCount .. "/" .. count .. ")")
            end
        else
            mainFrame.startBtn:Disable()
            mainFrame.startBtn:SetText("Re-invite All")
        end
    else
        mainFrame.startBtn:Hide()
    end
end

-- ── Toggle ────────────────────────────────────────────────────────────────────

function UI:Toggle()
    if not self.frame then self:BuildMainFrame() end
    if self.frame:IsShown() then
        self.frame:Hide()
    else
        self.frame:Show()
        if GF.activeGroupId then
            self:RefreshRoster()
        else
            self:ShowView("home")
        end
    end
end

-- ── Minimap button ────────────────────────────────────────────────────────────

function UI:UpdateMinimapPosition()
    if not self.minimapBtn then return end
    local angle = math.rad(GroupForgeDB.minimapAngle or 45)
    local x = math.cos(angle) * 80
    local y = math.sin(angle) * 80
    self.minimapBtn:SetPoint("CENTER", Minimap, "CENTER", x, y)
end

function UI:CreateMinimapButton()
    local LDB  = LibStub and LibStub:GetLibrary("LibDataBroker-1.1", true)
    local icon = LibStub and LibStub:GetLibrary("LibDBIcon-1.0", true)

    if LDB and icon then
        local obj = LDB:NewDataObject("GroupForge", {
            type = "data source",
            text = "GroupForge",
            icon = "Interface\\AddOns\\GroupForge\\icon.png",
            OnClick = function(_, _) UI:Toggle() end,
            OnTooltipShow = function(tooltip)
                tooltip:SetText(GOLD .. "GroupForge" .. RESET)
                tooltip:AddLine("Click to open", 1, 1, 1)
            end,
        })
        icon:Register("GroupForge", obj, GroupForgeDB.minimap)
        return
    end

    -- Fallback manual minimap button
    local btn = CreateFrame("Button", "GroupForgeMinimapButton", Minimap)
    btn:SetSize(32, 32)
    btn:SetFrameStrata("MEDIUM")
    btn:SetFrameLevel(8)

    local iconTex = btn:CreateTexture(nil, "BACKGROUND")
    iconTex:SetTexture("Interface\\AddOns\\GroupForge\\icon.png")
    iconTex:SetSize(20, 20)
    iconTex:SetPoint("CENTER", 0, 0)

    local border = btn:CreateTexture(nil, "OVERLAY")
    border:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
    border:SetSize(54, 54)
    border:SetPoint("TOPLEFT", 11, -11)

    btn:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")

    btn:RegisterForDrag("LeftButton")
    btn:SetScript("OnDragStart", function(self)
        self:LockHighlight()
        self:SetScript("OnUpdate", function()
            local xpos, ypos = GetCursorPosition()
            local xmin, ymin = Minimap:GetLeft(), Minimap:GetBottom()
            xpos = xmin - xpos / UIParent:GetScale() + 70
            ypos = ypos / UIParent:GetScale() - ymin - 70
            GroupForgeDB.minimapAngle = math.deg(math.atan2(ypos, xpos))
            UI:UpdateMinimapPosition()
        end)
    end)
    btn:SetScript("OnDragStop", function(self)
        self:UnlockHighlight()
        self:SetScript("OnUpdate", nil)
    end)
    btn:SetScript("OnClick", function() UI:Toggle() end)
    btn:SetScript("OnEnter", function(self)
        GameTooltip:SetOwner(self, "ANCHOR_LEFT")
        GameTooltip:AddLine(GOLD .. "GroupForge" .. RESET)
        GameTooltip:AddLine("Click to open", 1, 1, 1)
        GameTooltip:Show()
    end)
    btn:SetScript("OnLeave", function() GameTooltip:Hide() end)

    self.minimapBtn = btn
    self:UpdateMinimapPosition()
end

function UI:Init()
    self:CreateMinimapButton()
end
