GuildHelper = GuildHelper or {}

local addon = GuildHelper

addon.NewUIComponents = addon.NewUIComponents or {}

local components = addon.NewUIComponents

local function getThemeColors()
    local theme = addon.NewUITheme or {}
    local shell = theme.Shell or {}
    local default = theme.Default or {}
    return shell, default
end

local function resolveTexturePath(textureKeyOrPath)
    if type(textureKeyOrPath) ~= "string" or textureKeyOrPath == "" then
        return nil
    end

    local textures = addon.NewUIAssets and addon.NewUIAssets.Textures or nil
    if textures and textures[textureKeyOrPath] ~= nil then
        return textures[textureKeyOrPath] ~= "" and textures[textureKeyOrPath] or nil
    end

    return textureKeyOrPath
end

local function buildBackdropOptions(options, fallback)
    if type(options) ~= "table" then
        return fallback
    end

    if options.backdrop then
        return options.backdrop
    end

    local bgFile = resolveTexturePath(options.backgroundTextureKey or options.backgroundTexturePath)
    local edgeFile = resolveTexturePath(options.borderTextureKey or options.borderTexturePath)

    if not bgFile and not edgeFile then
        return fallback
    end

    return {
        bgFile = bgFile or fallback.bgFile,
        edgeFile = edgeFile or fallback.edgeFile,
        tile = fallback.tile,
        tileSize = fallback.tileSize,
        edgeSize = fallback.edgeSize,
        insets = fallback.insets,
    }
end

function components.ApplyRect(frame, parent, rect)
    if not frame or not parent or not rect then
        return frame
    end

    frame:ClearAllPoints()
    frame:SetPoint("TOPLEFT", parent, "TOPLEFT", rect.x or 0, rect.y or 0)
    frame:SetSize(rect.w or 0, rect.h or 0)
    return frame
end

function components.CreatePageRoot(parent)
    local root = CreateFrame("Frame", nil, parent)
    root:SetAllPoints(parent)
    return root
end

function components.CreatePanel(parent, rect, title, options)
    local panel = CreateFrame("Frame", nil, parent, BackdropTemplateMixin and "BackdropTemplate" or nil)
    components.ApplyRect(panel, parent, rect or { x = 0, y = 0, w = 0, h = 0 })

    local shellTheme, defaultTheme = getThemeColors()
    local panelTheme = (defaultTheme and defaultTheme.Panel) or {}
    local insets = (addon.NewUIAssets and addon.NewUIAssets.Insets and addon.NewUIAssets.Insets.Panel) or { left = 24, right = 24, top = 48, bottom = 20 }
    local fallbackBackdrop = {
        bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true,
        tileSize = 16,
        edgeSize = 16,
        insets = insets,
    }
    local backdrop = buildBackdropOptions(options, fallbackBackdrop)

    panel:SetBackdrop(backdrop)
    panel:SetBackdropColor(unpack(panelTheme.Background or { 0.12, 0.12, 0.14, 0.98 }))
    panel:SetBackdropBorderColor(unpack(panelTheme.Border or shellTheme.Border or { 0.34, 0.34, 0.4, 1 }))

    local titleText = panel:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    titleText:SetPoint("TOPLEFT", 24, -18)
    titleText:SetText(title or "")
    titleText:SetTextColor(unpack(panelTheme.Title or shellTheme.Text or { 0.96, 0.93, 0.84, 1 }))
    panel.TitleText = titleText

    local content = CreateFrame("Frame", nil, panel)
    content:SetPoint("TOPLEFT", 24, -48)
    content:SetPoint("BOTTOMRIGHT", -24, 20)
    panel.Content = content

    return panel
end

function components.CreateButton(parent, rect, text, options)
    local button = CreateFrame("Button", nil, parent, BackdropTemplateMixin and "BackdropTemplate" or nil)
    components.ApplyRect(button, parent, rect or { x = 0, y = 0, w = 0, h = 0 })
    options = type(options) == "table" and options or nil

    local shellTheme, defaultTheme = getThemeColors()
    local buttonTheme = (defaultTheme and defaultTheme.Button) or {}
    local fallbackBackdrop = {
        bgFile = "Interface\\Buttons\\WHITE8X8",
        edgeFile = "Interface\\Buttons\\WHITE8X8",
        tile = false,
        tileSize = 0,
        edgeSize = 1,
        insets = { left = 1, right = 1, top = 1, bottom = 1 },
    }

    if button.SetBackdrop and options then
        local backdrop = buildBackdropOptions(options, fallbackBackdrop)
        if backdrop ~= fallbackBackdrop or options.backdrop then
            button:SetBackdrop(backdrop)
            button:SetBackdropColor(unpack(buttonTheme.Background or { 0.12, 0.12, 0.14, 0.98 }))
            button:SetBackdropBorderColor(unpack(buttonTheme.Border or shellTheme.Border or { 0.34, 0.34, 0.4, 1 }))
        end
    end

    local font = button:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    font:SetPoint("CENTER")
    font:SetText(text or "")
    button.Text = font

    if options and type(options.onClick) == "function" then
        button:SetScript("OnClick", function()
            options.onClick(button)
        end)
    end

    return button
end

function components.CreateTabButton(parent, rect, text, selected, onClick, options)
    local button = components.CreateButton(parent, rect, text, options)
    button.selected = selected and true or false
    button:SetScript("OnClick", function()
        if onClick then
            onClick()
        end
    end)
    return button
end

function components.CreateFieldRow(contentFrame, y, label, value, options)
    if not contentFrame then
        return nil
    end

    options = options or {}

    local x = options.x or 0
    local labelW = options.labelW or 110
    local valueW = options.valueW or 220
    local rowH = options.rowH or options.height or 18
    local gap = options.gap or 8

    local row = CreateFrame("Frame", nil, contentFrame)
    row:SetPoint("TOPLEFT", contentFrame, "TOPLEFT", x, y or 0)
    row:SetSize(labelW + gap + valueW, rowH)

    local labelText = row:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    labelText:SetPoint("TOPLEFT", row, "TOPLEFT", 0, 0)
    labelText:SetSize(labelW, rowH)
    labelText:SetJustifyH("LEFT")
    labelText:SetWordWrap(false)
    labelText:SetText(label or "")
    if options.labelColor then
        labelText:SetTextColor(unpack(options.labelColor))
    end

    local valueText = row:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    valueText:SetPoint("TOPLEFT", row, "TOPLEFT", labelW + gap, 0)
    valueText:SetSize(valueW, rowH)
    valueText:SetJustifyH("LEFT")
    valueText:SetWordWrap(false)
    valueText:SetText(value or "")
    if options.valueColor then
        valueText:SetTextColor(unpack(options.valueColor))
    end

    row.LabelText = labelText
    row.ValueText = valueText
    return row
end

return components