-- MARK: Start Up
local ADDON_NAME, NS = ...
local L = LibStub("AceLocale-3.0"):GetLocale("MDungeonTeleports")

if not MDungeonTeleports then
    MDungeonTeleports = {}
end

if not MDungeonTeleports.Season1Pos then
    MDungeonTeleports.Season1Pos = {x = 975, y = -19}
end

if MDungeonTeleports.showTooltips == nil then
    MDungeonTeleports.showTooltips = false
end

if MDungeonTeleports.CompactMode == nil then
    MDungeonTeleports.CompactMode = false
end

if MDungeonTeleports.TrayModeSeason1 == nil then
    MDungeonTeleports.TrayModeSeason1 = false
end

if MDungeonTeleports.ShiftDragToggle == nil then
    MDungeonTeleports.ShiftDragToggle = false
end

-- Global Togggle
function TrayModeToggleSeason1()
    if InCombatLockdown() then
        return
    end
    if MDungeonTeleports.TrayMode then
        TrayIconSeason1:Show()
        TrayIconBackdropSeason1:Show()
    else
        TrayIconSeason1:Hide()
        TrayIconBackdropSeason1:Hide()
        TrayModeSeason1Off()
    end
end

-- TrayMode Function
local function TrayMode()
    if MDungeonTeleports.TrayModeSeason1 == true then
        TrayModeSeason1On()
    else
        TrayModeSeason1Off()
    end
end

-- Save Function
local function SaveSeason1Position()
    local DungeonFrame = PVEFrame
    if DungeonFrame then
        local frameScale = Season1:GetEffectiveScale()
        local parentScale = DungeonFrame:GetEffectiveScale()

        local season1Left = Season1:GetLeft() * frameScale
        local season1Top = Season1:GetTop() * frameScale
        local dungeonLeft = DungeonFrame:GetLeft() * parentScale
        local dungeonTop = DungeonFrame:GetTop() * parentScale

        local offsetX = (season1Left - dungeonLeft) / parentScale
        local offsetY = (season1Top - dungeonTop) / parentScale

        MDungeonTeleports.Season1Pos = {x = offsetX, y = offsetY}
    end
end

-- Load Function
local function LoadSeason1Position()
    local VarVersionS1 = 1
    if MDungeonTeleports.VarVersionS1 == nil or MDungeonTeleports.VarVersionS1 < VarVersionS1 then
        MDungeonTeleports.VarVersionS1 = VarVersionS1
        MDungeonTeleports.Season1Pos = {x = 975, y = -19}
    end
    local DungeonFrame = PVEFrame
    if DungeonFrame and MDungeonTeleports.Season1Pos then
        local pos = MDungeonTeleports.Season1Pos

        local frameScale = Season1:GetEffectiveScale()
        local parentScale = DungeonFrame:GetEffectiveScale()

        local adjustedX = pos.x * parentScale / frameScale
        local adjustedY = pos.y * parentScale / frameScale

        Season1:ClearAllPoints()
        Season1:SetPoint("TOPLEFT", DungeonFrame, "TOPLEFT", adjustedX, adjustedY)
    end
end

-- Reattach Function
local function ReattachSeason1()
    local DungeonFrame = PVEFrame
    if DungeonFrame and MDungeonTeleports.Season1Pos then
        local pos = MDungeonTeleports.Season1Pos

        local frameScale = Season1:GetEffectiveScale()
        local parentScale = DungeonFrame:GetEffectiveScale()

        local adjustedX = pos.x * parentScale / frameScale
        local adjustedY = pos.y * parentScale / frameScale

        Season1:ClearAllPoints()
        Season1:SetPoint("TOPLEFT", DungeonFrame, "TOPLEFT", adjustedX, adjustedY)
    end
end

-- MARK: Save Function on Close
local function OnPVEFrameClose()
    SaveSeason1Position()
end

-- Font Check and Change
local UserFont = "Interface/AddOns/MDungeonTeleports/media/fonts/expressway.ttf"

