local addonName, TOAST = ...

local frame
local titleFS, noticeFS, notesTitleFS, notesFS, sourceFS, closeButton, closeButtonText
local releaseBanner
local notesCard
local currentKind
local requiredFrame

local TEAL = { 0, 0.92, 0.79 }
local GOLD = { 0.88, 0.75, 0.36 }
local MUTED = { 0.65, 0.65, 0.65 }
local CURSEFORGE_URL = "https://www.curseforge.com/wow/addons/toast"

local TITLES = {
    changelog = "TOAST CHANGELOG",
    weekly = "TOAST Data Update",
    version = "TOAST Update Available",
    required = "UPDATE REQUIRED",
}

local function NoteText()
    local notes = TOAST.ReleaseNotes or {}
    local lines = {}
    for _, entry in ipairs(notes.entries or {}) do
        lines[#lines + 1] = "- " .. entry
    end
    return table.concat(lines, "\n\n")
end

local function DetailFor(kind, message)
    if kind == "changelog" then
        return "Latest changes in TOAST v" .. tostring(TOAST.VERSION), NoteText(), nil
    end
    if kind == "required" then
        return "Update via CurseForge",
            "1. Open the CurseForge app.\n\n2. Update TOAST to the newest version.\n\n3. Restart World of Warcraft or use /reload.",
            "TOAST remains unavailable until the required update is installed."
    end
    if kind == "version" then
        return "Update via CurseForge",
            message or ("Installed version: v" .. tostring(TOAST.VERSION)
                .. "\nAvailable version: newer peer build"
                .. "\n\nOpen CurseForge and update TOAST, then restart World of Warcraft or use /reload."),
            "The newer version was detected through a trusted TOAST crew peer."
    end
    return "Data refresh",
        "Your bundled crew data is older than the current weekly reset. Update your addon through CurseForge to refresh the leaderboard.",
        "Weekly data notices do not imply an addon-code change."
end

local function AddBorder(parent, color)
    local edges = {
        { "TOPLEFT", "TOPRIGHT", "SetHeight", 1 },
        { "BOTTOMLEFT", "BOTTOMRIGHT", "SetHeight", 1 },
        { "TOPLEFT", "BOTTOMLEFT", "SetWidth", 1 },
        { "TOPRIGHT", "BOTTOMRIGHT", "SetWidth", 1 },
    }
    for _, edge in ipairs(edges) do
        local texture = parent:CreateTexture(nil, "BORDER")
        texture:SetColorTexture(color[1], color[2], color[3], color[4])
        texture:SetPoint(edge[1], parent, edge[1], 0, 0)
        texture:SetPoint(edge[2], parent, edge[2], 0, 0)
        texture[edge[3]](texture, edge[4])
    end
end

local function BuildRequired()
    requiredFrame = CreateFrame("Frame", "TOASTUpdateRequired", UIParent, "BackdropTemplate")
    Mixin(requiredFrame, BackdropTemplateMixin)
    requiredFrame:SetSize(470, 336)
    requiredFrame:SetPoint("CENTER")
    requiredFrame:SetFrameStrata("DIALOG")
    requiredFrame:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8x8" })
    requiredFrame:SetBackdropColor(0.06, 0.08, 0.10, 1.0)
    AddBorder(requiredFrame, { 1, 1, 1, 0.12 })
    requiredFrame:Hide()

    local accent = requiredFrame:CreateTexture(nil, "ARTWORK")
    accent:SetColorTexture(GOLD[1], GOLD[2], GOLD[3], 1)
    accent:SetPoint("TOPLEFT", requiredFrame, "TOPLEFT", 0, 0)
    accent:SetPoint("TOPRIGHT", requiredFrame, "TOPRIGHT", 0, 0)
    accent:SetHeight(2)

    local alert = requiredFrame:CreateTexture(nil, "OVERLAY")
    alert:SetTexture("Interface\\AddOns\\TOAST\\media\\dividers\\UPDATE.png")
    alert:SetSize(98, 98)
    alert:SetPoint("TOP", requiredFrame, "TOP", 0, -22)

    local title = requiredFrame:CreateFontString(nil, "OVERLAY", "TOASTFontNormalHuge")
    title:SetPoint("TOP", alert, "BOTTOM", 0, -8)
    title:SetText("UPDATE REQUIRED")
    title:SetTextColor(GOLD[1], GOLD[2], GOLD[3])

    local body = requiredFrame:CreateFontString(nil, "OVERLAY", "TOASTFontHighlight")
    body:SetPoint("TOPLEFT", requiredFrame, "TOPLEFT", 42, -178)
    body:SetPoint("TOPRIGHT", requiredFrame, "TOPRIGHT", -42, -178)
    body:SetJustifyH("CENTER")
    body:SetJustifyV("TOP")
    body:SetWordWrap(true)
    body:SetText("This TOAST version is no longer supported.\nUpdate TOAST through CurseForge to continue.")

    local copyHint = requiredFrame:CreateFontString(nil, "OVERLAY", "TOASTFontNormalSmall")
    copyHint:SetPoint("TOP", requiredFrame, "TOP", 0, -214)
    copyHint:SetText("Ctrl+C to copy the update link")
    copyHint:SetTextColor(1, 1, 1, 0.45)

    local copyBox = CreateFrame("Frame", nil, requiredFrame)
    copyBox:SetSize(386, 26)
    copyBox:SetPoint("TOP", requiredFrame, "TOP", 0, -232)
    local copyBg = copyBox:CreateTexture(nil, "BACKGROUND")
    copyBg:SetAllPoints()
    copyBg:SetColorTexture(0.04, 0.05, 0.07, 0.9)
    AddBorder(copyBox, { 1, 1, 1, 0.12 })

    local copyField = CreateFrame("EditBox", nil, copyBox)
    copyField:SetAllPoints()
    copyField:SetFont(TOAST.FONT_PATH, 11, "")
    copyField:SetTextColor(1, 1, 1, 1)
    copyField:SetTextInsets(8, 8, 0, 0)
    TOAST.LockEditBox(copyField, CURSEFORGE_URL)

    local updateButton = TOAST.CreateActionButton(requiredFrame, "UPDATE VIA CURSEFORGE", "gold", 280, 30)
    updateButton:SetPoint("BOTTOM", requiredFrame, "BOTTOM", 0, 28)
    updateButton:SetScript("OnClick", function()
        copyField:SetFocus()
        copyField:HighlightText()
        print("|cffffd100TOAST|r: Open CurseForge, update TOAST, then restart WoW or use /reload.")
        requiredFrame:Hide()
    end)
end

local function ShowRequired()
    if not requiredFrame then BuildRequired() end
    if frame then frame:Hide() end
    requiredFrame:Show()
end

local function Build()
    frame = CreateFrame("Frame", "TOASTReleaseScreen", UIParent, "BackdropTemplate")
    Mixin(frame, BackdropTemplateMixin)
    frame:SetSize(620, 430)
    frame:SetPoint("CENTER")
    -- Release notes must remain readable when the community gate is already
    -- open, so they deliberately sit one stratum above that dialog.
    frame:SetFrameStrata("FULLSCREEN_DIALOG")
    frame:SetMovable(true)
    frame:SetBackdrop({
        bgFile = "Interface\\Buttons\\WHITE8x8",
    })
    -- Match the Dashboard and onboarding base surface. Cards and text fields
    -- may still be darker to preserve their own hierarchy.
    frame:SetBackdropColor(0.06, 0.08, 0.10, 1.0)
    AddBorder(frame, { 1, 1, 1, 0.12 })
    frame:Hide()

    local header = CreateFrame("Frame", nil, frame)
    -- Match the Dashboard/Leaderboard header proportions exactly.
    header:SetSize(620, 100)
    header:SetPoint("TOPLEFT")
    header:EnableMouse(true)
    header:RegisterForDrag("LeftButton")
    header:SetScript("OnDragStart", function() frame:StartMoving() end)
    header:SetScript("OnDragStop", function()
        frame:StopMovingOrSizing()
        if TOAST.SaveWindowPosition then TOAST.SaveWindowPosition(frame, "release") end
    end)

    -- Like the dashboard and onboarding, the banner is a header child. That
    -- confines it to the header and keeps the divider/body fully clean.
    releaseBanner = header:CreateTexture(nil, "BACKGROUND")
    releaseBanner:SetTexture("Interface\\AddOns\\TOAST\\media\\banners\\kwallen.png")
    releaseBanner:SetTexCoord(0, 1, 0, 1)
    releaseBanner:SetAllPoints(header)
    releaseBanner:SetVertexColor(1, 1, 1, 0.48)
    releaseBanner:Hide()

    -- Header child textures render above direct frame textures, so put this
    -- accent in a higher child frame just as the dashboard does.
    local topAccentFrame = CreateFrame("Frame", nil, frame)
    topAccentFrame:SetAllPoints(frame)
    topAccentFrame:SetFrameLevel(header:GetFrameLevel() + 1)
    local topAccent = topAccentFrame:CreateTexture(nil, "ARTWORK")
    topAccent:SetColorTexture(GOLD[1], GOLD[2], GOLD[3], 1)
    topAccent:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, 0)
    topAccent:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, 0)
    topAccent:SetHeight(2)

    local logo = header:CreateTexture(nil, "OVERLAY")
    logo:SetTexture("Interface\\AddOns\\TOAST\\media\\discord\\toast_128.tga")
    logo:SetSize(58, 58)
    logo:SetPoint("TOPLEFT", header, "TOPLEFT", 20, -16)

    titleFS = header:CreateFontString(nil, "OVERLAY", "TOASTFontNormalHuge")
    titleFS:SetPoint("TOPLEFT", logo, "TOPRIGHT", 12, -1)
    titleFS:SetFont(TOAST.FONT_PATH, 26, "")
    titleFS:SetTextColor(GOLD[1], GOLD[2], GOLD[3])

    local subtitle = header:CreateFontString(nil, "OVERLAY", "TOASTFontNormalSmall")
    subtitle:SetPoint("TOPLEFT", titleFS, "BOTTOMLEFT", 0, -5)
    subtitle:SetJustifyH("LEFT")
    subtitle:SetText("Totally Overengineered Aquatic Support Tech\nv" .. TOAST.VERSION)
    subtitle:SetTextColor(1, 1, 1, 0.45)

    if TOAST.CreateCloseButton then
        TOAST.CreateCloseButton(frame, function() frame:Hide() end)
    end

    if TOAST.CreateAnchorDivider then
        TOAST.CreateAnchorDivider(frame, 20, 600, -101, {
            medallionSize = 32,
            gap = 6,
            lineAlpha = 0.85,
            aboveFrame = header,
        })
    end

    noticeFS = frame:CreateFontString(nil, "OVERLAY", "TOASTFontHighlight")
    noticeFS:SetPoint("TOPLEFT", frame, "TOPLEFT", 28, -120)
    noticeFS:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -28, -120)
    noticeFS:SetJustifyH("LEFT")
    noticeFS:SetJustifyV("TOP")
    noticeFS:SetWordWrap(true)

    notesCard = CreateFrame("Frame", nil, frame)
    notesCard:SetPoint("TOPLEFT", frame, "TOPLEFT", 20, -146)
    notesCard:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -20, 58)
    local cardBg = notesCard:CreateTexture(nil, "BACKGROUND")
    cardBg:SetAllPoints()
    cardBg:SetColorTexture(1, 1, 1, 0.035)
    AddBorder(notesCard, { 1, 1, 1, 0.10 })

    local cardAccent = notesCard:CreateTexture(nil, "ARTWORK")
    cardAccent:SetColorTexture(GOLD[1], GOLD[2], GOLD[3], 0.75)
    cardAccent:SetPoint("TOPLEFT", notesCard, "TOPLEFT", 0, 0)
    cardAccent:SetPoint("TOPRIGHT", notesCard, "TOPRIGHT", 0, 0)
    cardAccent:SetHeight(1)

    notesTitleFS = notesCard:CreateFontString(nil, "OVERLAY", "TOASTFontNormal")
    notesTitleFS:SetPoint("TOPLEFT", notesCard, "TOPLEFT", 14, -12)
    notesTitleFS:SetTextColor(GOLD[1], GOLD[2], GOLD[3])

    notesFS = notesCard:CreateFontString(nil, "OVERLAY", "TOASTFontHighlight")
    notesFS:SetPoint("TOPLEFT", notesTitleFS, "BOTTOMLEFT", 0, -10)
    notesFS:SetPoint("TOPRIGHT", notesCard, "TOPRIGHT", -14, -42)
    notesFS:SetJustifyH("LEFT")
    notesFS:SetJustifyV("TOP")
    notesFS:SetWordWrap(true)

    sourceFS = frame:CreateFontString(nil, "OVERLAY", "TOASTFontNormalSmall")
    sourceFS:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 24, 22)
    sourceFS:SetTextColor(MUTED[1], MUTED[2], MUTED[3])

    closeButton, closeButtonText = TOAST.CreateActionButton(frame, "CLOSE", "gold", 120, 28)
    closeButton:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -24, 18)
    closeButton:SetScript("OnClick", function()
        if currentKind == "required" then
            print("|cffffd100TOAST|r: Open CurseForge, update TOAST, then restart WoW or use /reload.")
        end
        frame:Hide()
    end)
