GuildHelper = GuildHelper or {}

local addon = GuildHelper

addon.ContentService = addon.ContentService or {}

local function canEditOfficerNote()
    if C_GuildInfo and C_GuildInfo.CanEditOfficerNote then
        return C_GuildInfo.CanEditOfficerNote()
    end

    if CanEditOfficerNote then
        return CanEditOfficerNote()
    end

    return false
end

function addon.ContentService:IsGuildMaster()
    local _, _, rankIndex = GetGuildInfo("player")
    return tonumber(rankIndex) == 0
end

function addon.ContentService:CanManageBoard()
    return self:IsGuildMaster() or canEditOfficerNote()
end

local function getStoredGuildKey()
    return addon.FederationService:GetHomeGuild()
        or addon.Store:GetDisplayGuildKey()
        or addon.Store:GetGuildKey()
        or "Unguilded"
end

local function createRecord(contentType, title, body, guildKey)
    local playerName = addon.Store:GetPlayerName()

    return {
        id = addon.Repositories:NextId("content"),
        type = contentType,
        title = title,
        body = body,
        guildName = guildKey,
        author = playerName,
        pinned = false,
        createdAt = time(),
        updatedAt = time(),
        updatedBy = playerName,
        revision = 1,
        deleted = false,
    }
end

function addon.ContentService:EnsureSeedData()
    local contentTable = addon.Store:GetGuild().content

    if next(contentTable) then
        return
    end

    local guildKey = getStoredGuildKey()
    local welcome = createRecord(
        "announcement",
        "GuildHelper v3",
        "This is the unified guild board. Use it for announcements, resources, and events.",
        guildKey
    )

    welcome.pinned = true
    contentTable[welcome.id] = welcome
end

function addon.ContentService:ListVisibleContent(filters)
    local visibleGuilds = {}
    local filterText = string.lower(filters and filters.searchText or "")
    local filterType = string.lower(filters and filters.typeFilter or "all")
    local filterGuild = filters and filters.guildName or "all"
    local pinnedOnly = filters and filters.pinnedOnly or false

    for _, guildKey in ipairs(addon.FederationService:GetAllGuildKeys()) do
        visibleGuilds[guildKey] = true
    end

    return addon.Repositories:List("content", function(record)
        if record.deleted or not visibleGuilds[record.guildName] then
            return false
        end

        if filterType ~= "all" and string.lower(record.type or "") ~= filterType then
            return false
        end

        if filterGuild ~= "all" and record.guildName ~= filterGuild then
            return false
        end

        if pinnedOnly and not record.pinned then
            return false
        end

        if filterText ~= "" then
            local haystack = string.lower(table.concat({
                record.title or "",
                record.body or "",
                record.author or "",
            }, " "))

            if not string.find(haystack, filterText, 1, true) then
                return false
            end
        end

        return true
    end)
end

function addon.ContentService:GetContent(contentId)
    return addon.Repositories:Get("content", contentId)
end

function addon.ContentService:GetFirstVisibleContentId()
    local records = self:ListVisibleContent()

    if #records == 0 then
        return nil
    end

    return records[1].id
end

function addon.ContentService:Create(contentType, title, body, guildKey)
    if not self:CanManageBoard() then
        return nil
    end

    local record = createRecord(contentType or "announcement", title or "Untitled", body or "", guildKey or getStoredGuildKey())
    addon.Repositories:Upsert("content", record.id, record)
    addon.Store:GetSync().tableMeta.content.updatedAt = time()
    return record
end

function addon.ContentService:Update(contentId, payload)
    if not self:CanManageBoard() then
        return nil
    end

    local record = self:GetContent(contentId)

    if not record then
        return nil
    end

    record.type = payload.type ~= "" and payload.type or record.type
    record.title = payload.title ~= "" and payload.title or record.title
    record.body = payload.body or record.body
    record.guildName = payload.guildName ~= "" and payload.guildName or record.guildName
    record.updatedAt = time()
    record.updatedBy = addon.Store:GetPlayerName()
    record.revision = (record.revision or 0) + 1
    addon.Store:GetSync().tableMeta.content.updatedAt = record.updatedAt
    return record
end

function addon.ContentService:Delete(contentId)
    if not self:CanManageBoard() then
        return false
    end

    local record = self:GetContent(contentId)

    if not record then
        return false
    end

    record.deleted = true
    record.updatedAt = time()
    record.updatedBy = addon.Store:GetPlayerName()
    record.revision = (record.revision or 0) + 1
    addon.Store:GetSync().tableMeta.content.updatedAt = record.updatedAt
    return true
end

function addon.ContentService:TogglePinned(id)
    if not self:CanManageBoard() then
        return nil
    end

    local record = addon.Repositories:Get("content", id)

    if not record then
        return nil
    end

    record.pinned = not record.pinned
    record.updatedAt = time()
    record.updatedBy = addon.Store:GetPlayerName()
    record.revision = (record.revision or 0) + 1
    return record
end