local function LocaleFontCheck()
    if GetLocale() == "zhCN" then 
        UserFont = "Interface/AddOns/MDungeonTeleports/media/fonts/sarasa.ttf"
    elseif GetLocale() == "koKR" then 
        UserFont = "Interface/AddOns/MDungeonTeleports/media/fonts/wanted.ttf"
    else 
        UserFont = "Interface/AddOns/MDungeonTeleports/media/fonts/expressway.ttf"
    end
end

-- MARK: Login Start Up
local function OnPlayerLogin()
    LocaleFontCheck()
    LoadSeason1Position()
    UpdateSeason1Background()
    UpdateSeason1UI()
    CompactModeSeason1()
    TrayModeToggleSeason1()
    TrayMode()
    ShiftDragToggleS1()
    showTooltips = MDungeonTeleports.showTooltips
end

local loginFrame = CreateFrame("Frame")
loginFrame:RegisterEvent("PLAYER_LOGIN")
loginFrame:SetScript(
    "OnEvent",
    function(self, event)
        if event == "PLAYER_LOGIN" then
            OnPlayerLogin()
        end
    end
)

-- MARK: Tooltip Toggle
function ToggleTooltips()
    MDungeonTeleports.showTooltips = not MDungeonTeleports.showTooltips
end

-- MARK: Visibility Toggle
function Season1_UpdateVisibility(show)
    local seasonFrame = _G["Season1"]
    if seasonFrame then
        seasonFrame:SetShown(show)
    end
end

-- MARK: Season 1 Frame
local Season1 = CreateFrame("Frame", "Season1", PVEFrame)
Season1:SetSize(164, 130)
Season1:SetMovable(true)
Season1:EnableMouse(true)
Season1:RegisterForDrag("LeftButton")
Season1:SetClampedToScreen(true)

Season1.isBeingDragged = false

Season1:SetScript(
    "OnDragStart",
    function(self)
        self.isBeingDragged = true
        self:StartMoving()
    end
)

Season1:SetScript(
    "OnDragStop",
    function(self)
        if self.isBeingDragged then
            self:StopMovingOrSizing()
            SaveSeason1Position()
            self.isBeingDragged = false
            ReattachSeason1()
        end
    end
)

-- Season 1 Background
local backgroundSeason1 = Season1:CreateTexture(nil, "BACKGROUND")
backgroundSeason1:SetAllPoints(Season1)
backgroundSeason1:SetTexture("Interface/AddOns/MDungeonTeleports/media/framepacks/frames/default_frames.blp")
backgroundSeason1:SetTexCoord(0, 0.160156, 0, 0.126953)
backgroundSeason1:SetVertexColor(1, 1, 1, 1)

-- MARK: Update Background Function
function UpdateSeason1Background()
    local selectedTexture

    if MDungeonTeleports.CompactMode then
        selectedTexture = "Interface/Addons/MDungeonTeleports/media/framepacks/frames/borderless_frames.blp"
    else
        selectedTexture =
            MDungeonTeleports.selectedFramePack or
            "Interface/Addons/MDungeonTeleports/media/framepacks/frames/default_frames.blp"
    end

    backgroundSeason1:SetTexture(selectedTexture)
end

-- Season 1 Title
local Season1Title = Season1:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
Season1Title:SetFont(UserFont, 11, flags)
Season1Title:SetPoint("TOP", Season1, "TOP", 0, -4)
Season1Title:SetText(L["TITLE_S1"])

-- MARK: Time Formatting
local function FormatCooldownTime(seconds)
    if seconds >= 3600 then
        local hours = math.floor(seconds / 3600)
        return string.format("%dh", hours)
    elseif seconds >= 60 then
        local minutes = math.floor(seconds / 60)
        return string.format("%dm", minutes)
    else
        return string.format("%ds", math.floor(seconds))
    end
end

