// Vitest uses globals (configured in vite.config.mjs: test.globals = true).
// Pure logic tests for the news image prompt builder helpers.
// These helpers live in StudioNewsEditor.jsx — this file duplicates them
// so they can be tested in isolation without pulling in the full editor bundle.

// ── Minimal copies of the prompt-builder helpers ──────────────────────────

const NEWS_PROMPT_TYPE_MOODS = {
  announcement: 'Futuristic',
  release: 'Software Release',
  editorial: 'Editorial',
  opinion: 'Editorial',
  tutorial: 'Clean Instructional',
  platform_update: 'Modern Tech',
  event: 'Futuristic',
  challenge: 'Futuristic',
  interview: 'Editorial',
  spotlight: 'Editorial',
  archive: 'Retro Tech',
  industry_news: 'Modern Tech',
  review: 'Modern Tech',
  roundup: 'Modern Tech',
}

const NEWS_PROMPT_TYPE_ADDONS = {
  release: 'Use a glossy software-release poster style with product UI panels, feature highlights, and a polished launch atmosphere.',
  announcement: 'Use a clean announcement-poster style with a strong headline, clear hero image, and supporting modules that communicate the main update quickly.',
  editorial: 'Use a refined editorial magazine-cover style with a strong visual concept, cleaner composition, and slightly more cinematic atmosphere.',
  opinion: 'Use a refined editorial magazine-cover style with a strong visual concept, cleaner composition, and slightly more cinematic atmosphere.',
  event: 'Use a conference or event-poster style with keynote energy, glowing screens, stage-like lighting, and a premium event atmosphere.',
  tutorial: 'Use a clear structured instructional poster style with organized UI panels, workflow callouts, and helpful visual hierarchy.',
  platform_update: 'Use a modern platform-update style with system UI visuals, feature modules, and a polished ecosystem presentation.',
  archive: 'Use a retro-tech editorial style inspired by early 2000s computer magazines, with classic hardware, vintage UI influences, and modern polished lighting.',
}

const NEWS_PROMPT_KEYWORD_PATTERNS = [
  {
    keywords: ['apple', 'wwdc', 'ios', 'macos', 'iphone', 'ipad', 'swift'],
    addon: 'Use a sleek developer-conference atmosphere with modern device screens, app ecosystem visuals, and a premium keynote mood.',
  },
  {
    keywords: ['google', 'gemini', 'google i/o', 'android', 'pixel', 'tensorflow'],
    addon: 'Use a colorful futuristic creative AI studio style with glowing panels, image and video creation tools, search elements, and generative media visuals.',
  },
  {
    keywords: ['intel', 'amd', 'processor', 'cpu', 'gpu', 'nvidia', 'radeon', 'chip'],
    addon: 'Use a retro computing hardware feature style with processor chips, technical callouts, old-school PC references, and magazine-cover energy.',
  },
  {
    keywords: ['skin', 'theme', 'desktop', 'customize', 'customization', 'rainmeter', 'widget'],
    addon: 'Use a desktop customization promo style with theme previews, icon panels, widget windows, and a glossy desktop software aesthetic.',
  },
  {
    keywords: ['ai', 'artificial intelligence', 'llm', 'chatgpt', 'openai', 'midjourney', 'stable diffusion', 'generative'],
    addon: 'Use a colorful futuristic creative AI studio style with glowing panels, generative media outputs, neural network visuals, and advanced AI tool interfaces.',
  },
]

function resolveNewsPromptHeadline(data) {
  return String(data.title || data.meta_title || '').trim() || 'Skinbase News'
}

function resolveNewsPromptSubheadline(data) {
  const raw = String(data.excerpt || data.meta_description || '').replace(/<[^>]*>/g, '').trim()
  if (raw) {
    const words = raw.split(/\s+/)
    return words.slice(0, 18).join(' ') + (words.length > 18 ? '…' : '')
  }
  const plain = String(data.content || '').replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' ').trim()
  if (plain) {
    const sentence = plain.split(/[.!?]/)[0].trim()
    if (sentence.length > 10) {
      const words = sentence.split(/\s+/)
      return words.slice(0, 18).join(' ')
    }
  }
  return 'Latest technology and creative industry update'
}

function resolveNewsPromptTopic(data) {
  const parts = []
  const cat = String(data.category || '').trim()
  if (cat) parts.push(cat)
  const tagList = (Array.isArray(data.tag_names) ? data.tag_names : []).slice(0, 5).filter(Boolean)
  if (tagList.length) parts.push(tagList.join(', '))
  if (!parts.length) {
    const words = String(data.title || '').split(/\s+/).filter((w) => w.length > 3).slice(0, 4)
    if (words.length) parts.push(words.join(' '))
  }
  return parts.join(' · ') || 'Technology and digital culture news'
}

