-- ini
if not MDungeonTeleports then
   MDungeonTeleports = {}
end

if not MDungeonTeleports.PortalLibraryPos then
   MDungeonTeleports.PortalLibraryPos = {x = 970, y = -100}
end

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

-- Save
local function SavePortalLibraryPosition()
   local DungeonFrame = PVEFrame
   if DungeonFrame then
       local frameScale = PortalLibrary:GetScale()
       local parentScale = DungeonFrame:GetScale()

       local PortalLibraryLeft = PortalLibrary:GetLeft() * frameScale
       local PortalLibraryBottom = PortalLibrary:GetBottom() * frameScale
       local dungeonLeft = DungeonFrame:GetLeft() * parentScale
       local dungeonBottom = DungeonFrame:GetBottom() * parentScale

       local offsetX = (PortalLibraryLeft - dungeonLeft) / parentScale
       local offsetY = (PortalLibraryBottom - dungeonBottom) / parentScale

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

-- Load
local function LoadPortalLibraryPosition()
   local DungeonFrame = PVEFrame
   if DungeonFrame and MDungeonTeleports.PortalLibraryPos then
       local pos = MDungeonTeleports.PortalLibraryPos

       local frameScale = PortalLibrary:GetScale()
       local parentScale = DungeonFrame:GetScale()

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

       PortalLibrary:ClearAllPoints()
       PortalLibrary:SetPoint("BOTTOMLEFT", DungeonFrame, "BOTTOMLEFT", adjustedX, adjustedY)
   end
end

-- Reattatch
local function ReattatchPortalLibrary()
   local DungeonFrame = PVEFrame
   if DungeonFrame and MDungeonTeleports.PortalLibraryPos then
       local pos = MDungeonTeleports.PortalLibraryPos

       local frameScale = PortalLibrary:GetScale()
       local parentScale = DungeonFrame:GetScale()

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

       PortalLibrary:ClearAllPoints()
       PortalLibrary:SetPoint("BOTTOMLEFT", DungeonFrame, "BOTTOMLEFT", adjustedX, adjustedY)
   end
end

-- load position
local function LoadPortalLibraryPosition()
   ReattatchPortalLibrary()
end

-- save on close
local function OnPVEFrameClose()
   SavePortalLibraryPosition()
end

-- load on login
local function OnPlayerLogin()
   UpdatePortalLibraryBackground()
   LoadPortalLibraryPosition()
   UpdatePortalLibraryUI()
end

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

-- tooltip toggle
function ToggleTooltips()
   MDungeonTeleports.showTooltips = not MDungeonTeleports.showTooltips
end

-- visibility funtion
function PortalLibrary_UpdateVisibility(show)
   local portalLibraryFrame = _G["PortalLibrary"]
   if portalLibraryFrame then
       portalLibraryFrame:SetShown(show)
   end
end
-- data for buttons
-- dragonflight
local row1Data = {
   {icon = "Interface\\Icons\\achievement_dungeon_dragonacademy", spellID = 393273, name = "AA"},
   {icon = "Interface\\Icons\\achievement_dungeon_arcanevaults", spellID = 393279, name = "AV"},
   {icon = "Interface\\Icons\\achievement_dungeon_brackenhidehollow", spellID = 393267, name = "BH"},
   {icon = "Interface\\Icons\\achievement_dungeon_hallsofinfusion", spellID = 393283, name = "HOI"},
   {icon = "Interface\\Icons\\achievement_dungeon_neltharus", spellID = 393276, name = "NELTH"},
   {icon = "Interface\\Icons\\achievement_dungeon_centaurplains", spellID = 393262, name = "NO"},
   {icon = "Interface\\Icons\\achievement_dungeon_lifepools", spellID = 393256, name = "RLP"},
   {icon = "Interface\\Icons\\achievement_dungeon_uldaman", spellID = 393222, name = "ULD"},
   {icon = "Interface\\Icons\\achievement_dungeon_dawnoftheinfinite", spellID = 424197, name = "DOTI"}
}
-- shadowlands
local row2Data = {
   {icon = "Interface\\Icons\\achievement_dungeon_theotherside", spellID = 354468, name = "DOS"},
   {icon = "Interface\\Icons\\achievement_dungeon_hallsofattonement", spellID = 354465, name = "HOA"},
   {icon = "Interface\\Icons\\achievement_dungeon_mistsoftirnascithe", spellID = 354464, name = "MISTS"},
   {icon = "Interface\\Icons\\achievement_dungeon_theneroticwake", spellID = 354462, name = "NW"},
   {icon = "Interface\\Icons\\achievement_dungeon_plaguefall", spellID = 354463, name = "PF"},
   {icon = "Interface\\Icons\\achievement_dungeon_sanguinedepths", spellID = 354469, name = "SD"},
   {icon = "Interface\\Icons\\achievement_dungeon_spireofascension", spellID = 354466, name = "SOA"},
   {icon = "Interface\\Icons\\achievement_dungeon_theatreofpain", spellID = 354467, name = "TOP"},
   {icon = "Interface\\Icons\\achievement_dungeon_brokerdungeon", spellID = 367416, name = "TAZ"}
}

