import { describe, expect, it } from 'vitest'
import { UnsupportedOperation, type MarketingAdapter } from './index.js'
import { createSegment } from './segments.js'
import { makeSelfManagedAdapter } from './self-managed.js'
import { createMemoryComplianceStore } from './compliance.js'

function fakeAdapter(supports: MarketingAdapter['supports']): MarketingAdapter {
  return {
    name: 'fake',
    supports,
    async upsertContact() {},
    async removeContact() {},
    async tagContact() {},
    async createList() {
      return { id: '1', name: 'L' }
    },
    async lists() {
      return []
    },
    async createCampaign(input) {
      return { ...input, id: 'c1' }
    },
    async sendCampaign() {
      return { sent: [], refused: [] }
    },
    async campaignStats() {
      return { opens: 0, clicks: 0, bounces: 0, unsubs: 0 }
    },
    async syncSuppression() {
      return []
    },
    async createSegment(def) {
      return { id: 'seg-1', ...def }
    },
    async listSegments() {
      return []
    },
  } as MarketingAdapter & {
    createSegment: (def: { name: string; listId: string; filter: object }) => Promise<{
      id: string
      name: string
      listId: string
      filter: object
    }>
  }
}

describe('segments capability', () => {
  it('succeeds on a supporting adapter', async () => {
    const adapter = fakeAdapter({ segments: true, scheduling: false, automation: false })
    const segment = await createSegment(adapter, {
      name: 'VIP',
      listId: 'list-1',
      filter: { tag: 'vip' },
    })
    expect(segment.id).toBe('seg-1')
  })

  it('throws UnsupportedOperation on a non-supporting adapter', async () => {
    const adapter = makeSelfManagedAdapter({
      from: 'news@example.com',
      mail: { send: async () => ({ id: '1', provider: 'fake' }) },
      store: {
        async upsertContact() {},
        async removeContact() {},
        async tagContact() {},
        async createList(name) {
          return { id: 'l1', name }
        },
        async lists() {
          return []
        },
        async saveCampaign() {},
        async getCampaign() {
          return null
        },
        async getListRecipients() {
          return []
        },
        async recordOpen() {},
        async recordClick() {},
        async getStats() {
          return { opens: 0, clicks: 0, bounces: 0, unsubs: 0 }
        },
        async createSegment(def) {
          return { id: 's1', ...def }
        },
        async listSegments() {
          return []
        },
        async scheduleCampaign() {},
      },
      complianceStore: createMemoryComplianceStore(),
    })

    expect(adapter.supports.segments).toBe(true)
    const nonSupporting = fakeAdapter({ segments: false, scheduling: true, automation: false })
    await expect(
      createSegment(nonSupporting, { name: 'VIP', listId: '1', filter: {} }),
    ).rejects.toBeInstanceOf(UnsupportedOperation)
  })
})