function resolveNewsPromptType(data) {
  const raw = String(data.type || '').trim()
  if (!raw) return 'News'
  return raw.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase())
}

function resolveNewsPromptMood(data) {
  const type = String(data.type || '').toLowerCase().replace(/\s+/g, '_')
  return NEWS_PROMPT_TYPE_MOODS[type] || 'Modern Tech'
}

function resolveNewsPromptTypeAddon(data) {
  const type = String(data.type || '').toLowerCase().replace(/\s+/g, '_')
  return NEWS_PROMPT_TYPE_ADDONS[type] || ''
}

function resolveNewsPromptKeywordAddon(data) {
  const title = String(data.title || '').toLowerCase()
  const tags = (Array.isArray(data.tag_names) ? data.tag_names : []).join(' ').toLowerCase()
  const category = String(data.category || '').toLowerCase()
  const combined = `${title} ${tags} ${category}`
  const addons = []
  for (const pattern of NEWS_PROMPT_KEYWORD_PATTERNS) {
    if (pattern.keywords.some((kw) => combined.includes(kw))) {
      addons.push(pattern.addon)
    }
  }
  return [...new Set(addons)].join('\n')
}

function buildNewsImagePrompt(data) {
  const headline = resolveNewsPromptHeadline(data)
  const subheadline = resolveNewsPromptSubheadline(data)
  const topic = resolveNewsPromptTopic(data)
  const newsType = resolveNewsPromptType(data)
  const mood = resolveNewsPromptMood(data)
  const typeAddon = resolveNewsPromptTypeAddon(data)
  const keywordAddon = resolveNewsPromptKeywordAddon(data)

  const lines = [
    'Create a premium Skinbase news cover image in 16:9 aspect ratio.',
    '',
    `Headline: "${headline}"`,
    `Subheadline: "${subheadline}"`,
    `Topic: ${topic}`,
    `News type: ${newsType}`,
    `Mood: ${mood}`,
  ]
  if (typeAddon) lines.push('', typeAddon)
  if (keywordAddon) lines.push('', keywordAddon)
  return lines.join('\n')
}

// ─────────────────────────────────────────────────────────────────────────────

describe('resolveNewsPromptHeadline', () => {
  it('returns title when present', () => {
    expect(resolveNewsPromptHeadline({ title: 'My Title' })).toBe('My Title')
  })

  it('falls back to meta_title', () => {
    expect(resolveNewsPromptHeadline({ title: '', meta_title: 'Meta Title' })).toBe('Meta Title')
  })

  it('returns fallback when both are empty', () => {
    expect(resolveNewsPromptHeadline({})).toBe('Skinbase News')
  })
})

describe('resolveNewsPromptSubheadline', () => {
  it('returns excerpt truncated to 18 words', () => {
    const long = 'word '.repeat(25).trim()
    const result = resolveNewsPromptSubheadline({ excerpt: long })
    expect(result.endsWith('…')).toBe(true)
    expect(result.split(/\s+/).filter((w) => !w.startsWith('…') && w !== '…').length).toBeLessThanOrEqual(18)
  })

  it('returns excerpt as-is when short', () => {
    expect(resolveNewsPromptSubheadline({ excerpt: 'Short excerpt.' })).toBe('Short excerpt.')
  })

  it('strips HTML tags from excerpt', () => {
    expect(resolveNewsPromptSubheadline({ excerpt: '<p>Clean text</p>' })).toBe('Clean text')
  })

  it('returns fallback when all fields are empty', () => {
    expect(resolveNewsPromptSubheadline({})).toBe('Latest technology and creative industry update')
  })

  it('falls back to meta_description when excerpt is missing', () => {
    expect(resolveNewsPromptSubheadline({ meta_description: 'Meta desc' })).toBe('Meta desc')
  })
})

describe('resolveNewsPromptTopic', () => {
  it('includes category and tags', () => {
    const result = resolveNewsPromptTopic({ category: 'Tech News', tag_names: ['AI', 'Google'] })
    expect(result).toContain('Tech News')
    expect(result).toContain('AI')
    expect(result).toContain('Google')
  })

  it('falls back to title keywords when no category or tags', () => {
    const result = resolveNewsPromptTopic({ title: 'Some Long Title With Words' })
    expect(result.length).toBeGreaterThan(0)
  })

  it('returns generic fallback when all are empty', () => {
    expect(resolveNewsPromptTopic({})).toBe('Technology and digital culture news')
  })

  it('caps tags at 5', () => {
    const data = { tag_names: ['a', 'b', 'c', 'd', 'e', 'f', 'g'] }
    const result = resolveNewsPromptTopic(data)
    expect(result.split(',').length).toBeLessThanOrEqual(5)
  })
})