-- -MARK: Cooldown Text Function
local function UpdateCooldownText(button, spellID)
    local cooldownFrame = button.cooldownText
    local cooldownOverlay = button.cooldownOverlay
    local spellCooldownInfo = C_Spell.GetSpellCooldown(spellID)

    if spellCooldownInfo then
        local startTime = spellCooldownInfo.startTime
        local duration = spellCooldownInfo.duration
        local isEnabled = spellCooldownInfo.isEnabled

        if startTime > 0 and duration > 0 and isEnabled then
            local remaining = max(0, (startTime + duration) - GetTime())

            if remaining > 5 then
                cooldownFrame:SetText(FormatCooldownTime(remaining))
                cooldownOverlay:Show()
            else
                cooldownFrame:SetText("")
                cooldownOverlay:Hide()
            end
        else
            cooldownFrame:SetText("")
            cooldownOverlay:Hide()
        end
    else
        cooldownFrame:SetText("")
        cooldownOverlay:Hide()
    end
end

-- MARK: Button Settings
local buttonSize = 32
local buttonSpacing = 5

local spellButtons = {}

-- MARK: Button Creation
local function CreateSpellButton(parent, data, rowOffset)
    local button = CreateFrame("Button", nil, parent, "SecureActionButtonTemplate")
    button:SetSize(buttonSize, buttonSize)
    button:SetPoint("TOPLEFT", parent, "TOPLEFT", (data.index - 1) * (buttonSize + buttonSpacing) + 10, rowOffset)

    button.data = data

    -- Texture for the button
    local buttonTexture = button:CreateTexture(nil, "ARTWORK")
    buttonTexture:SetAllPoints(button)
    buttonTexture:SetTexture(data.icon)

    -- Border texture
    local borderTexture = button:CreateTexture(nil, "OVERLAY")
    borderTexture:SetAllPoints(button)
    borderTexture:SetTexture("Interface\\AddOns\\MDungeonTeleports\\media\\ui\\ui_default\\button_border.blp")
    borderTexture:SetDrawLayer("OVERLAY", 2)
    button.borderTexture = borderTexture

    -- Cooldown texture
    local cooldownOverlay = button:CreateTexture(nil, "OVERLAY")
    cooldownOverlay:SetAllPoints(button)
    cooldownOverlay:SetTexture("Interface\\Tooltips\\UI-Tooltip-Background")
    cooldownOverlay:SetVertexColor(0, 0, 0, 0.6)
    cooldownOverlay:Hide()
    button.cooldownOverlay = cooldownOverlay

    -- Button text
    local buttonText = button:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    buttonText:SetPoint("TOP", button, "BOTTOM", 1, -2)
    local font, _, flags = buttonText:GetFont()
    buttonText:SetFont(UserFont, 11, "OUTLINE")
    buttonText:SetTextColor(1, 1, 1)
    buttonText:SetText(data.name)
    button.buttonText = buttonText

    -- Cooldown text
    local cooldownText = button:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    cooldownText:SetPoint("CENTER", button, "CENTER", 1, 0)
    cooldownText:SetTextColor(1, 1, 1)
    cooldownText:SetFont(UserFont, 14, "OUTLINE")
    button.cooldownText = cooldownText

    -- Spell ID
    button:SetAttribute("type", "spell")
    button:SetAttribute("spell", data.spellID)

    -- Hover overlay
    local hoverOverlay = button:CreateTexture(nil, "HIGHLIGHT")
    hoverOverlay:SetAllPoints(button)
    hoverOverlay:SetTexture("Interface\\AddOns\\MDungeonTeleports\\media\\ui\\ui_default\\button_highlight.blp")
    hoverOverlay:Hide()
    button.hoverOverlay = hoverOverlay

    table.insert(spellButtons, button)

    -- Button texture update function
    local function UpdateButtonTexture()
        local UIPack

        if MDungeonTeleports.CompactMode then
            UIPack = "Interface/Addons/MDungeonTeleports/media/ui/ui_default/"
        else
            UIPack = MDungeonTeleports.selectedUIPack or "Interface/Addons/MDungeonTeleports/media/ui/ui_default/"
        end

        if IsSpellKnown(data.spellID) then
            buttonTexture:SetTexture(data.icon)
        elseif MDungeonTeleports.AltLocks then
            if type(AltLocks) == "table" then
                for _, lock in ipairs(AltLocks) do
                    if lock.spellID == data.spellID then
                        buttonTexture:SetTexture(lock.icon)
                        buttonTexture:SetAlpha(0.6)
                        buttonTexture:SetDesaturated(true)
                        return
                    end
                end
            end
            buttonTexture:SetTexture(UIPack .. "lock.blp")
            buttonTexture:SetAlpha(1)
            buttonTexture:SetDesaturated(false)
        else
            buttonTexture:SetTexture(UIPack .. "lock.blp")
            buttonTexture:SetAlpha(1)
            buttonTexture:SetDesaturated(false)
        end
    end

    button.UpdateButtonTexture = UpdateButtonTexture

    UpdateButtonTexture()

    -- Event handler
    local function OnEvent(self, event)
        if event == "SPELL_UPDATE_COOLDOWN" or event == "SPELLS_CHANGED" then
            UpdateButtonTexture()
            UpdateCooldownText(self, data.spellID)
        end
    end

    -- Tooltips and hover
    button:SetScript(
        "OnEnter",
        function(self)
            if MDungeonTeleports.showTooltips then
                GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
                GameTooltip:SetSpellByID(data.spellID)
                GameTooltip:Show()
            end
            hoverOverlay:Show()
        end
    )

    button:SetScript(
        "OnLeave",
        function(self)
            GameTooltip:Hide()
            hoverOverlay:Hide()
        end
    )

    -- Register events
    button:RegisterEvent("SPELL_UPDATE_COOLDOWN")
    button:RegisterEvent("SPELLS_CHANGED")
    button:RegisterForClicks("AnyUp", "AnyDown")
    button:SetScript("OnEvent", OnEvent)

    return button
