import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import { prisma } from '../../prisma.js'
import {
  resolveUserNotificationTargets,
  resolveAdminNotificationTargets,
  resolveAuthCodeTargets,
  ensureUserNotificationPreference,
} from '../preferences.js'

const ORDER_CREATED = 'order:created'
const AUTH_CODE_REQUESTED = 'auth:codeRequested'

describe('preferences', () => {
  beforeEach(async () => {
    await prisma.notificationPreference.deleteMany()
    await prisma.adminNotificationSettings.deleteMany()
    await prisma.user.deleteMany()
  })

  afterEach(async () => {
    await prisma.notificationPreference.deleteMany()
    await prisma.adminNotificationSettings.deleteMany()
    await prisma.user.deleteMany()
  })

  it('returns empty targets when user has no preferences', async () => {
    const user = await prisma.user.create({ data: { email: 'test@test.com' } })
    const targets = await resolveUserNotificationTargets(ORDER_CREATED, { userId: user.id })
    expect(targets).toEqual([])
  })

  it('returns email target when user has preferences enabled', async () => {
    const user = await prisma.user.create({ data: { email: 'test@test.com' } })
    await prisma.notificationPreference.create({
      data: { userId: user.id, globalEnabled: true, orderCreated: true },
    })
    const targets = await resolveUserNotificationTargets(ORDER_CREATED, { userId: user.id })
    expect(targets).toHaveLength(1)
    expect(targets[0]).toEqual({ channel: 'email', recipient: 'test@test.com' })
  })

  it('returns no targets when globalEnabled is false', async () => {
    const user = await prisma.user.create({ data: { email: 'test@test.com' } })
    await prisma.notificationPreference.create({
      data: { userId: user.id, globalEnabled: false, orderCreated: true },
    })
    const targets = await resolveUserNotificationTargets(ORDER_CREATED, { userId: user.id })
    expect(targets).toEqual([])
  })

  it('returns no targets when specific event is disabled', async () => {
    const user = await prisma.user.create({ data: { email: 'test@test.com' } })
    await prisma.notificationPreference.create({
      data: { userId: user.id, globalEnabled: true, orderCreated: false },
    })
    const targets = await resolveUserNotificationTargets(ORDER_CREATED, { userId: user.id })
    expect(targets).toEqual([])
  })

  it('ensures user preference is created if not exists', async () => {
    const user = await prisma.user.create({ data: { email: 'test@test.com' } })
    const prefs = await ensureUserNotificationPreference(user.id)
    expect(prefs.globalEnabled).toBe(true)
    expect(prefs.userId).toBe(user.id)
  })

  it('returns admin targets when settings enabled', async () => {
    await prisma.user.create({ data: { email: 'admin@test.com' } })
    const origAdminEmail = process.env.ADMIN_EMAIL
    process.env.ADMIN_EMAIL = 'admin@test.com'

    await prisma.adminNotificationSettings.create({
      data: { emailEnabled: true, newOrder: true },
    })

    const targets = await resolveAdminNotificationTargets(ORDER_CREATED, {})
    expect(targets.some((t) => t.channel === 'email' && t.recipient === 'admin@test.com')).toBe(true)

    process.env.ADMIN_EMAIL = origAdminEmail
  })

  it('resolveAuthCodeTargets returns email for user and telegram for admin', async () => {
    await prisma.adminNotificationSettings.create({
      data: { telegramEnabled: true, telegramChatId: '12345', authCodeDuplicate: true },
    })

    const targets = await resolveAuthCodeTargets(AUTH_CODE_REQUESTED, {
      email: 'user@test.com',
      code: '123456',
      isAdmin: true,
    })

    expect(targets.some((t) => t.channel === 'email' && t.recipient === 'user@test.com')).toBe(true)
    expect(targets.some((t) => t.channel === 'telegram' && t.recipient === '12345')).toBe(true)
  })
})
