const { test, beforeEach, afterEach } = require('node:test')
const assert = require('node:assert/strict')

// Exercise the News-gump sync decisions against a fake sidecar client by
// monkeypatching the shared modules newsGump require()s (same instance) — no DB,
// no network.
const uoLinkClient = require('../src/utils/uoLinkClient')
const settings = require('../src/model/settings/settings.model')
const newsGump = require('../src/utils/newsGump')

let calls
const saved = {}

beforeEach(() => {
  calls = { post: [], del: [] }
  saved.postNews = uoLinkClient.postNews
  saved.deleteNews = uoLinkClient.deleteNews
  saved.get = settings.get
  uoLinkClient.postNews = async (article) => { calls.post.push(article); return { ok: true, status: 200 } }
  uoLinkClient.deleteNews = async (id) => { calls.del.push(id); return { ok: true, status: 200 } }
  settings.get = async () => null // no gump image configured
})

afterEach(() => {
  uoLinkClient.postNews = saved.postNews
  uoLinkClient.deleteNews = saved.deleteNews
  settings.get = saved.get
})

const newsPost = (over = {}) => ({ id: 42, category: 'news', published: true, title: 'Double XP Weekend', excerpt: 'Starts Friday.', body: null, ...over })

test('buildArticle centres the title, links the news list, and respects announce', async () => {
  const a = await newsGump.buildArticle(newsPost(), { announce: false })
  assert.equal(a.id, '42')
  assert.match(a.body, /<CENTER>Double XP Weekend<\/CENTER>/)
  assert.match(a.body, /Starts Friday\./)
  assert.match(a.url, /\/site\/news$/)
  assert.equal(a.announce, false)
})

test('a fresh publish into news pushes with announce=true', async () => {
  await newsGump.syncPost(newsPost(), { wasPublished: false, wasNews: false })
  assert.equal(calls.post.length, 1)
  assert.equal(calls.post[0].announce, true)
  assert.equal(calls.del.length, 0)
})

test('an edit of already-published news refreshes silently (announce=false)', async () => {
  await newsGump.syncPost(newsPost({ title: 'Edited' }), { wasPublished: true, wasNews: true })
  assert.equal(calls.post.length, 1)
  assert.equal(calls.post[0].announce, false)
})

test('unpublishing published news pulls the article from the gump', async () => {
  await newsGump.syncPost(newsPost({ published: false }), { wasPublished: true, wasNews: true })
  assert.equal(calls.post.length, 0)
  assert.deepEqual(calls.del, ['42'])
})

test('a draft never-published news post does nothing', async () => {
  await newsGump.syncPost(newsPost({ published: false }), { wasPublished: false, wasNews: false })
  assert.equal(calls.post.length, 0)
  assert.equal(calls.del.length, 0)
})

test('a non-news post (e.g. screenshot) is never pushed', async () => {
  await newsGump.syncPost(newsPost({ category: 'screenshot' }), { wasPublished: false, wasNews: false })
  assert.equal(calls.post.length, 0)
})
