local addonName, SinsToolkit = ...

local Components = {}
SinsToolkit.UIComponents = Components

local GOLD = { 0.85, 0.66, 0.29 }
local PURPLE = { 0.72, 0.40, 0.93 }
local GREEN = { 0.10, 0.95, 0.35 }
local RED = { 1.00, 0.28, 0.28 }
local BLUE = { 0.30, 0.62, 1.00 }

local function Theme()
    return SinsToolkit.UI and SinsToolkit.UI.Theme
end

local function ApplyBackdrop(frame, r, g, b, a, br, bg, bb, ba)
    if not frame or not frame.SetBackdrop then return end
    frame:SetBackdrop({
        bgFile = "Interface\\Buttons\\WHITE8X8",
        edgeFile = "Interface\\Buttons\\WHITE8X8",
        edgeSize = 1,
        insets = { left = 1, right = 1, top = 1, bottom = 1 },
    })
    frame:SetBackdropColor(r or 0.02, g or 0.018, b or 0.026, a or 0.96)
    frame:SetBackdropBorderColor(br or PURPLE[1], bg or PURPLE[2], bb or PURPLE[3], ba or 0.85)
end

local function SetFontColor(fontString, color)
    if not fontString or not color then return end
    fontString:SetTextColor(color[1], color[2], color[3])
end

local function HideDialog()
    local frame = Components.dialogFrame
    if frame then frame:Hide() end
    local overlay = Components.dialogOverlay
    if overlay then overlay:Hide() end
end

function Components:StylePanel(frame, variant)
    if variant == "warning" then
        ApplyBackdrop(frame, 0.025, 0.018, 0.018, 0.98, 0.85, 0.24, 0.24, 0.95)
    elseif variant == "soft" then
        ApplyBackdrop(frame, 0.025, 0.022, 0.032, 0.88, 0.32, 0.20, 0.42, 0.72)
    else
        ApplyBackdrop(frame, 0.018, 0.016, 0.024, 0.96, PURPLE[1], PURPLE[2], PURPLE[3], 0.86)
    end
end

function Components:CreateCard(parent, title, icon, width, height)
    local themeApi = Theme()
    local padding = themeApi and themeApi.GetCardPadding and themeApi.GetCardPadding("compact") or 14
    local iconSize = themeApi and themeApi.GetSize and themeApi.GetSize("icon") or { width = 28, height = 28 }
    local card = CreateFrame("Frame", nil, parent, "BackdropTemplate")
    card:SetSize(width or 260, height or 110)
    self:StylePanel(card, "soft")

    if icon then
        card.icon = card:CreateTexture(nil, "ARTWORK")
        card.icon:SetSize(iconSize.width or 28, iconSize.height or 28)
        card.icon:SetPoint("TOPLEFT", padding, -padding)
        card.icon:SetTexture(icon)
    end

    card.title = card:CreateFontString(nil, "OVERLAY", themeApi and themeApi.GetFont and themeApi.GetFont("card_title") or "GameFontNormal")
    card.title:SetPoint("TOPLEFT", icon and card.icon or card, icon and "TOPRIGHT" or "TOPLEFT", icon and 10 or padding, icon and -1 or -padding)
    card.title:SetText(title or "")
    if themeApi and themeApi.ApplyCardTitle then themeApi.ApplyCardTitle(card.title) else SetFontColor(card.title, GOLD) end

    card.body = card:CreateFontString(nil, "OVERLAY", themeApi and themeApi.GetFont and themeApi.GetFont("body_small") or "GameFontHighlightSmall")
    card.body:SetPoint("TOPLEFT", padding, icon and -(padding + 36) or -(padding + 24))
    card.body:SetPoint("RIGHT", -padding, 0)
    card.body:SetJustifyH("LEFT")
    card.body:SetJustifyV("TOP")
    if themeApi and themeApi.ApplySmallBodyFont then themeApi.ApplySmallBodyFont(card.body) end

    return card
end

