local addonName, ns = ...
-- ApiVault Reports workflow panel for AppShell. Added in v1.3.5 Interface Clarity Phase 4.
-- Copyable report hub only. No runtime source file reads and no protected/secure execution.
local ApiVault = ns

ApiVault.ReportsPanel = ApiVault.ReportsPanel or {}
local Panel = ApiVault.ReportsPanel

local function trim(value)
    value = tostring(value or "")
    return (value:gsub("^%s+", ""):gsub("%s+$", ""))
end

local function append(lines, value)
    table.insert(lines, tostring(value or ""))
end

local function createText(parent, template)
    local fs = parent:CreateFontString(nil, "OVERLAY", template or "GameFontNormal")
    fs:SetJustifyH("LEFT")
    fs:SetJustifyV("TOP")
    return fs
end

local function createBackdropFrame(name, parent)
    return CreateFrame("Frame", name, parent, BackdropTemplateMixin and "BackdropTemplate" or nil)
end

local function setBackdrop(frame)
    if not frame.SetBackdrop then return end
    frame:SetBackdrop({
        bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true,
        tileSize = 16,
        edgeSize = 12,
        insets = { left = 4, right = 4, top = 4, bottom = 4 },
    })
    frame:SetBackdropColor(0.02, 0.02, 0.03, 0.86)
end

local function createButton(parent, label, width, anchor, x, y, onClick)
    local button = CreateFrame("Button", nil, parent, "UIPanelButtonTemplate")
    button:SetSize(width or 100, 22)
    if anchor and anchor.GetObjectType then
        button:SetPoint("LEFT", anchor, "RIGHT", x or 6, y or 0)
    else
        button:SetPoint("TOPLEFT", parent, "TOPLEFT", x or 20, y or -20)
    end
    button:SetText(label)
    button:SetScript("OnClick", onClick)
    return button
end

function Panel:Clear(parent)
    if parent.ApiVaultReportsChildren then
        for _, child in ipairs(parent.ApiVaultReportsChildren) do
            if child.Hide then child:Hide() end
            if child.SetParent then child:SetParent(nil) end
        end
    end
    parent.ApiVaultReportsChildren = {}
end

function Panel:Add(parent, child)
    parent.ApiVaultReportsChildren = parent.ApiVaultReportsChildren or {}
    table.insert(parent.ApiVaultReportsChildren, child)
    return child
end

function Panel:GetInput()
    return trim(self.input and self.input:GetText() or "")
end

function Panel:SetOutput(text)
    if self.output then
        if ApiVault.CapOutputText then text = ApiVault:CapOutputText(text) end
        self.output:SetText(tostring(text or ""))
        self.output:SetCursorPosition(0)
    end
end

function Panel:EmptyState()
    if ApiVault.EmptyState and ApiVault.EmptyState.Build then
        return ApiVault.EmptyState:Build("Reports V2", {
            "Copyable report hub for session exports, addon reports, error reports, audit output and developer checklists.",
            "Policy badges: [COPYABLE] [READ-ONLY] [INSPECT-ONLY] [NO-RUNTIME-FILE-READS]",
        }, {
            "No report type has been selected yet.",
            "Some report modules may be unavailable depending on TOC load order.",
        }, {
            "Type an addon name or filter when needed.",
            "Click Session Export, Addon Report, Error Report or a checklist button.",
            "Use Select Output, then Ctrl+C to copy.",
        })
    end
    return "Reports V2\n\nSelect a report type."
end

function Panel:BuildSessionExport()
    if ApiVault.DeveloperSessionExport and ApiVault.DeveloperSessionExport.BuildReport then
        return ApiVault.DeveloperSessionExport:BuildReport()
    end
    return "Session export unavailable."
end

function Panel:BuildAddonReport()
    local query = self:GetInput()
    if query == "" then
        return "No addon context.\n\nType an addon name such as StockVault, then click Addon Report."
    end
    if ApiVault.AddonLookup and ApiVault.AddonLookup.FormatAddonReport then
        return ApiVault.AddonLookup:FormatAddonReport(query)
    end
    return "Addon lookup unavailable."
