/* eslint-disable @typescript-eslint/no-explicit-any */
import { describe, expect, it, vi } from 'vitest'

import {
  confirmDoubleOptIn,
  createMemoryComplianceStore,
  type CampaignLegalContext,
} from '@platform-modules/marketing'
import { makeSelfManagedAdapter } from '@platform-modules/marketing/self-managed'
import { createPlatformMarketingDeps } from '../marketing'

const TENANT_ID = 'tenant-1'

type PlatformMarketingTestRow = Record<string, any>

type PlatformMarketingTestState = {
  sequence: number
  leads: PlatformMarketingTestRow[]
  campaigns: PlatformMarketingTestRow[]
}

const legal: CampaignLegalContext = {
  region: 'EU',
  oneClickUnsubscribeUrl: 'https://example.com/unsub/one-click',
  legal: {
    spf: true,
    dkim: true,
    dmarc: true,
    physicalPostalAddress: '1 Market St, Tel Aviv',
    advertisingLabel: 'פרסומת',
  },
}

function createDbState(): PlatformMarketingTestState {
  return {
    sequence: 1,
    leads: [],
    campaigns: [],
  }
}

function createStateBackedDb(state: PlatformMarketingTestState = createDbState()) {
  return { __platformMarketingState: state }
}

describe('marketing platform parity', () => {
  it('enumerates host-table suppressions faithfully through the ComplianceStore and self-managed adapter', async () => {
    const db = createStateBackedDb({
      sequence: 3,
      leads: [
        {
          id: 'lead-1',
          tenantId: TENANT_ID,
          name: 'Blocked A',
          email: 'blocked-a@example.com',
          sourceMetadata: {
            platformMarketing: {
              suppression: {
                email: 'blocked-a@example.com',
                reason: 'unsubscribe',
                suppressedAt: '2026-07-01T00:00:00.000Z',
              },
            },
          },
        },
        {
          id: 'lead-2',
          tenantId: TENANT_ID,
          name: 'Blocked B',
          email: 'blocked-b@example.com',
          sourceMetadata: {
            platformMarketing: {
              suppression: {
                email: 'blocked-b@example.com',
                reason: 'bounce',
                suppressedAt: '2026-07-02T00:00:00.000Z',
              },
            },
          },
        },
      ],
      campaigns: [],
    })

    const deps = createPlatformMarketingDeps(db as never, TENANT_ID, () => new Date('2026-07-01T00:00:00.000Z'))

    expect(await deps.complianceStore.listSuppressed()).toEqual([
      {
        email: 'blocked-a@example.com',
        reason: 'unsubscribe',
        suppressedAt: '2026-07-01T00:00:00.000Z',
      },
      {
        email: 'blocked-b@example.com',
        reason: 'bounce',
        suppressedAt: '2026-07-02T00:00:00.000Z',
      },
    ])

    const adapter = makeSelfManagedAdapter({
      from: 'news@example.com',
      mail: { send: vi.fn() },
      store: deps.store,
      complianceStore: deps.complianceStore,
    })

    expect(await adapter.syncSuppression()).toEqual(await deps.complianceStore.listSuppressed())
  })

  it('matches the module consent flow while persisting contact membership in host tables', async () => {
    const clock = () => new Date('2026-07-03T10:00:00.000Z')
    const db = createStateBackedDb()
    const deps = createPlatformMarketingDeps(db as never, TENANT_ID, clock)

    const memoryStore = createMemoryComplianceStore()
    const expectedConsent = await confirmDoubleOptIn(
      memoryStore,
      'Lead@Example.com',
      'EU',
      () => clock().toISOString(),
    )

    const actualConsent = await confirmDoubleOptIn(
      deps.complianceStore,
      'Lead@Example.com',
      'EU',
      () => clock().toISOString(),
    )

    const list = await deps.store.createList('Newsletter')
    await deps.store.upsertContact(
      {
        email: 'Lead@Example.com',
        tags: ['vip'],
        attributes: { firstName: 'Ada' },
      },
      list.id,
    )
    await deps.store.tagContact('Lead@Example.com', 'beta')

    expect(actualConsent).toEqual(expectedConsent)
    expect(await deps.complianceStore.getConsent('lead@example.com')).toEqual(expectedConsent)
    expect(await deps.store.getListRecipients([list.id])).toEqual(['lead@example.com'])
    expect(db.__platformMarketingState.leads[0]?.sourceMetadata.platformMarketing.tags).toEqual([
      'vip',
      'beta',
    ])
  })

  it('persists lists, segments, campaigns, scheduling, and stats via host-table metadata', async () => {
    const db = createStateBackedDb()
    const deps = createPlatformMarketingDeps(db as never, TENANT_ID, () => new Date('2026-07-04T00:00:00.000Z'))

    const list = await deps.store.createList('Customers')
    const segment = await deps.store.createSegment({
      name: 'VIP customers',
      listId: list.id,
      filter: { tag: 'vip' },
    })
    const campaign = await deps.store.createCampaign({
      name: 'Launch',
      subject: 'Hello',
      html: '<p>Hello</p>',
      text: 'Hello',
      listIds: [list.id],
      region: 'IL',
    })

    await deps.store.scheduleCampaign(campaign.id, '2026-07-10T00:00:00.000Z')
    await deps.store.recordOpen(campaign.id, 'lead@example.com')
    await deps.store.recordClick(campaign.id, 'lead@example.com', 'https://example.com/offer')

    expect(await deps.store.lists()).toEqual([list])
    expect(await deps.store.listSegments(list.id)).toEqual([segment])
    expect(await deps.store.getCampaign(campaign.id)).toEqual({
      ...campaign,
      subject: 'Hello',
      html: '<p>Hello</p>',
      text: 'Hello',
      listIds: [list.id],
      region: 'IL',
    })
    expect(await deps.store.getStats(campaign.id)).toEqual({
      opens: 1,
      clicks: 1,
      bounces: 0,
      unsubs: 0,
    })
    expect(db.__platformMarketingState.campaigns).toEqual(
      expect.arrayContaining([
        expect.objectContaining({
          name: 'Customers',
          targetSegment: expect.objectContaining({ kind: 'platform-list' }),
        }),
        expect.objectContaining({
          name: 'VIP customers',
          targetSegment: expect.objectContaining({ kind: 'platform-segment', listId: list.id }),
        }),
        expect.objectContaining({
          id: campaign.id,
          scheduledAt: '2026-07-10T00:00:00.000Z',
          targetSegment: expect.objectContaining({
            kind: 'platform-campaign',
            stats: { opens: 1, clicks: 1, bounces: 0, unsubs: 0 },
          }),
        }),
      ]),
    )
  })

  it('runs the module compliance gate against the embedded host stores', async () => {
    const db = createStateBackedDb()
    const deps = createPlatformMarketingDeps(db as never, TENANT_ID, () => new Date('2026-07-05T00:00:00.000Z'))

    const list = await deps.store.createList('Newsletter')
    await confirmDoubleOptIn(deps.complianceStore, 'reader@example.com', 'EU', () => '2026-07-05T00:00:00.000Z')
    await deps.store.upsertContact({ email: 'reader@example.com' }, list.id)

    const campaign = await deps.store.createCampaign({
      name: 'Digest',
      subject: 'Weekly digest',
      html: '<p>Digest</p>',
      listIds: [list.id],
      region: 'EU',
    })

    const send = vi.fn(async (_message: unknown) => ({ id: 'msg-1', provider: 'fake' }))
    const adapter = makeSelfManagedAdapter({
      from: 'news@example.com',
      mail: { send },
      store: deps.store,
      complianceStore: deps.complianceStore,
    })

    const result = await adapter.sendCampaign(campaign.id, {
      trackingBaseUrl: 'https://track.example',
      legal,
    })

    expect(result).toEqual({ sent: ['reader@example.com'], refused: [] })
    expect(send).toHaveBeenCalledTimes(1)
    expect(send.mock.calls[0]?.[0]).toEqual(
      expect.objectContaining({
        to: 'reader@example.com',
        headers: expect.objectContaining({
          'List-Unsubscribe': '<https://example.com/unsub/one-click>',
        }),
      }),
    )
  })
})