end

-- MARK: Update UI Function
function UpdateSeason1UI()
    local UIPack

    if MDungeonTeleports.CompactMode then
        UIPack = "Interface/Addons/MDungeonTeleports/media/ui/ui_default/"
    else
        UIPack = MDungeonTeleports.selectedUIPack or "Interface/Addons/MDungeonTeleports/media/ui/ui_default/"
    end

    for _, btn in ipairs(spellButtons) do
        if btn.borderTexture then
            btn.borderTexture:SetTexture(UIPack .. "button_border.blp")
        end
        if btn.hoverOverlay then
            btn.hoverOverlay:SetTexture(UIPack .. "button_highlight.blp")
        end
        if btn.UpdateButtonTexture then
            btn.UpdateButtonTexture()
        end
    end
end

-- MARK: Button Rows Setup
local rowOffset = -30
local row2Offset = -79

for i, data in ipairs(MDT_Season1Row1) do
    data.index = i
    data.row = 1
    CreateSpellButton(Season1, data, rowOffset)
end

for i, data in ipairs(MDT_Season1Row2) do
    data.index = i
    data.row = 2
    CreateSpellButton(Season1, data, row2Offset)
end

-- Compact Mode Start
function TrayModeToggleSeason1()
    if InCombatLockdown() then
        return
    end
    if MDungeonTeleports.TrayMode then
        TrayButtonSeason1:Show()
    else
        TrayButtonSeason1:Hide()
        TrayModeSeason1Off()
    end
end

-- Compact Mode Start
function CompactModeSeason1()
    if MDungeonTeleports.CompactMode == true then
        CompactModeSeason1On()
    else
        CompactModeSeason1Off()
    end
end

--MARK: Tray Icon Button and Backdrop
local TrayButtonSeason1 = CreateFrame("Button", "TrayButtonSeason1", Season1)
TrayButtonSeason1:SetSize(12, 130)
TrayButtonSeason1:SetPoint("CENTER", Season1, "RIGHT", 8, 0)

local TrayButtonTextureSeason1 = TrayButtonSeason1:CreateTexture(nil, "BACKGROUND")
TrayButtonTextureSeason1:SetAllPoints(TrayButtonSeason1)
TrayButtonTextureSeason1:SetTexture("Interface/AddOns/MDungeonTeleports/media/ui/ui_elements/chevrons.blp")
TrayButtonTextureSeason1:SetTexCoord(0.929687, 1, 0, 0.761718)