function Components:CreateSection(parent, title)
    local themeApi = Theme()
    local section = CreateFrame("Frame", nil, parent)
    section:SetSize(320, 30)

    section.title = section:CreateFontString(nil, "OVERLAY", themeApi and themeApi.GetFont and themeApi.GetFont("page_title") or "GameFontNormalLarge")
    section.title:SetPoint("LEFT")
    section.title:SetText(title or "")
    if themeApi and themeApi.ApplyPageTitle then themeApi.ApplyPageTitle(section.title) else SetFontColor(section.title, PURPLE) end

    section.line = section:CreateTexture(nil, "ARTWORK")
    section.line:SetColorTexture(PURPLE[1], PURPLE[2], PURPLE[3], 0.45)
    section.line:SetHeight(1)
    section.line:SetPoint("LEFT", section.title, "RIGHT", 12, 0)
    section.line:SetPoint("RIGHT", section, "RIGHT", 0, 0)

    return section
end

function Components:CreateStatusBadge(parent, text, state)
    local themeApi = Theme()
    local badge = CreateFrame("Frame", nil, parent, "BackdropTemplate")
    badge:SetSize(110, 22)
    self:StylePanel(badge, "soft")

    local color = state == "enabled" and GREEN or state == "disabled" and RED or state == "info" and BLUE or GOLD
    badge:SetBackdropBorderColor(color[1], color[2], color[3], 0.9)

    badge.text = badge:CreateFontString(nil, "OVERLAY", themeApi and themeApi.GetFont and themeApi.GetFont("status_text") or "GameFontHighlightSmall")
    badge.text:SetPoint("CENTER")
    badge.text:SetText(text or "")
    if themeApi and themeApi.ApplyStatusText then themeApi.ApplyStatusText(badge.text) end
    SetFontColor(badge.text, color)

    return badge
end

function Components:CreateActionButton(parent, text, onClick, tooltip, width)
    local themeApi = Theme()
    local size = themeApi and themeApi.GetSize and themeApi.GetSize("button_small") or { width = 150, height = 26 }
    local button = CreateFrame("Button", nil, parent, "UIPanelButtonTemplate")
    button:SetSize(width or 150, size.height or 26)
    button:SetText(text or "OK")
    button:SetScript("OnClick", function(self)
        if onClick then onClick(self) end
    end)
    if tooltip then
        button:SetScript("OnEnter", function(self)
            GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
            GameTooltip:SetText(text or "Action", 1, 0.82, 0)
            GameTooltip:AddLine(tooltip, 1, 1, 1, true)
            GameTooltip:Show()
        end)
        button:SetScript("OnLeave", GameTooltip_Hide)
    end
    return button
end

function Components:CreateWarningPanel(parent, title, body)
    local panel = self:CreateCard(parent, title or "Warning", nil, 360, 120)
    self:StylePanel(panel, "warning")
    panel.body:SetText(body or "")
    return panel
end

local function EnsureDialog()
    if Components.dialogFrame then return Components.dialogFrame end

    local overlay = CreateFrame("Frame", "SinsToolkitDialogOverlay", UIParent, "BackdropTemplate")
    overlay:SetAllPoints(UIParent)
    overlay:SetFrameStrata("FULLSCREEN_DIALOG")
    overlay:SetFrameLevel(8990)
    overlay:EnableMouse(true)
    ApplyBackdrop(overlay, 0, 0, 0, 0.35, 0, 0, 0, 0)
    overlay:Hide()
    Components.dialogOverlay = overlay

    local frame = CreateFrame("Frame", "SinsToolkitDialogFrame", UIParent, "BackdropTemplate")
    frame:SetSize(480, 320)
    frame:SetPoint("CENTER")
    frame:SetFrameStrata("FULLSCREEN_DIALOG")
    frame:SetFrameLevel(9000)
    frame:SetToplevel(true)
    frame:SetMovable(true)
    frame:EnableMouse(true)
    frame:RegisterForDrag("LeftButton")
    frame:SetScript("OnDragStart", frame.StartMoving)
    frame:SetScript("OnDragStop", frame.StopMovingOrSizing)
    Components:StylePanel(frame)

    frame.title = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    frame.title:SetPoint("TOPLEFT", 24, -22)
    frame.title:SetPoint("TOPRIGHT", -24, -22)
    frame.title:SetJustifyH("CENTER")
    local themeApi = Theme()
    if themeApi and themeApi.ApplyPageTitle then themeApi.ApplyPageTitle(frame.title) else SetFontColor(frame.title, GOLD) end

    frame.body = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    frame.body:SetPoint("TOPLEFT", 30, -62)
    frame.body:SetPoint("TOPRIGHT", -30, -62)
    frame.body:SetJustifyH("LEFT")
    frame.body:SetJustifyV("TOP")
    if themeApi and themeApi.ApplyBodyFont then themeApi.ApplyBodyFont(frame.body) end

    frame.checkbox = CreateFrame("CheckButton", "SinsToolkitDialogCheckbox", frame, "ChatConfigCheckButtonTemplate")
    frame.checkbox:SetPoint("BOTTOMLEFT", 24, 18)
    frame.checkbox:Hide()

    frame.buttons = {}
    for i = 1, 3 do
        local button = Components:CreateActionButton(frame, "")
        button:Hide()
        frame.buttons[i] = button
    end

    frame.close = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
    frame.close:SetPoint("TOPRIGHT", -4, -4)
    frame.close:SetScript("OnClick", HideDialog)

    frame:Hide()
    Components.dialogFrame = frame
    return frame