end

function Panel:BuildErrorReport()
    local filter = self:GetInput()
    local lines = {}
    append(lines, "ApiVault Error Report")
    append(lines, "=====================")
    append(lines, "Badges: [LIVE] [READ-ONLY] [ERROR-INBOX]")
    append(lines, "filter: " .. tostring(filter ~= "" and filter or "<all>"))
    append(lines, "")
    if ApiVault.ErrorInbox and ApiVault.ErrorInbox.FormatList then
        append(lines, ApiVault.ErrorInbox:FormatList(filter))
    else
        append(lines, "Error Inbox unavailable.")
    end
    local record = ApiVault.ErrorInbox and ApiVault.ErrorInbox.GetLatestMatch and ApiVault.ErrorInbox:GetLatestMatch(filter) or nil
    if record and ApiVault.ErrorInbox and ApiVault.ErrorInbox.Explain then
        append(lines, "")
        append(lines, "------------------------------")
        append(lines, ApiVault.ErrorInbox:Explain(record))
        if ApiVault.ErrorInbox.CopyGitHubIssue then
            append(lines, "")
            append(lines, "------------------------------")
            append(lines, ApiVault.ErrorInbox:CopyGitHubIssue(record))
        end
    else
        append(lines, "")
        append(lines, "No matching error explanation available.")
        append(lines, "Possible reasons: no captured errors, filter mismatch, or bridge loaded after the error occurred.")
    end
    return table.concat(lines, "\n")
end

function Panel:BuildLastAudit()
    if ApiVault.AddonAudit and ApiVault.AddonAudit.GetLastReportText then
        return ApiVault.AddonAudit:GetLastReportText()
    end
    return "No AddonAudit report available. Run /av audit first, paste code, and click Auto Detect."
end

function Panel:BuildChecklist(kind)
    if ApiVault.ChecklistExport and ApiVault.ChecklistExport.Build then
        return ApiVault.ChecklistExport:Build(kind)
    end
    return "Checklist export unavailable."
end

function Panel:BuildTaintChecklist()
    local text = self:GetInput()
    if text ~= "" and ApiVault.TaintCombatSafetyAssistant and ApiVault.TaintCombatSafetyAssistant.FormatReport then
        return ApiVault.TaintCombatSafetyAssistant:FormatReport(text)
    end
    return self:BuildChecklist("secure-checklist")
end

function Panel:BuildPackageReport()
    local text = self:GetInput()
    if text ~= "" and ApiVault.AddonPackageValidator and ApiVault.AddonPackageValidator.FormatReport then
        return ApiVault.AddonPackageValidator:FormatReport(text)
    end
    return self:BuildChecklist("toc-checklist")
end

function Panel:Run(kind)
    if kind == "session" then
        self:SetOutput(self:BuildSessionExport())
    elseif kind == "addon" then
        self:SetOutput(self:BuildAddonReport())
    elseif kind == "error" then
        self:SetOutput(self:BuildErrorReport())
    elseif kind == "last-audit" then
        self:SetOutput(self:BuildLastAudit())
    elseif kind == "api-summary" then
        self:SetOutput(self:BuildChecklist("api-summary"))
    elseif kind == "secure-checklist" then
        self:SetOutput(self:BuildTaintChecklist())
    elseif kind == "package" then
        self:SetOutput(self:BuildPackageReport())
    elseif kind == "test-checklist" then
        self:SetOutput(self:BuildChecklist("test-checklist"))
    else
        self:SetOutput(self:EmptyState())
    end
end

function Panel:SelectOutput()
    if self.output then
        self.output:SetFocus()
        self.output:HighlightText()
    end
end

function Panel:OpenLegacyExport()
    if ApiVault.ExportPanel and ApiVault.ExportPanel.OpenWithContext then
        ApiVault.ExportPanel:OpenWithContext(nil, "test-checklist")
        self:SetOutput("[LEGACY PANEL]\nOpened the standalone Export panel.\n\nReports V2 remains the primary cockpit workflow for /av reports.")
    elseif ApiVault.DeveloperMustHaveToolsPanel and ApiVault.DeveloperMustHaveToolsPanel.Open then
        ApiVault.DeveloperMustHaveToolsPanel:Open("export")
        self:SetOutput("[LEGACY PANEL]\nOpened Developer Tools session export fallback.")
    else
        self:SetOutput("Legacy export panel unavailable.")
    end
