/**
 * `@platform-modules/marketing` — newsletter/campaign seam (LCD adapter axis + compliance core).
 */
import {
  executeCompliantSend,
  type CampaignLegalContext,
  type CompliantSendInput,
  type CompliantSendResult,
  type ComplianceStore,
} from './compliance.js'

export type MarketingSupports = {
  segments: boolean
  scheduling: boolean
  automation: boolean
}

export type MarketingContact = {
  email: string
  attributes?: Record<string, string>
  tags?: string[]
}

export type MarketingList = {
  id: string
  name: string
}

export type Campaign = {
  id: string
  name: string
  subject: string
  html: string
  text?: string
  listIds: string[]
  region?: 'US' | 'EU' | 'IL' | (string & {})
}

export type CampaignStats = {
  opens: number
  clicks: number
  bounces: number
  unsubs: number
}

export type SuppressionEntry = {
  email: string
  reason: 'unsubscribe' | 'bounce' | 'complaint' | 'manual'
  suppressedAt: string
}

export type ConsentRecord = {
  email: string
  doubleOptInConfirmed: boolean
  confirmedAt?: string
  trackingConsent: boolean
  trackingConsentAt?: string
  region?: string
}

export type SendCampaignOpts = {
  trackingBaseUrl: string
  legal: CampaignLegalContext
}

export type SendCampaignResult = CompliantSendResult

export interface MarketingAdapter {
  readonly name: string
  readonly supports: MarketingSupports
  upsertContact(contact: MarketingContact, listId?: string): Promise<void>
  removeContact(email: string, listId?: string): Promise<void>
  tagContact(email: string, tag: string): Promise<void>
  createList(name: string): Promise<MarketingList>
  lists(): Promise<MarketingList[]>
  createCampaign(campaign: Omit<Campaign, 'id'>): Promise<Campaign>
  sendCampaign(campaignId: string, opts: SendCampaignOpts): Promise<SendCampaignResult>
  campaignStats(campaignId: string): Promise<CampaignStats>
  syncSuppression(): Promise<SuppressionEntry[]>
}

export class MarketingError extends Error {}

export class UnsupportedOperation extends MarketingError {
  override readonly name = 'UnsupportedOperation'

  constructor(
    readonly capability: 'segments' | 'scheduling' | 'automation',
    message?: string,
  ) {
    super(message ?? `adapter does not support capability: ${capability}`)
  }
}

export class MarketingProviderError extends MarketingError {
  override readonly name = 'MarketingProviderError'

  constructor(
    message: string,
    readonly provider: string,
    readonly retryable = false,
    readonly cause?: unknown,
  ) {
    super(message)
  }
}

export type MarketingAdapterName = 'self-managed' | 'brevo'

export type MarketingAdapterFactory = (
  creds: unknown,
  deps?: MarketingAdapterDeps,
) => MarketingAdapter

export type MarketingAdapterDeps = {
  complianceStore?: ComplianceStore
}

const adapterFactories: Partial<Record<MarketingAdapterName, MarketingAdapterFactory>> = {}

export function registerMarketingAdapter(
  name: MarketingAdapterName,
  factory: MarketingAdapterFactory,
): void {
  adapterFactories[name] = factory
}

export function getAdapter(
  name: string,
  creds: unknown,
  deps?: MarketingAdapterDeps,
): MarketingAdapter {
  const factory = adapterFactories[name as MarketingAdapterName]
  if (!factory) {
    throw new Error(
      `No marketing adapter factory registered for "${name}". Import @platform-modules/marketing/${name} to register it.`,
    )
  }
  return factory(creds, deps)
}

export function requireCapability(
  adapter: MarketingAdapter,
  capability: keyof MarketingSupports,
): void {
  if (!adapter.supports[capability]) {
    throw new UnsupportedOperation(capability)
  }
}

/** Shared compliant send orchestration — adapters call this; never bypass. */
export async function sendCampaignThroughCompliance(
  store: ComplianceStore,
  input: CompliantSendInput,
  sendOne: Parameters<typeof executeCompliantSend>[2],
): Promise<CompliantSendResult> {
  return executeCompliantSend(store, input, sendOne)
}

export {
  ComplianceError,
  applyTracking,
  assertRecipientEligible,
  buildRfc8058Headers,
  confirmDoubleOptIn,
  createMemoryComplianceStore,
  executeCompliantSend,
  recordTrackingConsent,
  validatePreSendLegalGate,
  type CampaignLegalContext,
  type CompliantRecipientMessage,
  type CompliantSendInput,
  type CompliantSendResult,
  type ComplianceRegion,
  type ComplianceStore,
  type SenderLegalDeclaration,
  type SendCampaignRefusal,
  type TrackingOpts,
} from './compliance.js'
