import { beforeEach, describe, expect, it, vi } from 'vitest'

const {
  getUserEmailPrefs,
  getUserEmailAndLocale,
  getUserTelegramPrefs,
  getUserTelegramChatId,
  loadAdapterCredential,
  sendEmail,
} = vi.hoisted(() => ({
  getUserEmailPrefs: vi.fn(),
  getUserEmailAndLocale: vi.fn(),
  getUserTelegramPrefs: vi.fn(),
  getUserTelegramChatId: vi.fn(),
  loadAdapterCredential: vi.fn(),
  sendEmail: vi.fn(),
}))

vi.mock('@zync/db/queries', () => ({
  getUserEmailPrefs,
  getUserEmailAndLocale,
  getUserTelegramPrefs,
  getUserTelegramChatId,
}))

vi.mock('../src/credentials', () => ({
  loadAdapterCredential,
}))

vi.mock('../src/email/send-email', () => ({
  sendEmail,
}))

import { EmailNotificationAdapter } from '../src/adapters/email'
import { TelegramNotificationAdapter } from '../src/adapters/telegram'

describe('notification adapters tenant scoping', () => {
  beforeEach(() => {
    vi.clearAllMocks()
  })

  it('email adapter reads delivery prefs and locale in the current tenant scope', async () => {
    getUserEmailPrefs.mockResolvedValue({ emailTypes: ['invoice_paid'] })
    getUserEmailAndLocale.mockResolvedValue({ email: 'user@example.com', locale: 'he' })
    sendEmail.mockResolvedValue({ id: 'email_1' })

    const adapter = new EmailNotificationAdapter({} as never, {
      RESEND_API_KEY: 'resend',
    } as never, 'tenant-1')

    await expect(
      adapter.deliver('user-1', {
        type: 'invoice_paid',
        title: 'Invoice paid',
        body: 'Acme paid',
      }),
    ).resolves.toEqual({ delivered: true })

    expect(getUserEmailPrefs).toHaveBeenCalledWith(expect.anything(), 'user-1', 'tenant-1')
    expect(getUserEmailAndLocale).toHaveBeenCalledWith(expect.anything(), 'user-1', 'tenant-1')
  })

  it('telegram adapter reads opt-in preferences in the current tenant scope', async () => {
    getUserTelegramPrefs.mockResolvedValue({ telegramTypes: ['task_comment'] })
    getUserTelegramChatId.mockResolvedValue('1234')
    loadAdapterCredential.mockResolvedValue('bot-token')

    const fetchMock = vi.fn().mockResolvedValue({
      ok: true,
      text: vi.fn(),
    })
    vi.stubGlobal('fetch', fetchMock)

    const adapter = new TelegramNotificationAdapter({} as never, {
      INTEGRATION_ENCRYPTION_KEY: 'key',
    } as never, 'tenant-2')

    await expect(
      adapter.deliver('user-2', {
        type: 'task_comment',
        title: 'Comment',
        body: 'New comment',
      }),
    ).resolves.toEqual({ delivered: true })

    expect(getUserTelegramPrefs).toHaveBeenCalledWith(expect.anything(), 'user-2', 'tenant-2')
    expect(getUserTelegramChatId).toHaveBeenCalledWith(expect.anything(), 'user-2', 'tenant-2')
  })
})
