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

const {
  mockCreateDb,
  mockGetTenantById,
  mockCreateAiChatSession,
  mockAppendAiChatMessage,
  mockLastAiChatMessages,
  mockLastTelegramAiMessages,
  mockLastWhatsAppAiMessages,
  mockTouchAiChatSession,
  mockGetCreditPurchases,
  mockGetGlobalConfig,
  mockCallAI,
  mockRetrieveContext,
} = vi.hoisted(() => ({
  mockCreateDb: vi.fn(() => ({})),
  mockGetTenantById: vi.fn(),
  mockCreateAiChatSession: vi.fn(),
  mockAppendAiChatMessage: vi.fn(),
  mockLastAiChatMessages: vi.fn(),
  mockLastTelegramAiMessages: vi.fn(),
  mockLastWhatsAppAiMessages: vi.fn(),
  mockTouchAiChatSession: vi.fn(),
  mockGetCreditPurchases: vi.fn(),
  mockGetGlobalConfig: vi.fn(),
  mockCallAI: vi.fn(),
  mockRetrieveContext: vi.fn(),
}))

vi.mock('@zync/db/queries', () => ({
  createDb: mockCreateDb,
  getTenantById: mockGetTenantById,
  createAiChatSession: mockCreateAiChatSession,
  appendAiChatMessage: mockAppendAiChatMessage,
  lastAiChatMessages: mockLastAiChatMessages,
  lastTelegramAiMessages: mockLastTelegramAiMessages,
  lastWhatsAppAiMessages: mockLastWhatsAppAiMessages,
  touchAiChatSession: mockTouchAiChatSession,
  getCreditPurchases: mockGetCreditPurchases,
  getGlobalConfig: mockGetGlobalConfig,
}))

vi.mock('../src/index.ts', () => ({
  callAI: mockCallAI,
}))

vi.mock('../src/rag/retrieve.ts', () => ({
  retrieveContext: mockRetrieveContext,
}))

import { runAssistantTurn } from '../src/chat/assistant'

describe('runAssistantTurn', () => {
  beforeEach(() => {
    vi.clearAllMocks()
    mockGetTenantById.mockResolvedValue({ name: 'Tenant', defaultCurrency: 'USD' })
    mockCreateAiChatSession.mockResolvedValue({ id: 'session-1' })
    mockAppendAiChatMessage.mockResolvedValue({ id: 'message-1' })
    mockLastTelegramAiMessages.mockResolvedValue([])
    mockLastWhatsAppAiMessages.mockResolvedValue([
      { role: 'assistant', content: 'Previous WhatsApp reply' },
    ])
    mockRetrieveContext.mockResolvedValue('context')
    mockCallAI.mockResolvedValue({
      content: 'Fresh reply',
      inputTokens: 10,
      outputTokens: 5,
      model: 'claude-sonnet-4-6',
    })
  })

  it('loads recent WhatsApp history before calling the model', async () => {
    await runAssistantTurn({} as never, {
      tenantId: 'tenant-1',
      channel: 'whatsapp',
      message: 'What did we discuss?',
      whatsappChatId: 'wa-123',
      tier: 'enterprise',
    })

    expect(mockLastWhatsAppAiMessages).toHaveBeenCalledWith({}, 'tenant-1', 'wa-123', 5)
    expect(mockCallAI).toHaveBeenCalledWith(
      expect.anything(),
      expect.objectContaining({
        messages: expect.arrayContaining([
          expect.objectContaining({ role: 'assistant', content: 'Previous WhatsApp reply' }),
          expect.objectContaining({ role: 'user', content: 'What did we discuss?' }),
        ]),
      }),
    )
  })
})