end

function Components:ShowDialog(options)
    options = options or {}
    local frame = EnsureDialog()
    local overlay = self.dialogOverlay

    frame:SetSize(options.width or 500, options.height or 340)
    frame:ClearAllPoints()
    frame:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
    frame.title:SetText(options.title or "Sin's Toolkit")
    frame.body:SetText(options.body or "")

    if options.variant == "warning" then
        self:StylePanel(frame, "warning")
    else
        self:StylePanel(frame)
    end

    for _, button in ipairs(frame.buttons) do
        button:Hide()
        button:SetScript("OnClick", nil)
    end

    local buttons = options.buttons or { { text = "OK" } }
    local buttonWidth = options.buttonWidth or 128
    local spacing = 12
    local total = (#buttons * buttonWidth) + ((#buttons - 1) * spacing)
    local startX = -(total / 2) + (buttonWidth / 2)

    for index, spec in ipairs(buttons) do
        local button = frame.buttons[index]
        if button then
            button:SetSize(buttonWidth, 26)
            button:SetText(spec.text or "OK")
            button:ClearAllPoints()
            button:SetPoint("BOTTOM", frame, "BOTTOM", startX + ((index - 1) * (buttonWidth + spacing)), 18)
            button:SetScript("OnClick", function()
                if spec.onClick then spec.onClick(frame) end
                if spec.close ~= false then HideDialog() end
            end)
            button:Show()
        end
    end

    if options.checkboxText then
        frame.checkbox:Show()
        frame.checkbox:SetChecked(options.checkboxGet and options.checkboxGet() or false)
        _G.SinsToolkitDialogCheckboxText:SetText(options.checkboxText)
        frame.checkbox:SetScript("OnClick", function(self)
            if options.checkboxSet then options.checkboxSet(self:GetChecked()) end
        end)
    else
        frame.checkbox:Hide()
    end

    if options.modal then
        overlay:Show()
    else
        overlay:Hide()
    end

    frame:SetFrameStrata("FULLSCREEN_DIALOG")
    frame:SetFrameLevel(9000)
    frame:SetToplevel(true)
    frame:Show()
    frame:Raise()
    return frame
end

function Components:ShowWarningDialog(options)
    options = options or {}
    options.variant = "warning"
    options.modal = options.modal ~= false
    return self:ShowDialog(options)
end

function Components:ShowConfirmationDialog(options)
    options = options or {}
    options.modal = options.modal ~= false
    return self:ShowDialog(options)
end

function Components:ShowNotification(options)
    options = options or {}
    options.modal = options.modal == true
    return self:ShowDialog(options)
end

_G.STK_CreateCard = function(...) return Components:CreateCard(...) end
_G.STK_CreateSection = function(...) return Components:CreateSection(...) end
_G.STK_CreateStatusBadge = function(...) return Components:CreateStatusBadge(...) end
_G.STK_CreateActionButton = function(...) return Components:CreateActionButton(...) end
_G.STK_CreateWarningPanel = function(...) return Components:CreateWarningPanel(...) end
_G.STK_ShowDialog = function(...) return Components:ShowDialog(...) end
_G.STK_ShowWarningDialog = function(...) return Components:ShowWarningDialog(...) end
_G.STK_ShowConfirmationDialog = function(...) return Components:ShowConfirmationDialog(...) end
_G.STK_ShowNotification = function(...) return Components:ShowNotification(...) end