local TrayButtonHighlightSeason1 = TrayButtonSeason1:CreateTexture(nil, "HIGHLIGHT")
TrayButtonHighlightSeason1:SetAllPoints(TrayButtonSeason1)
TrayButtonHighlightSeason1:SetTexture("Interface/AddOns/MDungeonTeleports/media/ui/ui_elements/chevrons.blp")
TrayButtonHighlightSeason1:SetTexCoord(0.859375, 0.929687, 0, 0.761718)
TrayButtonHighlightSeason1:Hide()

TrayButtonSeason1.TrayButtonHighlightSeason1 = TrayButtonHighlightSeason1
TrayButtonSeason1.TrayButtonTextureSeason1 = TrayButtonTextureSeason1

TrayButtonSeason1:SetScript(
    "OnEnter",
    function(self)
        TrayButtonTextureSeason1:Hide()
        TrayButtonHighlightSeason1:Show()
    end
)

TrayButtonSeason1:SetScript(
    "OnLeave",
    function(self)
        TrayButtonTextureSeason1:Show()
        TrayButtonHighlightSeason1:Hide()
    end
)

TrayButtonSeason1:SetScript(
    "OnClick",
    function(self)
        if InCombatLockdown() then
            print("Cannot use this in combat!")
            return
        end
        TrayModeSeason1On()
    end
)

-- MARK: Compact Mode On
function CompactModeSeason1On()
    if MDungeonTeleports.TrayModeSeason1 == true then
        Season1:SetSize(12, 94)
    else
        Season1:SetSize(142, 94)
    end

    if MDungeonTeleports.CompactMode == true then
        TrayButtonSeason1:SetHeight(94)
        TrayButtonTextureSeason1:SetTexCoord(0, 0.070312, 0, 0.550781)
        TrayButtonHighlightSeason1:SetTexCoord(0.070312, 0.140625, 0, 0.550781)
    else
        TrayButtonSeason1:SetHeight(130)
        TrayButtonTextureSeason1:SetTexCoord(0.929687, 1, 0, 0.761718)
        TrayButtonHighlightSeason1:SetTexCoord(0.859375, 0.929687, 0, 0.761718)
    end

    backgroundSeason1:SetTexCoord(0.1, 0.140156, 0.1, 0.106953)
    Season1Title:SetPoint("TOP", Season1, "TOP", 0, -4)
    Season1Title:SetFont(UserFont, 11, "OUTLINE")

    local buttonSpacing = 2
    local compactRowOffset = -18
    local compactRow2Offset = -57

    local numColumns = #MDT_Season1Row1

    for _, button in ipairs(spellButtons) do
        local data = button.data
        local isRow2 = (data.row == 2)
        local rowOffset = isRow2 and compactRow2Offset or compactRowOffset
        local colOffset = (data.index - 1) * (buttonSize + buttonSpacing) + 4

        -- Move button
        button:SetPoint("TOPLEFT", button:GetParent(), "TOPLEFT", colOffset, rowOffset)

        -- Adjust button text
        local buttonText = button.buttonText
        if buttonText then
            buttonText:ClearAllPoints()
            buttonText:SetPoint("TOP", button, "BOTTOM", 1, 12)
            buttonText:SetFont(UserFont, 10, "OUTLINE")
        end
        local cooldownText = button.cooldownText
        if cooldownText then
            cooldownText:ClearAllPoints()
            cooldownText:SetPoint("CENTER", button, "CENTER", 0, 4)
            cooldownText:SetFont(UserFont, 12, "OUTLINE")
        end
    end
end

