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

const {
  createPlatformSupportMessageMock,
  listPlatformSupportMessagesMock,
} = vi.hoisted(() => ({
  createPlatformSupportMessageMock: vi.fn(),
  listPlatformSupportMessagesMock: vi.fn(),
}))

vi.mock('@zync/db/queries', async () => {
  const actual = await vi.importActual<object>('@zync/db/queries')
  return {
    ...actual,
    createPlatformSupportMessage: createPlatformSupportMessageMock,
    listPlatformSupportMessages: listPlatformSupportMessagesMock,
  }
})

import {
  buildPlatformHelpdeskBackfillRows,
  createPlatformTicketMessage,
  listPlatformTicketMessages,
  type LegacySlaPolicyRow,
  type LegacyTicketAttachmentRow,
  type LegacyTicketMessageRow,
  type LegacyTicketRow,
} from '../helpdesk'

describe('helpdesk platform parity', () => {
  beforeEach(() => {
    vi.clearAllMocks()
  })

  it('persists a module message through the query layer while preserving host extension columns', async () => {
    const db = {}
    createPlatformSupportMessageMock.mockResolvedValue({
      id: 'msg-1',
      ticketId: 'ticket-1',
      tenantId: 'tenant-1',
      authorType: 'staff',
      authorId: 'user-1',
      authorName: 'Agent',
      content: '<p>Reply</p>',
      source: 'email',
      createdAt: new Date('2026-07-01T00:00:00Z'),
    })

    const message = await createPlatformTicketMessage(db as never, 'tenant-1', 'ticket-1', {
      author_type: 'staff',
      author_id: 'user-1',
      author_name: 'Agent',
      content: '<p>Reply</p>',
      source: 'email',
    })

    expect(createPlatformSupportMessageMock).toHaveBeenCalledWith(db, {
      tenantId: 'tenant-1',
      ticketId: 'ticket-1',
      authorType: 'staff',
      authorId: 'user-1',
      authorName: 'Agent',
      content: '<p>Reply</p>',
      source: 'email',
    })
    expect(message).toEqual({
      id: 'msg-1',
      ticket_id: 'ticket-1',
      tenant_id: 'tenant-1',
      author_type: 'staff',
      author_id: 'user-1',
      author_name: 'Agent',
      content: '<p>Reply</p>',
      source: 'email',
      created_at: '2026-07-01T00:00:00.000Z',
    })
  })

  it('lists module-backed ticket messages in the host response shape', async () => {
    const db = {}
    listPlatformSupportMessagesMock.mockResolvedValue([
      {
        id: 'msg-1',
        ticketId: 'ticket-1',
        tenantId: 'tenant-1',
        authorType: 'customer',
        authorId: null,
        authorName: 'Pat',
        content: 'Need help',
        source: 'portal',
        createdAt: new Date('2026-07-01T01:00:00Z'),
      },
    ])

    await expect(listPlatformTicketMessages(db as never, 'tenant-1', 'ticket-1')).resolves.toEqual([
      {
        id: 'msg-1',
        ticket_id: 'ticket-1',
        tenant_id: 'tenant-1',
        author_type: 'customer',
        author_id: null,
        author_name: 'Pat',
        content: 'Need help',
        source: 'portal',
        created_at: '2026-07-01T01:00:00.000Z',
      },
    ])
    expect(listPlatformSupportMessagesMock).toHaveBeenCalledWith(db, {
      tenantId: 'tenant-1',
      ticketId: 'ticket-1',
    })
  })

  it('builds expand/backfill rows for messages, attachments, transitions, and SLA policies', () => {
    const ticketRows: LegacyTicketRow[] = [
      {
        id: 'ticket-1',
        tenantId: 'tenant-1',
        assigneeId: 'user-1',
        resolvedAt: new Date('2026-06-10T10:00:00Z'),
        closedAt: new Date('2026-06-12T10:00:00Z'),
      },
    ]
    const messageRows: LegacyTicketMessageRow[] = [
      {
        id: 'msg-1',
        ticketId: 'ticket-1',
        tenantId: 'tenant-1',
        authorType: 'staff',
        authorId: 'user-1',
        authorName: 'Agent',
        content: '<p>Reply</p>',
        source: 'email',
        deletedAt: null,
        createdAt: new Date('2026-06-10T09:00:00Z'),
      },
    ]
    const attachmentRows: LegacyTicketAttachmentRow[] = [
      {
        id: 'att-1',
        messageId: 'msg-1',
        tenantId: 'tenant-1',
        filename: 'invoice.pdf',
        r2Key: 'tickets/invoice.pdf',
        url: 'https://cdn.example.com/tickets/invoice.pdf',
        sizeBytes: 42,
        mimeType: 'application/pdf',
        createdAt: new Date('2026-06-10T09:01:00Z'),
      },
    ]
    const policyRows: LegacySlaPolicyRow[] = [
      {
        tenantId: 'tenant-1',
        priority: 'high',
        firstResponseHours: 2,
        resolutionHours: 8,
      },
    ]

    const rows = buildPlatformHelpdeskBackfillRows({
      tickets: ticketRows,
      messages: messageRows,
      attachments: attachmentRows,
      slaPolicies: policyRows,
    })

    expect(rows.messages).toEqual([
      {
        id: 'msg-1',
        parentType: 'ticket',
        parentId: 'ticket-1',
        tenantId: 'tenant-1',
        authorType: 'staff',
        authorId: 'user-1',
        authorName: 'Agent',
        body: '<p>Reply</p>',
        visibility: 'email',
        source: 'email',
        deletedAt: null,
        createdAt: new Date('2026-06-10T09:00:00Z'),
      },
    ])
    expect(rows.attachments).toEqual([
      {
        id: 'att-1',
        parentType: 'ticket_message',
        parentId: 'msg-1',
        tenantId: 'tenant-1',
        messageId: 'msg-1',
        objectKey: 'tickets/invoice.pdf',
        fileName: 'invoice.pdf',
        mimeType: 'application/pdf',
        url: 'https://cdn.example.com/tickets/invoice.pdf',
        sizeBytes: 42,
        createdAt: new Date('2026-06-10T09:01:00Z'),
      },
    ])
    expect(rows.transitions).toEqual([
      {
        parentType: 'ticket',
        parentId: 'ticket-1',
        tenantId: 'tenant-1',
        fromStatus: 'open',
        toStatus: 'resolved',
        actorId: 'user-1',
        reason: 'legacy resolved backfill',
        at: new Date('2026-06-10T10:00:00Z'),
      },
      {
        parentType: 'ticket',
        parentId: 'ticket-1',
        tenantId: 'tenant-1',
        fromStatus: 'resolved',
        toStatus: 'closed',
        actorId: 'user-1',
        reason: 'legacy closed backfill',
        at: new Date('2026-06-12T10:00:00Z'),
      },
    ])
    expect(rows.slaPolicies).toEqual([
      {
        scopeKey: 'tenant-1:high:resolution',
        tenantId: 'tenant-1',
        priority: 'high',
        target: 'resolution',
        dueMinutes: 480,
      },
    ])
  })
})