end

function TOAST.ShowReleaseScreen(kind, message)
    if kind == "required" then
        ShowRequired()
        return
    end
    if not frame then Build() end
    if requiredFrame then requiredFrame:Hide() end
    currentKind = kind
    -- A peer-version notice is informational like the changelog, so it uses
    -- the exact same banner -> divider -> card rhythm rather than the older
    -- text-first release layout.
    local usesChangelogLayout = kind == "changelog" or kind == "version"
    -- A peer notice contains only a short status and action. Keep its card
    -- fitted to that content instead of leaving a changelog-sized empty body.
    frame:SetSize(620, kind == "version" and 292 or 430)
    releaseBanner:SetShown(usesChangelogLayout)
    noticeFS:SetShown(not usesChangelogLayout)
    notesCard:ClearAllPoints()
    notesCard:SetPoint("TOPLEFT", frame, "TOPLEFT", 20, usesChangelogLayout and -124 or -146)
    notesCard:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -20, 58)
    local notes = TOAST.ReleaseNotes or {}
    titleFS:SetText(TITLES[kind] or TITLES.changelog)
    if usesChangelogLayout then
        noticeFS:SetText("")
    elseif kind == "required" then
        noticeFS:SetText("This TOAST version is no longer supported.\nTo continue using TOAST, update it through CurseForge.")
    else
        noticeFS:SetText(message or "Latest changes in this TOAST build.")
    end
    noticeFS:SetTextColor(kind == "required" and GOLD[1] or 1, kind == "required" and GOLD[2] or 1,
        kind == "required" and GOLD[3] or 1)
    local detailTitle, detailText, detailSource = DetailFor(kind, message)
    notesTitleFS:SetText(detailTitle)
    notesFS:SetText(detailText)
    sourceFS:SetText(detailSource or ((notes.sourceLabel or "CHANGELOG.md") .. "  -  " .. (notes.version or TOAST.VERSION)))
    closeButtonText:SetText(kind == "required" and "UPDATE VIA CURSEFORGE" or "CLOSE")
    frame:Show()
    frame:Raise()
end

TOAST.commands["changelog"] = function()
    TOAST.ShowReleaseScreen("changelog")
end