-- MARK: Compact Mode Off
function CompactModeSeason1Off()
    if MDungeonTeleports.TrayModeSeason1 then
        Season1:SetSize(12, 130)
    else
        Season1:SetSize(164, 130)
    end

    if MDungeonTeleports.CompactMode then
        TrayButtonSeason1:SetHeight(94)
        TrayButtonTextureSeason1:SetTexCoord(0, 0.070312, 0, 0.550781)
        TrayButtonHighlightSeason1:SetTexCoord(0.070312, 0.140625, 0, 0.550781)
    else
        TrayButtonSeason1:SetHeight(130)
        TrayButtonTextureSeason1:SetTexCoord(0.929687, 1, 0, 0.761718)
        TrayButtonHighlightSeason1:SetTexCoord(0.859375, 0.929687, 0, 0.761718)
    end

    backgroundSeason1:SetTexCoord(0, 0.160156, 0, 0.126953)
    Season1Title:SetPoint("TOP", Season1, "TOP", 0, -10)
    Season1Title:SetFont(UserFont, 13, "OUTLINE")

    local buttonSpacing = 5
    local rowOffset = -30
    local row2Offset = -79

    local numColumns = #MDT_Season1Row1

    for _, button in ipairs(spellButtons) do
        local data = button.data
        local isRow2 = (data.row == 2)
        local rowOffset = isRow2 and row2Offset or rowOffset
        local colOffset = (data.index - 1) * (buttonSize + buttonSpacing) + 10

        -- Move button
        button:SetPoint("TOPLEFT", button:GetParent(), "TOPLEFT", colOffset, rowOffset)

        -- Adjust button text
        local buttonText = button.buttonText
        if buttonText then
            buttonText:ClearAllPoints()
            buttonText:SetPoint("TOP", button, "BOTTOM", 1, -2)
            buttonText:SetFont(UserFont, 11, "OUTLINE")
        end
        local cooldownText = button.cooldownText
        if cooldownText then
            cooldownText:ClearAllPoints()
            cooldownText:SetPoint("CENTER", button, "CENTER", 1, 0)
            cooldownText:SetFont(UserFont, 14, "OUTLINE")
        end
    end
end

-- MARK: Tray Mode On
function TrayModeSeason1On()
    MDungeonTeleports.TrayModeSeason1 = true

    Season1:SetWidth(12)

    Season1Title:Hide()

    for _, button in ipairs(spellButtons) do
        button:Hide()
    end

    TrayButtonSeason1:SetPoint("CENTER", Season1, "RIGHT", -6, 0)

    TrayButtonTextureSeason1:SetRotation(math.pi)

    TrayButtonHighlightSeason1:SetRotation(math.pi)

    TrayButtonSeason1:SetScript(
    "OnClick",
    function(self)
        if InCombatLockdown() then
            print("Cannot use this in combat!")
            return
        end
        TrayModeSeason1Off()
    end
)
end

-- MARK: Tray Mode Off
function TrayModeSeason1Off()
    MDungeonTeleports.TrayModeSeason1 = false

    local curWidthRes

    if MDungeonTeleports.CompactMode == true then
        curWidthRes = 142
    else
        curWidthRes = 164
    end

    if MDungeonTeleports.CompactMode == true then
        trayHeight = 94
    else
        trayHeight = 130
    end

    Season1Title:Show()
    Season1:SetWidth(curWidthRes)

    for _, button in ipairs(spellButtons) do
        button:Show()
    end

    TrayButtonSeason1:SetHeight(trayHeight)
    TrayButtonSeason1:SetPoint("CENTER", Season1, "RIGHT", 8, 0)

    TrayButtonTextureSeason1:SetRotation(0)

    TrayButtonHighlightSeason1:SetRotation(0)

    TrayButtonSeason1:SetScript(
    "OnClick",
    function(self)
        if InCombatLockdown() then
            print("Cannot use this in combat!")
            return
        end
        TrayModeSeason1On()
    end
)
end

-- MARK: Shift Drag Toggle
function ShiftDragToggleS1()
    if MDungeonTeleports.ShiftDragToggle == true then
        Season1:SetScript("OnDragStart", function(self)
            if IsShiftKeyDown() then
                self.isBeingDragged = true
                self:StartMoving()
            end
        end)
    else
        Season1:SetScript("OnDragStart", function(self)
            self.isBeingDragged = true
            self:StartMoving()
        end)
    end
end

UpdateSeason1UI()