end

function Panel:Render(parent)
    self:Clear(parent)

    if ApiVault.Header and ApiVault.Header.Render then
        ApiVault.Header:Render(self, parent, "Reports V2", "Copyable report hub for session exports, addon reports, error reports, audit output and developer checklists.", {"COPYABLE", "READ-ONLY", "INSPECT-ONLY", "NO-RUNTIME-FILE-READS"})
    else
        local title = self:Add(parent, createText(parent, "GameFontHighlightLarge"))
        title:SetPoint("TOPLEFT", parent, "TOPLEFT", 20, -18)
        title:SetText("Reports V2")
    end

    local input = self:Add(parent, CreateFrame("EditBox", nil, parent, "InputBoxTemplate"))
    self.input = input
    input:SetSize(360, 24)
    input:SetPoint("TOPLEFT", parent, "TOPLEFT", 20, -90)
    input:SetAutoFocus(false)
    input:SetText("")
    input:SetScript("OnEnterPressed", function(box)
        box:ClearFocus()
        Panel:Run("addon")
    end)

    local session = self:Add(parent, createButton(parent, "Session Export", 116, input, 10, 0, function() Panel:Run("session") end))
    local addon = self:Add(parent, createButton(parent, "Addon Report", 108, session, 6, 0, function() Panel:Run("addon") end))
    local errorReport = self:Add(parent, createButton(parent, "Error Report", 104, addon, 6, 0, function() Panel:Run("error") end))

    local lastAudit = self:Add(parent, createButton(parent, "Last Audit", 90, nil, 20, -124, function() Panel:Run("last-audit") end))
    local apiSummary = self:Add(parent, createButton(parent, "API Summary", 104, lastAudit, 6, 0, function() Panel:Run("api-summary") end))
    local secure = self:Add(parent, createButton(parent, "Secure Checklist", 124, apiSummary, 6, 0, function() Panel:Run("secure-checklist") end))
    local package = self:Add(parent, createButton(parent, "Package", 82, secure, 6, 0, function() Panel:Run("package") end))
    local test = self:Add(parent, createButton(parent, "Test Checklist", 114, package, 6, 0, function() Panel:Run("test-checklist") end))

    local selectOut = self:Add(parent, createButton(parent, "Select Output", 108, nil, 20, -154, function() Panel:SelectOutput() end))
    local clear = self:Add(parent, createButton(parent, "Clear", 70, selectOut, 6, 0, function() input:SetText(""); Panel:SetOutput(Panel:EmptyState()) end))
    self:Add(parent, createButton(parent, "Legacy Export", 108, clear, 6, 0, function() Panel:OpenLegacyExport() end))

    local bg = self:Add(parent, createBackdropFrame(nil, parent))
    bg:SetPoint("TOPLEFT", parent, "TOPLEFT", 20, -190)
    bg:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT", -20, 20)
    setBackdrop(bg)

    local scroll = self:Add(parent, CreateFrame("ScrollFrame", nil, bg, "UIPanelScrollFrameTemplate"))
    scroll:SetPoint("TOPLEFT", bg, "TOPLEFT", 12, -12)
    scroll:SetPoint("BOTTOMRIGHT", bg, "BOTTOMRIGHT", -30, 12)

    local output = self:Add(parent, CreateFrame("EditBox", nil, scroll))
    self.output = output
    output:SetMultiLine(true)
    output:SetAutoFocus(false)
    output:SetFontObject(ChatFontNormal)
    output:SetWidth(720)
    output:SetText(self:EmptyState())
    output:SetScript("OnEscapePressed", function(box) box:ClearFocus() end)
    scroll:SetScrollChild(output)

    parent:SetScript("OnSizeChanged", function()
        if output and bg then output:SetWidth(math.max(520, bg:GetWidth() - 50)) end
    end)
end