local factionGroup = UnitFactionGroup("player")

local siegeID
if factionGroup == "Horde" then
   siegeID = 464256
elseif factionGroup == "Alliance" then
   siegeID = 445418
end

-- battle for azeroth
local row3Data = {
   {icon = "Interface\\Icons\\achievement_dungeon_ataldazar", spellID = 424187, name = "AD"},
   {icon = "Interface\\Icons\\achievement_dungeon_freehold", spellID = 410071, name = "FH"},
   {icon = "Interface\\Icons\\achievement_dungeon_siegeofboralus", spellID = siegeID, name = "SIEGE"},
   {icon = "Interface\\Icons\\achievement_dungeon_underrot", spellID = 410074, name = "UNDR"},
   {icon = "Interface\\Icons\\achievement_dungeon_waycrestmannor", spellID = 424167, name = "WM"},
   {icon = "Interface\\Icons\\achievement_boss_mechagon", spellID = 373274, name = "MECHA"}
}
-- legion
local row4Data = {
   {icon = "Interface\\Icons\\achievement_dungeon_blackrookhold", spellID = 424153, name = "BRH"},
   {icon = "Interface\\Icons\\achievement_dungeon_courtofstars", spellID = 393766, name = "COS"},
   {icon = "Interface\\Icons\\achievement_dungeon_darkheartthicket", spellID = 424163, name = "DT"},
   {icon = "Interface\\Icons\\achievement_dungeon_hallsofvalor", spellID = 393764, name = "HOV"},
   {icon = "Interface\\Icons\\achievement_dungeon_neltharionslair", spellID = 410078, name = "NL"},
   {icon = "Interface\\Icons\\achievement_raid_karazhan", spellID = 373262, name = "KARA"}
}
-- warlords of draenor
local row5Data = {
   {icon = "Interface\\Icons\\achievement_dungeon_auchindoun", spellID = 159897, name = "AUCH"},
   {icon = "Interface\\Icons\\achievement_dungeon_ogreslagmines", spellID = 159895, name = "BSM"},
   {icon = "Interface\\Icons\\achievement_dungeon_everbloom", spellID = 159901, name = "EB"},
   {icon = "Interface\\Icons\\achievement_dungeon_blackrockdepot", spellID = 159900, name = "GD"},
   {icon = "Interface\\Icons\\achievement_dungeon_blackrockdocks", spellID = 159896, name = "ID"},
   {icon = "Interface\\Icons\\achievement_dungeon_shadowmoonhideout", spellID = 159899, name = "SBG"},
   {icon = "Interface\\Icons\\achievement_dungeon_arakkoaspires", spellID = 159898, name = "SR"},
   {icon = "Interface\\Icons\\achievement_dungeon_upperblackrockspire", spellID = 159902, name = "UBRS"}
}
-- mists of pandaria
local row6Data = {
   {icon = "Interface\\Icons\\achievement_greatwall", spellID = 131225, name = "GOTSS"},
   {icon = "Interface\\Icons\\achievement_dungeon_mogupalace", spellID = 131222, name = "MSP"},
   {icon = "Interface\\Icons\\spell_holy_senseundead", spellID = 131232, name = "SCHOLO"},
   {icon = "Interface\\Icons\\inv_helmet_52", spellID = 131231, name = "SH"},
   {icon = "Interface\\Icons\\spell_holy_resurrection", spellID = 131229, name = "SM"},
   {icon = "Interface\\Icons\\achievement_dungeon_siegeofniuzaotemple", spellID = 131228, name = "SNT"},
   {icon = "Interface\\Icons\\achievement_shadowpan_hideout", spellID = 131206, name = "SPM"},
   {icon = "Interface\\Icons\\achievement_brewery", spellID = 131205, name = "SSB"},
   {icon = "Interface\\Icons\\achievement_jadeserpent", spellID = 131204, name = "TJS"}
}
-- cataclysm
local row7Data = {
   {icon = "Interface\\Icons\\achievement_dungeon_grimbatol", spellID = 445424, name = "GB"},
   {icon = "Interface\\Icons\\achievement_dungeon_throne of the tides", spellID = 424142, name = "TOTT"},
   {icon = "Interface\\Icons\\achievement_dungeon_skywall", spellID = 410080, name = "VP"}
}
-- data for titles
local expansionTitles = {
   {text = "--Dragonflight--", offset = -27},
   {text = "--Shadowlands--", offset = -87},
   {text = "--Battle for Azeroth--", offset = -147},
   {text = "--Legion--", offset = -207},
   {text = "--Warlords of Draenor--", offset = -267},
   {text = "--Mists of Pandaria--", offset = -327},
   {text = "--Cataclysm--", offset = -387}
}
-- frame
local PortalLibrary = CreateFrame("Frame", "PortalLibrary", PVEFrame)
PortalLibrary:SetSize(348, 450)
PortalLibrary:SetPoint("CENTER", PVEFrame, "CENTER", 900, 0)
PortalLibrary:SetMovable(true)
PortalLibrary:EnableMouse(true)
PortalLibrary:RegisterForDrag("LeftButton")