describe('resolveNewsPromptType', () => {
  it('capitalizes and humanizes underscored types', () => {
    expect(resolveNewsPromptType({ type: 'platform_update' })).toBe('Platform Update')
  })

  it('returns "News" when type is missing', () => {
    expect(resolveNewsPromptType({})).toBe('News')
  })

  it('handles simple types correctly', () => {
    expect(resolveNewsPromptType({ type: 'editorial' })).toBe('Editorial')
    expect(resolveNewsPromptType({ type: 'release' })).toBe('Release')
  })
})

describe('resolveNewsPromptMood', () => {
  it('returns correct mood for known types', () => {
    expect(resolveNewsPromptMood({ type: 'archive' })).toBe('Retro Tech')
    expect(resolveNewsPromptMood({ type: 'tutorial' })).toBe('Clean Instructional')
    expect(resolveNewsPromptMood({ type: 'announcement' })).toBe('Futuristic')
    expect(resolveNewsPromptMood({ type: 'release' })).toBe('Software Release')
  })

  it('returns Modern Tech fallback for unknown type', () => {
    expect(resolveNewsPromptMood({ type: 'unknown_type' })).toBe('Modern Tech')
    expect(resolveNewsPromptMood({})).toBe('Modern Tech')
  })
})

describe('resolveNewsPromptTypeAddon', () => {
  it('returns addon text for known types', () => {
    expect(resolveNewsPromptTypeAddon({ type: 'release' })).toContain('software-release poster')
    expect(resolveNewsPromptTypeAddon({ type: 'event' })).toContain('conference or event-poster')
    expect(resolveNewsPromptTypeAddon({ type: 'archive' })).toContain('retro-tech editorial')
  })

  it('returns empty string for unknown type', () => {
    expect(resolveNewsPromptTypeAddon({ type: 'unknown' })).toBe('')
    expect(resolveNewsPromptTypeAddon({})).toBe('')
  })
})

describe('resolveNewsPromptKeywordAddon', () => {
  it('detects apple/WWDC keyword in title', () => {
    const result = resolveNewsPromptKeywordAddon({ title: 'Apple WWDC 2026 Keynote', tag_names: [] })
    expect(result).toContain('developer-conference atmosphere')
  })

  it('detects AI keyword in tags', () => {
    const result = resolveNewsPromptKeywordAddon({ title: 'New Update', tag_names: ['AI', 'Gemini'] })
    expect(result).toContain('creative AI studio')
  })

  it('detects desktop customization keyword', () => {
    const result = resolveNewsPromptKeywordAddon({ title: 'Best desktop customization tools', tag_names: [] })
    expect(result).toContain('desktop customization promo')
  })

  it('returns empty string when no keywords match', () => {
    const result = resolveNewsPromptKeywordAddon({ title: 'Random Article', tag_names: ['general'] })
    expect(result).toBe('')
  })

  it('deduplicates addons when multiple patterns match the same text', () => {
    // "AI" matches both ai pattern; ensure no duplicates
    const result = resolveNewsPromptKeywordAddon({ title: 'ai ai ai', tag_names: ['ai', 'artificial intelligence'] })
    const lines = result.split('\n').filter(Boolean)
    expect(lines.length).toBe(new Set(lines).size)
  })
})

describe('buildNewsImagePrompt', () => {
  it('includes the article headline in the prompt', () => {
    const prompt = buildNewsImagePrompt({ title: 'Google I/O 2026 Keynote', type: 'announcement' })
    expect(prompt).toContain('Google I/O 2026 Keynote')
  })

  it('includes the type addon for release articles', () => {
    const prompt = buildNewsImagePrompt({ title: 'App Launch', type: 'release' })
    expect(prompt).toContain('software-release poster')
  })

  it('includes the keyword addon when tags match', () => {
    const prompt = buildNewsImagePrompt({ title: 'New skin', tag_names: ['desktop', 'theme'], type: 'release' })
    expect(prompt).toContain('desktop customization promo')
  })

  it('uses fallback headline when title is missing', () => {
    const prompt = buildNewsImagePrompt({})
    expect(prompt).toContain('Skinbase News')
  })

  it('contains the 16:9 aspect ratio instruction', () => {
    const prompt = buildNewsImagePrompt({ title: 'Test' })
    expect(prompt).toContain('16:9')
  })

  it('contains the mood line', () => {
    const prompt = buildNewsImagePrompt({ title: 'Tutorial Article', type: 'tutorial' })
    expect(prompt).toContain('Clean Instructional')
  })
})
