local API = rawget(_G, "LIDPANELS_API")
local INTERNAL_API = type(API) == "table" and type(API.__internal) == "table" and API.__internal or nil
if type(INTERNAL_API) ~= "table" then
  error("LidPanels missing internal API registry.")
end

local function CreateAboutUtilitySections(editor, aboutContent, deps)
  deps = deps or {}
  local MakeAboutTitle = deps.MakeAboutTitle
  local MakeYellowSubHeader = deps.MakeYellowSubHeader
  local RootDB = deps.RootDB
  local SafeHookScript = deps.SafeHookScript or function(frame, scriptName, handler)
    if frame and type(frame.HookScript) == "function" and type(handler) == "function" then
      pcall(frame.HookScript, frame, scriptName, handler)
    end
  end
  local titleColor = deps.titleColor or { 0.6588, 0.4784, 0.9098, 1.0 }
  local titleR, titleG, titleB, titleA = titleColor[1], titleColor[2], titleColor[3], titleColor[4] or 1.0

  local aboutCreditsFrame = CreateFrame("Frame", nil, aboutContent)
  aboutCreditsFrame:SetAllPoints(aboutContent)
  aboutCreditsFrame:Hide()
  editor.aboutCreditsFrame = aboutCreditsFrame

  local creditsTitle = MakeAboutTitle(aboutCreditsFrame, "Credits", 0, 0)
  editor.aboutCreditsTitle = creditsTitle

  local function CreateCreditsSection(parent, titleText, bodyText)
    local header = parent:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    header:SetJustifyH("LEFT")
    header:SetText(titleText)
    header:SetTextColor(titleR, titleG, titleB, titleA)

    local body = parent:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    body:SetJustifyH("LEFT")
    body:SetText(bodyText)
    if body.SetSpacing then body:SetSpacing(3) end

    local divider = parent:CreateTexture(nil, "ARTWORK")
    divider:SetColorTexture(1, 1, 1, 0.14)
    divider:SetHeight(1)

    return {
      header = header,
      body = body,
      divider = divider,
    }
  end

  local creditsSections = {
    CreateCreditsSection(
      aboutCreditsFrame,
      "Disclaimer",
      "This addon is an independent fan project and is not affiliated with or endorsed by Blizzard Entertainment, Inc.\n" ..
      "World of Warcraft and all related artwork are trademarks or registered trademarks of Blizzard Entertainment."
    ),
    CreateCreditsSection(
      aboutCreditsFrame,
      "Acknowledgements",
      "A big thank you to the creators of ElvUI for their exceptional work.\n" ..
      "While this addon does not use ElvUI code, its robust environment and tools greatly helped with stress testing, diagnostics, and ensuring compatibility with other addons.\n\n" ..
      "Inspired by the original KGPanels addon and its creator, whose work shaped UI customization for many players over the years.\n\n" ..
      "Special thanks to the creator of LargerMacroIconSelection - their icon list was incredibly helpful while building the icon selection features.\n\n" ..
      "Last but not least, a big thank you to wuuusaa, who helped forging LidPanels architecture wise and accompany me on this journey."
    ),
    CreateCreditsSection(
      aboutCreditsFrame,
      "Testing & Feedback",
      "Special thanks to the following people for their time, feedback, and testing support:\n\n" ..
      "- Valmaris\n" ..
      "- Rikku\n" ..
      "- wuuusaa\n" ..
      "- MoerphyK"
    ),
    CreateCreditsSection(
      aboutCreditsFrame,
      "Development Tools",
      "This addon was developed with assistance from AI tools, including ChatGPT and Codex, which supported code generation, problem solving, and technical exploration."
    ),
    CreateCreditsSection(
      aboutCreditsFrame,
      "Graphics & Visuals",
      "Certain UI graphics and visual assets were created with the assistance of ChatGPT."
    ),
    CreateCreditsSection(
      aboutCreditsFrame,
      "Additional Support",
      "Thanks to everyone who shared suggestions, bug reports, and ideas during development <3"
    ),
  }
  editor.aboutCreditsSections = creditsSections

  local function UpdateAboutCreditsLayout()
    if not aboutContent or not creditsSections then return end
    if editor and editor.aboutSection and editor.aboutSection ~= "Credits" then return end
    local w = (aboutContent:GetWidth() or 0) - 24
    if w < 220 then w = 220 end
    if w > 620 then w = 620 end

    local y = -26
    for index, section in ipairs(creditsSections) do
      section.header:ClearAllPoints()
      section.header:SetPoint("TOPLEFT", creditsTitle, "TOPLEFT", 0, y)
      section.header:SetWidth(w)
      local hf, _, hflags = section.header:GetFont()
      if hf then section.header:SetFont(hf, 15, hflags) end

      local headerHeight = (section.header.GetStringHeight and section.header:GetStringHeight()) or 22
      y = y - headerHeight - 10

      section.body:ClearAllPoints()
      section.body:SetPoint("TOPLEFT", creditsTitle, "TOPLEFT", 0, y)
      section.body:SetWidth(w)
      local bf, _, bflags = section.body:GetFont()
      if bf then section.body:SetFont(bf, 13, bflags) end
      local bodyHeight = (section.body.GetStringHeight and section.body:GetStringHeight()) or 70
      y = y - bodyHeight

      if section.divider then
        if index < #creditsSections then
          section.divider:Show()
          section.divider:ClearAllPoints()
          section.divider:SetPoint("TOPLEFT", creditsTitle, "TOPLEFT", 0, y - 14)
          section.divider:SetWidth(w)
          y = y - 28
        else
          section.divider:Hide()
        end
      end
    end

    local h = math.max(520, math.floor((-y) + 120))
    if editor and editor.SetAboutContentHeight then
      editor:SetAboutContentHeight(h)
    end
  end
  editor.UpdateAboutCreditsLayout = UpdateAboutCreditsLayout
  SafeHookScript(aboutCreditsFrame, "OnShow", UpdateAboutCreditsLayout)
  SafeHookScript(aboutContent, "OnSizeChanged", UpdateAboutCreditsLayout)

  local aboutStressFrame = CreateFrame("Frame", nil, aboutContent)
  aboutStressFrame:SetAllPoints(aboutContent)
  aboutStressFrame:Hide()
  editor.aboutStressFrame = aboutStressFrame

  local stressTitle = MakeAboutTitle(aboutStressFrame, "Stresstest", 0, 0)
  editor.aboutStressTitle = stressTitle

  local stressContainer = CreateFrame("Frame", nil, aboutStressFrame)
  stressContainer:SetPoint("TOPLEFT", stressTitle, "BOTTOMLEFT", 0, -8)
  stressContainer:SetPoint("TOPRIGHT", aboutStressFrame, "TOPRIGHT", -10, -8)
  stressContainer:SetHeight(10)
  editor.aboutStressContainer = stressContainer

  local STRESS_ENTRIES = {
    {
      version = "Version 1.0.0",
      sections = {
        { title = "CPU", bullets = {
            "Base AddOn: ~0.0%",
        } },
        { title = "Unicolor / Gradient / Background / Textures / Icons", bullets = {
            "20 active static Panels: ~0.0%",
            "50 active static Panels: ~0.0%",
            "100 active static Panels: ~0.0%",
            "150 active static Panels: ~0.0%",
        } },
        { title = "Models (All over the screen)", bullets = {
            "10 active animated Panels: ~0.3%",
        } },
        { title = "FPS", bullets = {
            "150 active static panels: ~ -7 FPS",
            "10 active animated panels: ~ -60 to -70 FPS",
        } },
        { title = "Summary", bullets = {
            "Static panels have a minor FPS impact. Around 20 panels in a normal UI are estimated at roughly -1 FPS overall.",
            "Animated model panels can have a major FPS impact depending on the model type and panel size.",
            "A panel using Stats information also has a small impact because it updates live.",
            "A panel using the live FPS graph has a moderate impact that depends strongly on the update frequency. A 0.1s update interval is heavier than 1.0s.",
        } },
        { title = "General Notes", bullets = {
            "Exact values vary by hardware, FPS, combat conditions, and addon stack.",
            "Only panels from the currently active profile are evaluated.",
        } },
      },
    },
  }

  local stressLines = {}
  local stressDividers = {}

  local function GetStressLine(index)
    local fs = stressLines[index]
    if not fs then
      fs = stressContainer:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
      fs:SetJustifyH("LEFT")
      stressLines[index] = fs
    end
    return fs
  end

  local function GetStressDivider(index)
    local tx = stressDividers[index]
    if not tx then
      tx = stressContainer:CreateTexture(nil, "ARTWORK")
      tx:SetColorTexture(1, 1, 1, 0.14)
      tx:SetHeight(1)
      stressDividers[index] = tx
    end
    return tx
  end

  local function HideUnusedStress(fromLine, fromDivider)
    for i = fromLine, #stressLines do stressLines[i]:Hide() end
    for i = fromDivider, #stressDividers do stressDividers[i]:Hide() end
  end

  local function UpdateStressText()
    local width = (aboutContent:GetWidth() or 560) - 14
    if width < 220 then width = 220 end
    local lineIndex, dividerIndex, y = 1, 1, 0

    for _, entry in ipairs(STRESS_ENTRIES) do
      local divider = GetStressDivider(dividerIndex); dividerIndex = dividerIndex + 1
      divider:ClearAllPoints()
      divider:SetPoint("TOPLEFT", stressContainer, "TOPLEFT", 0, y)
      divider:SetWidth(width)
      divider:Show()
      y = y - 12

      local versionLine = GetStressLine(lineIndex); lineIndex = lineIndex + 1
      versionLine:ClearAllPoints()
      versionLine:SetPoint("TOPLEFT", stressContainer, "TOPLEFT", 0, y)
      versionLine:SetWidth(width)
      versionLine:SetText(entry.version or "")
      local vf, _, vflags = versionLine:GetFont()
      versionLine:SetFont(vf, 16, vflags)
      versionLine:SetTextColor(titleR, titleG, titleB, titleA)
      versionLine:Show()
      y = y - ((versionLine:GetStringHeight() or 0) + 8)

      for _, note in ipairs(entry.notes or {}) do
        local noteLine = GetStressLine(lineIndex); lineIndex = lineIndex + 1
        noteLine:ClearAllPoints()
        noteLine:SetPoint("TOPLEFT", stressContainer, "TOPLEFT", 0, y)
        noteLine:SetWidth(width)
        noteLine:SetText(note)
        local nf, _, nflags = noteLine:GetFont()
        noteLine:SetFont(nf, 13, nflags)
        noteLine:SetTextColor(0.9, 0.9, 0.9, 1)
        noteLine:Show()
        y = y - ((noteLine:GetStringHeight() or 0) + 6)
      end

      for _, section in ipairs(entry.sections or {}) do
        local sectionLine = GetStressLine(lineIndex); lineIndex = lineIndex + 1
        sectionLine:ClearAllPoints()
        sectionLine:SetPoint("TOPLEFT", stressContainer, "TOPLEFT", 0, y)
        sectionLine:SetWidth(width)
        sectionLine:SetText(section.title or "")
        local sf, _, sflags = sectionLine:GetFont()
        sectionLine:SetFont(sf, 14, sflags)
        sectionLine:SetTextColor(titleR, titleG, titleB, titleA)
        sectionLine:Show()
        y = y - ((sectionLine:GetStringHeight() or 0) + 4)

        for _, bulletText in ipairs(section.bullets or {}) do
          local bulletLine = GetStressLine(lineIndex); lineIndex = lineIndex + 1
          bulletLine:ClearAllPoints()
          bulletLine:SetPoint("TOPLEFT", stressContainer, "TOPLEFT", 8, y)
          bulletLine:SetWidth(width - 8)
          bulletLine:SetText(string.char(226, 128, 162) .. " " .. tostring(bulletText))
          local bf, _, bflags = bulletLine:GetFont()
          bulletLine:SetFont(bf, 13, bflags)
          bulletLine:SetTextColor(0.9, 0.9, 0.9, 1)
          bulletLine:Show()
          y = y - ((bulletLine:GetStringHeight() or 0) + 2)
        end
        y = y - 6
      end
      y = y - 8
    end

    HideUnusedStress(lineIndex, dividerIndex)
    stressContainer:SetHeight(math.max(40, -y + 6))
  end

  local function UpdateAboutStressLayout()
    if not aboutContent or not stressContainer then return end
    if editor and editor.aboutSection and editor.aboutSection ~= "Stresstest" then return end
    UpdateStressText()
    local h = stressContainer:GetHeight() or 400
    if editor and editor.SetAboutContentHeight then
      editor:SetAboutContentHeight(math.max(520, math.floor(h + 140)))
    end
  end
  editor.UpdateAboutStressLayout = UpdateAboutStressLayout
  SafeHookScript(aboutStressFrame, "OnShow", UpdateAboutStressLayout)
  SafeHookScript(aboutContent, "OnSizeChanged", UpdateAboutStressLayout)

  local aboutTutorialImagesFrame = CreateFrame("Frame", nil, aboutContent)
  aboutTutorialImagesFrame:SetAllPoints(aboutContent)
  aboutTutorialImagesFrame:Hide()
  editor.aboutTutorialImagesFrame = aboutTutorialImagesFrame

  local aboutTutorialImagesTitle = MakeAboutTitle(aboutTutorialImagesFrame, "Disable Tutorial Images", 0, 0)
  editor.aboutTutorialImagesTitle = aboutTutorialImagesTitle

  local aboutTutorialImagesText = aboutTutorialImagesFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
  aboutTutorialImagesText:SetPoint("TOPLEFT", aboutTutorialImagesTitle, "BOTTOMLEFT", 0, -8)
  aboutTutorialImagesText:SetWidth(560)
  aboutTutorialImagesText:SetJustifyH("LEFT")
  aboutTutorialImagesText:SetText(
    "Use this option if you want to save disk space by deleting tutorial images.\n\n" ..
    "Folder: Interface\\AddOns\\LidPanels\\Media\\Lidpanels\\Tutorials\n\n" ..
    "If that folder or files are missing, WoW may show green placeholder boxes.\n" ..
    "Set mode to Disabled to stop loading tutorial images and keep cards transparent."
  )
  editor.aboutTutorialImagesText = aboutTutorialImagesText

  local aboutTutorialImagesModeHeader = MakeYellowSubHeader(aboutTutorialImagesFrame, "Mode", 0, -164)
  editor.aboutTutorialImagesModeHeader = aboutTutorialImagesModeHeader

  local aboutTutorialImagesToggleBtn = CreateFrame("Button", nil, aboutTutorialImagesFrame, "UIPanelButtonTemplate")
  aboutTutorialImagesToggleBtn:SetSize(110, 20)
  aboutTutorialImagesToggleBtn:SetPoint("TOPLEFT", aboutTutorialImagesModeHeader, "BOTTOMLEFT", 0, -8)
  editor.aboutTutorialImagesToggleBtn = aboutTutorialImagesToggleBtn

  local aboutTutorialImagesState = aboutTutorialImagesFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
  aboutTutorialImagesState:SetPoint("TOPLEFT", aboutTutorialImagesToggleBtn, "BOTTOMLEFT", 0, -8)
  aboutTutorialImagesState:SetWidth(560)
  aboutTutorialImagesState:SetJustifyH("LEFT")
  editor.aboutTutorialImagesState = aboutTutorialImagesState

  local function RefreshTutorialImagesSection()
    local root = RootDB()
    root.ui = root.ui or {}
    local disabled = root.ui.disableTutorialImages == true
    if aboutTutorialImagesToggleBtn then
      aboutTutorialImagesToggleBtn:SetText(disabled and "Disabled" or "Enabled")
    end
    if aboutTutorialImagesState then
      if disabled then
        aboutTutorialImagesState:SetText("Tutorial images are not loaded")
        aboutTutorialImagesState:SetTextColor(1.0, 0.78, 0.78, 1.0)
      else
        aboutTutorialImagesState:SetText("Tutorial images are currently shown")
        aboutTutorialImagesState:SetTextColor(0.82, 0.92, 0.82, 1.0)
      end
    end
  end
  editor.RefreshTutorialImagesSection = RefreshTutorialImagesSection

  aboutTutorialImagesToggleBtn:SetScript("OnClick", function()
    local root = RootDB()
    root.ui = root.ui or {}
    root.ui.disableTutorialImages = not (root.ui.disableTutorialImages == true)
    RefreshTutorialImagesSection()
    if editor and editor.ApplyTutorialTextureMode then editor:ApplyTutorialTextureMode() end
    if editor and editor.LayoutTutorial then editor:LayoutTutorial() end
    if editor and editor.LayoutNoPanel then editor:LayoutNoPanel() end
    if editor and editor.LayoutProfileWelcome then editor:LayoutProfileWelcome() end
  end)

  local function UpdateAboutTutorialImagesLayout()
    if not aboutContent or not aboutTutorialImagesText then return end
    if editor and editor.aboutSection and editor.aboutSection ~= "TutorialImages" then return end
    local w = (aboutContent:GetWidth() or 0) - 10
    if w < 200 then w = 200 end
    aboutTutorialImagesText:SetWidth(w)
    if aboutTutorialImagesState then
      aboutTutorialImagesState:SetWidth(math.max(220, w - 40))
    end
    local t1 = (aboutTutorialImagesText.GetStringHeight and aboutTutorialImagesText:GetStringHeight()) or 120
    local t2 = (aboutTutorialImagesState and aboutTutorialImagesState.GetStringHeight and aboutTutorialImagesState:GetStringHeight()) or 20
    if editor and editor.SetAboutContentHeight then
      editor:SetAboutContentHeight(math.max(520, math.floor(t1 + t2 + 230)))
    end
  end
  editor.UpdateAboutTutorialImagesLayout = UpdateAboutTutorialImagesLayout
  SafeHookScript(aboutTutorialImagesFrame, "OnShow", function()
    if editor and editor.RefreshTutorialImagesSection then editor:RefreshTutorialImagesSection() end
    UpdateAboutTutorialImagesLayout()
  end)
  SafeHookScript(aboutContent, "OnSizeChanged", UpdateAboutTutorialImagesLayout)

  local aboutDeveloperFrame = CreateFrame("Frame", nil, aboutContent)
  aboutDeveloperFrame:SetAllPoints(aboutContent)
  aboutDeveloperFrame:Hide()
  editor.aboutDeveloperFrame = aboutDeveloperFrame

  local aboutDeveloperTitle = MakeAboutTitle(aboutDeveloperFrame, "Developer Mode", 0, 0)
  editor.aboutDeveloperTitle = aboutDeveloperTitle

  local aboutDeveloperText = aboutDeveloperFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
  aboutDeveloperText:SetPoint("TOPLEFT", aboutDeveloperTitle, "BOTTOMLEFT", 0, -8)
  aboutDeveloperText:SetWidth(560)
  aboutDeveloperText:SetJustifyH("LEFT")
  aboutDeveloperText:SetText(
    "Enable chat debugging to show internal trigger logs for SpellID and threshold detection.\n\n" ..
    "Error tracing and silent-error tracing are active only while Developer Mode is enabled."
  )
  editor.aboutDeveloperText = aboutDeveloperText

  local aboutDeveloperModeCheck = CreateFrame("CheckButton", "LIDPANELS_AboutDeveloperModeCheck", aboutDeveloperFrame, "UICheckButtonTemplate")
  aboutDeveloperModeCheck:SetPoint("TOPLEFT", aboutDeveloperText, "BOTTOMLEFT", 0, -10)
  _G[aboutDeveloperModeCheck:GetName() .. "Text"]:SetText("Activate Developer Mode")
  editor.aboutDeveloperModeCheck = aboutDeveloperModeCheck

  local aboutDeveloperState = aboutDeveloperFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
  aboutDeveloperState:SetPoint("TOPLEFT", aboutDeveloperModeCheck, "BOTTOMLEFT", 0, -8)
  aboutDeveloperState:SetWidth(560)
  aboutDeveloperState:SetJustifyH("LEFT")
  editor.aboutDeveloperState = aboutDeveloperState

  local function RefreshDeveloperSection()
    local root = RootDB()
    root.ui = root.ui or {}
    local enabled = root.ui.developerMode == true
    if aboutDeveloperModeCheck then
      aboutDeveloperModeCheck:SetChecked(enabled)
    end
    if aboutDeveloperState then
      if enabled then
        aboutDeveloperState:SetText("Developer Mode is ON.\nSilent-error tracing is active.")
      else
        aboutDeveloperState:SetText("Developer Mode is OFF.\nSilent-error tracing is currently disabled.")
      end
    end
  end
  editor.RefreshDeveloperSection = RefreshDeveloperSection

  aboutDeveloperModeCheck:SetScript("OnClick", function(self)
    local root = RootDB()
    root.ui = root.ui or {}
    local enabled = self:GetChecked() and true or false
    root.ui.developerMode = enabled
    local debugStore = _G.LIDPANELS_Debug
    if not enabled and debugStore then
      debugStore.silent = {}
    end
    RefreshDeveloperSection()
    if editor and editor.RefreshAbout then editor:RefreshAbout() end
  end)

  local function UpdateAboutDeveloperLayout()
    if not aboutContent or not aboutDeveloperText then return end
    if editor and editor.aboutSection and editor.aboutSection ~= "Developer" then return end
    local w = (aboutContent:GetWidth() or 0) - 10
    if w < 200 then w = 200 end
    aboutDeveloperText:SetWidth(w)
    if aboutDeveloperState then aboutDeveloperState:SetWidth(w) end
    local t1 = (aboutDeveloperText.GetStringHeight and aboutDeveloperText:GetStringHeight()) or 80
    local t2 = (aboutDeveloperState and aboutDeveloperState.GetStringHeight and aboutDeveloperState:GetStringHeight()) or 20
    if editor and editor.SetAboutContentHeight then
      editor:SetAboutContentHeight(math.max(520, math.floor(t1 + t2 + 228)))
    end
  end
  editor.UpdateAboutDeveloperLayout = UpdateAboutDeveloperLayout
  SafeHookScript(aboutDeveloperFrame, "OnShow", function()
    if editor and editor.RefreshDeveloperSection then editor:RefreshDeveloperSection() end
    UpdateAboutDeveloperLayout()
  end)
  SafeHookScript(aboutContent, "OnSizeChanged", UpdateAboutDeveloperLayout)
end

INTERNAL_API.LIDPANELS_CreateAboutUtilitySections_Impl = CreateAboutUtilitySections