-- drag
PortalLibrary:SetScript(
   "OnDragStart",
   function(self)
       if IsShiftKeyDown() then
           self.isBeingDragged = true
           self:StartMoving()
       end
   end
)

PortalLibrary:SetScript(
   "OnDragStop",
   function(self)
       if self.isBeingDragged then
           self:StopMovingOrSizing()
           SavePortalLibraryPosition()
           self.isBeingDragged = false
           ReattatchPortalLibrary()
       end
   end
)

-- backgroundPortalLib
local backgroundPortalLib = PortalLibrary:CreateTexture(nil, "BACKGROUND")
backgroundPortalLib:SetAllPoints(PortalLibrary)
backgroundPortalLib:SetTexture("Interface/AddOns/MDungeonTeleports/media/frames/default_frames.blp")
backgroundPortalLib:SetTexCoord(0.160156, 0.5, 0, 0.439453)
backgroundPortalLib:SetVertexColor(1, 1, 1, 1)

function UpdatePortalLibraryBackground()
   local selectedTexture =
       MDungeonTeleports.selectedFramePack or "Interface/Addons/MDungeonTeleports/media/frames/default_frames.blp"
   backgroundPortalLib:SetTexture(selectedTexture)
end

-- title
local PortalLibraryTitle = PortalLibrary:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
PortalLibraryTitle:SetPoint("TOP", PortalLibrary, "TOP", 0, -10)
PortalLibraryTitle:SetFont("Interface/AddOns/MDungeonTeleports/media/fonts/expressway.ttf", 13, flags)
PortalLibraryTitle:SetText("Portal Library")

-- expansion titles
for _, section in ipairs(expansionTitles) do
   local title = PortalLibrary:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
   title:SetPoint("TOP", PortalLibrary, "TOP", 0, section.offset)
   local font, _, flags = title:GetFont()
   title:SetFont("Interface/AddOns/MDungeonTeleports/media/fonts/expressway.ttf", 11, flags)
   title:SetTextColor(0.2, 0.8, 0.9)
   title:SetText(section.text)
end

-- buttons settings and functions
local buttonSize = 32
local buttonSpacing = 5
local rowOffset = -40

-- 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

-- cooldown text
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

local spellButtons = {}

-- Create spell buttons
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)

   -- 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\\default_ui\\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("Interface/AddOns/MDungeonTeleports/media/fonts/expressway.ttf", 11, flags)
   buttonText:SetTextColor(1, 1, 1)
   buttonText:SetText(data.name)

   -- Cooldown text
   local cooldownText = button:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
   cooldownText:SetPoint("CENTER", button, "CENTER", -1, -1)
   cooldownText:SetTextColor(1, 1, 1)
   cooldownText:SetFont("Interface/AddOns/MDungeonTeleports/media/fonts/expressway.ttf", 14, flags)
   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\\default_ui\\button_highlight.blp")
   hoverOverlay:Hide()
   button.hoverOverlay = hoverOverlay

   table.insert(spellButtons, button)

   -- Button texture update function
   local function UpdateButtonTexture()
       local UIPack = MDungeonTeleports.selectedUIPack or "Interface/Addons/MDungeonTeleports/media/ui/default_ui/"

       if IsSpellKnown(data.spellID) then
           buttonTexture:SetTexture(data.icon)
       else
           -- Use the UIPack for the lock texture
           buttonTexture:SetTexture(UIPack .. "lock.blp")
       end
   end

   button.UpdateButtonTexture = UpdateButtonTexture

   -- Call texture update
   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

function UpdatePortalLibraryUI()
   local UIPack = MDungeonTeleports.selectedUIPack or "Interface/Addons/MDungeonTeleports/media/ui/default_ui/"

   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

-- buttons row 1
for i, data in ipairs(row1Data) do
   data.index = i
   CreateSpellButton(PortalLibrary, data, rowOffset)
end

-- buttons row 2
local row2Offset = -99
for i, data in ipairs(row2Data) do
   data.index = i
   CreateSpellButton(PortalLibrary, data, row2Offset)
end

-- buttons row 3
local row3Offset = -159
for i, data in ipairs(row3Data) do
   data.index = i
   CreateSpellButton(PortalLibrary, data, row3Offset)
end

-- buttons row 4
local row4Offset = -219
for i, data in ipairs(row4Data) do
   data.index = i
   CreateSpellButton(PortalLibrary, data, row4Offset)
end

-- buttons row 5
local row5Offset = -279
for i, data in ipairs(row5Data) do
   data.index = i
   CreateSpellButton(PortalLibrary, data, row5Offset)
end

-- buttons row 6
local row6Offset = -339
for i, data in ipairs(row6Data) do
   data.index = i
   CreateSpellButton(PortalLibrary, data, row6Offset)
end

-- buttons row 7
local row7Offset = -399
for i, data in ipairs(row7Data) do
   data.index = i
   CreateSpellButton(PortalLibrary, data, row7Offset)
end

UpdatePortalLibraryUI()
