local fontPath = "Interface/AddOns/WoWStudy/Fonts/NotoSansCJK-Medium.ttc"

StaticPopupDialogs["WOWSTUDY_CONFIRM_DELETE_CARD"] = {
    text = "Are you sure you want to delete this card?",
    button1 = "Yes",
    button2 = "No",
    OnAccept = function(self, data)
        -- 'data' will contain question
        local question = data.question
        local deck     = data.deck

        -- Delete the card
        WoWStudySaved.decks[deck].cardsByQuestion[question] = nil
        WoWStudyFunction.RefreshStatsPanel()
    end,
    OnCancel = function(self)
        -- Do nothing; user canceled
    end,
    timeout = 0,
    whileDead = true,
    hideOnEscape = true,
    preferredIndex = 3,
}

function WoWStudyFunction.SetupFlashcardStatsPanel(menuFrame, menuPanel2)
    local flashcardStatsPanel = CreateFrame("Frame", "WoWStudyFlashcardStatsPanel", menuFrame, "ShadowOverlayTemplate")
    flashcardStatsPanel:SetPoint("LEFT", menuPanel2, "RIGHT", 10, 0)
    flashcardStatsPanel:SetSize(600, 489)
    flashcardStatsPanel:Hide()

    local title = flashcardStatsPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    title:SetPoint("TOP", flashcardStatsPanel, "TOP", 0, -10)
    title:SetText("Flashcards")

    -----------------------------------------------------------------------
    -- Search Box and Label
    -- (Extra top padding: e.g. offset by -70 from the top)
    -----------------------------------------------------------------------
    local searchBox = CreateFrame("EditBox", nil, flashcardStatsPanel, "InputBoxTemplate")
    searchBox:SetSize(200, 20)
    searchBox:SetPoint("TOPLEFT", flashcardStatsPanel, "TOPLEFT", 20, -70) -- More top padding
    searchBox:SetAutoFocus(false)
    searchBox:SetText("")
    searchBox:SetCursorPosition(0)
    searchBox:SetFont(fontPath, 14, "OUTLINE")

    local searchLabel = flashcardStatsPanel:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    searchLabel:SetPoint("BOTTOMLEFT", searchBox, "TOPLEFT", 4, 2)
    searchLabel:SetText("Search:")

    -----------------------------------------------------------------------
    -- List Panel
    -----------------------------------------------------------------------
    local listPanel = CreateFrame("Frame", nil, flashcardStatsPanel)
    listPanel:SetSize(600, 420)
    listPanel:SetPoint("TOPLEFT", flashcardStatsPanel, "TOPLEFT", 0, -100) 
    -- also moved down to allow space for search bar

    local scrollFrame = CreateFrame("ScrollFrame", nil, listPanel)
    scrollFrame:SetSize(580, 380)
    scrollFrame:SetPoint("TOPLEFT", listPanel, "TOPLEFT", 10, -10)

    local scrollChild = CreateFrame("Frame", nil, scrollFrame)
    scrollFrame:SetScrollChild(scrollChild)

    scrollFrame:EnableMouseWheel(true)
    scrollFrame:SetScript("OnMouseWheel", function(self, delta)
        local current   = self:GetVerticalScroll()
        local maxScroll = self:GetVerticalScrollRange()
        local step      = 60
        if delta > 0 then
            self:SetVerticalScroll(math.max(0, current - step))
        else
            self:SetVerticalScroll(math.min(maxScroll, current + step))
        end
    end)

    -----------------------------------------------------------------------
    -- Stats Panel (detail view)
    -----------------------------------------------------------------------
    local statsPanel = CreateFrame("Frame", nil, flashcardStatsPanel)
    statsPanel:SetSize(600, 420)
    statsPanel:SetPoint("TOPLEFT", flashcardStatsPanel, "TOPLEFT", 0, -50)
    statsPanel:Hide()

    local statsTitle = statsPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    statsTitle:SetPoint("TOPLEFT", statsPanel, "TOPLEFT", 10, -10)
    statsTitle:SetText("Card Stats:")

    -- ScrollFrame for stats text
    local statsScrollFrame = CreateFrame("ScrollFrame", nil, statsPanel, "UIPanelScrollFrameTemplate")
    statsScrollFrame:SetPoint("TOPLEFT", statsTitle, "BOTTOMLEFT", 0, -10)
    statsScrollFrame:SetSize(500, 300)

    local statsScrollChild = CreateFrame("Frame", nil, statsScrollFrame)
    statsScrollChild:SetPoint("TOPLEFT", statsScrollFrame, "TOPLEFT")
    statsScrollChild:SetWidth(480)
    statsScrollChild:SetHeight(1)
    statsScrollFrame:SetScrollChild(statsScrollChild)

    local statsText = statsScrollChild:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    statsText:SetPoint("TOPLEFT", statsScrollChild, "TOPLEFT", 0, 0)
    statsText:SetWidth(400)
    statsText:SetJustifyH("LEFT")
    statsText:SetJustifyV("TOP")
    statsText:SetWordWrap(true)

    statsScrollFrame:EnableMouseWheel(true)
    statsScrollFrame:SetScript("OnMouseWheel", function(self, delta)
        local current = self:GetVerticalScroll()
        local maxScroll = self:GetVerticalScrollRange()
        local step = 30
        if delta > 0 then
            self:SetVerticalScroll(math.max(0, current - step))
        else
            self:SetVerticalScroll(math.min(maxScroll, current + step))
        end
    end)    

    local deleteButton = CreateFrame("Button", nil, statsPanel, "UIPanelButtonTemplate")
    deleteButton:SetSize(80, 24)
    deleteButton:SetText("Delete")
    -- anchor it to the right or somewhere visible
    deleteButton:SetPoint("BOTTOMRIGHT", statsPanel, "BOTTOMRIGHT", -60, 10)

    local backButton = CreateFrame("Button", nil, statsPanel, "UIPanelButtonTemplate")
    backButton:SetSize(80, 24)
    backButton:SetPoint("BOTTOMLEFT", statsPanel, "BOTTOMLEFT", 10, 10)
    backButton:SetText("Back")
    backButton:SetScript("OnClick", function()
        statsPanel:Hide()
        -- show the list panel and search box again
        listPanel:Show()
        searchBox:Show()
        searchLabel:Show()
    end)

    -----------------------------------------------------------------------
    -- Row Pool
    -----------------------------------------------------------------------
    local rowPool = {}
    local ROW_WIDTH = 580
    local MIN_ROW_HEIGHT = 20
    local rowSpacing = 10

    -- Reusable function
    local function GetRowFrame(parent)
        for _, row in ipairs(rowPool) do
            if not row.inUse then
                row.inUse = true
                row:Show()
                row:SetParent(parent)
                return row
            end
        end

        local row = CreateFrame("Button", nil, parent, "BackdropTemplate")
        row:EnableMouse(true)
        row:RegisterForClicks("LeftButtonUp")
        row:SetBackdrop({
            bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            edgeSize = 12,
        })
        row:SetBackdropBorderColor(0.4, 0.4, 0.4, 1)

        row:SetScript("OnEnter", function()
            row:SetBackdropBorderColor(1, 1, 0, 1)
        end)
        row:SetScript("OnLeave", function()
            row:SetBackdropBorderColor(0.4, 0.4, 0.4, 1)
        end)

        local textFS = row:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        textFS:SetPoint("TOPLEFT", row, "TOPLEFT", 5, -5)
        textFS:SetWidth(ROW_WIDTH - 10)
        textFS:SetJustifyH("LEFT")
        textFS:SetJustifyV("TOP")
        textFS:SetWordWrap(true)
        textFS:SetSpacing(2)
        textFS:SetFont(fontPath, 14)
        row.textFS = textFS

        row.inUse = true
        table.insert(rowPool, row)
        return row
    end

    -----------------------------------------------------------------------
    -- Refresh function
    -----------------------------------------------------------------------
    function WoWStudyFunction.RefreshStatsPanel()
        -- Hide & free all row frames
        for _, row in ipairs(rowPool) do
            row:Hide()
            row.inUse = false
        end

        local offsetY = 0
        scrollChild:SetSize(ROW_WIDTH, 1)

        local filterText = searchBox:GetText()
        filterText = filterText and filterText:lower() or ""

        WoWStudyFunction.UpdateSelectedFlashcards()

        for i, card in ipairs(WoWStudyGlobal.selectedFlashcards or {}) do
            if filterText == "" or card.question:lower():find(filterText, 1, true) then
                local row = GetRowFrame(scrollChild)
                row:SetPoint("TOPLEFT", scrollChild, "TOPLEFT", 0, offsetY)

                -- measure text to set row height
                row.textFS:SetText(card.question)
                local measuredHeight = row.textFS:GetStringHeight() + 10
                local finalHeight = math.max(MIN_ROW_HEIGHT, measuredHeight)
                row:SetSize(ROW_WIDTH, finalHeight)

                offsetY = offsetY - (finalHeight + rowSpacing)

                row:SetScript("OnClick", function()

                    local ratio = 0
                    if (card.totalCorrect + card.totalIncorrect) > 0 then
                        ratio = (card.totalCorrect / (card.totalCorrect + card.totalIncorrect)) * 100
                    end

                    lastTime = date("%c", card.lastTime)

                    -- Make a variable based on spacedRepetitionLevel, which shows the hour representation of score and hours remaining
                    local thresholds = {
                        [0] = 0,              -- 0 minutes (0 hours)
                        [1] = 600,            -- 10 minutes (0.17 hours)
                        [2] = 1200,           -- 20 minutes (0.33 hours)
                        [3] = 2400,           -- 40 minutes (0.67 hours)
                        [4] = 4800,           -- 80 minutes (1.33 hours)
                        [5] = 9600,           -- 160 minutes (2.67 hours)
                        [6] = 19200,          -- 320 minutes (5.33 hours)
                        [7] = 38400,          -- 640 minutes (10.67 hours)
                        [8] = 76800,          -- 1280 minutes (21.33 hours)
                        [9] = 153600,         -- 2560 minutes (42.67 hours)
                        [10] = 307200,        -- 5120 minutes (85.33 hours)
                        [11] = 614400,        -- 10240 minutes (170.67 hours)
                        [12] = 1228800,       -- 20480 minutes (341.33 hours)
                        [13] = 2457600,       -- 40960 minutes (682.67 hours)
                        [14] = 4915200,       -- 81920 minutes (1365.33 hours)
                        [15] = 9830400        -- 163840 minutes (2730.67 hours, above 1400 hours)
                    }

                    -- Score hours no decimals
                    local timeRemaining = thresholds[card.spacedRepetitionLevel] - (time() - card.lastTime)
                    if timeRemaining < 0 then
                        timeRemaining = 0
                    end

                    -- score into hours 1 decimal
                    local hoursRemaining = timeRemaining / 3600

                    -- Display card history last 10
                    local historyString = ""
                    local historyCount = 0
                    for i = #card.history, 1, -1 do
                        -- Make a red or green square based on correct or incorrect
                        local square = card.history[i].correct and "|cFF00FF00\*|r" or "|cFFFF0000\*|r"
                        historyString = historyString .. square .. " "
                        historyCount = historyCount + 1
                    end

                    local statsString = string.format([[
Deck: %s

Question: %s

Answer: %s

Last Time: %s

Next showing in: %.1f hours

Correct: %d

Incorrect: %d

Ratio: %.1f%%

History: %s]],card.deckName, card.question, card.answer, tostring(card.lastTime), hoursRemaining, card.totalCorrect, card.totalIncorrect, ratio, historyString)
                    statsText:SetText(statsString)
                    statsText:SetFont(fontPath, 10)
                    statsText:SetPoint("TOPLEFT", statsScrollChild, "TOPLEFT", 0, 0)
                    statsText:SetWidth(400)
                    statsText:SetJustifyH("LEFT")
                    statsText:SetJustifyV("TOP")
                    statsText:SetMaxLines(0)
                    statsText:SetWordWrap(true)
                    local textHeight = statsText:GetStringHeight()
                    statsScrollChild:SetHeight(textHeight)
                    statsScrollFrame:SetVerticalScroll(0)

                    -- hide search box and label
                    searchBox:Hide()
                    searchLabel:Hide()

                    listPanel:Hide()
                    statsPanel:Show()
                    if card.source == "external" then
                        -- Create or reuse a small button
                        deleteButton:Hide()
                    else
                        deleteButton:SetScript("OnClick", function()
                            -- Pop up confirmation
                            StaticPopup_Show("WOWSTUDY_CONFIRM_DELETE_CARD", nil, nil, { question = card.question, deck = card.deckName })
                            statsPanel:Hide()
                            -- show the list panel and search box again
                            listPanel:Show()
                            searchBox:Show()
                            searchLabel:Show()
                        end)
                        deleteButton:Show()
                    end
                end)
            end
        end

        scrollChild:SetSize(ROW_WIDTH, math.abs(offsetY))
        scrollFrame:SetVerticalScroll(0)
    end

    -- On text changed in searchBox
    searchBox:SetScript("OnTextChanged", function(self, userInput)
        if userInput then
            WoWStudyFunction.RefreshStatsPanel()
        end
    end)

    flashcardStatsPanel:SetScript("OnShow", function()
        WoWStudyFunction.RefreshStatsPanel()
    end)

    return flashcardStatsPanel
end
