/**
 * NullPaymentAdapter — zync-subscription spec (Task 5).
 *
 * Ships with the platform as the default adapter (ZYNC_PAYMENT_ADAPTER='null').
 * Operates without any external payment provider:
 *  - createCheckoutSession → throws PaymentProviderNotConfiguredError
 *  - getSubscriptionStatus → reads zync_subscriptions.status directly from DB
 *  - updateSubscription / cancelSubscription → mutates DB directly, logs action
 *  - getInvoiceHistory → []
 *  - handleWebhook → throws (webhook endpoint returns 501)
 *  - getBillingPortalUrl → null
 *
 * This adapter enables the full subscription UI to be used and tested before
 * any real payment integration exists. Ops provisions tenants via admin override.
 */
import type { TenantTier } from '@zync/types'
import type { ZyncPaymentAdapter, ZyncSubscriptionStatus, ZyncInvoice, WebhookEvent } from './types'
import { PaymentProviderNotConfiguredError } from './errors'
import type { Db } from '@zync/db/queries'
import {
  getSubscriptionByTenantId,
  cancelSubscription,
  updateSubscriptionTier,
} from '@zync/db/queries'

export class NullPaymentAdapter implements ZyncPaymentAdapter {
  private readonly db: Db

  constructor(db: Db) {
    this.db = db
  }

  async createCheckoutSession(
    _tenantId: string,
    _tier: TenantTier,
    _period: 'monthly' | 'annual',
  ): Promise<{ checkoutUrl: string; sessionId: string }> {
    throw new PaymentProviderNotConfiguredError()
  }

  async getSubscriptionStatus(tenantId: string): Promise<ZyncSubscriptionStatus> {
    const sub = await getSubscriptionByTenantId(this.db, tenantId)
    if (!sub) return 'active' // default for tenants without a row
    return sub.status as ZyncSubscriptionStatus
  }

  async updateSubscription(tenantId: string, newTier: TenantTier): Promise<void> {
    await updateSubscriptionTier(this.db, tenantId, newTier)
    console.log(`[NullPaymentAdapter] updateSubscription: tenant=${tenantId} -> tier=${newTier}`)
  }

  async cancelSubscription(tenantId: string): Promise<{ effectiveDate: Date }> {
    const sub = await getSubscriptionByTenantId(this.db, tenantId)
    // Effective date: end of current period if known, else now
    const effectiveDate = sub?.currentPeriodEnd ?? new Date()
    await cancelSubscription(this.db, tenantId)
    console.log(`[NullPaymentAdapter] cancelSubscription: tenant=${tenantId} effectiveDate=${effectiveDate.toISOString()}`)
    return { effectiveDate }
  }

  async getInvoiceHistory(_tenantId: string): Promise<ZyncInvoice[]> {
    return []
  }

  async handleWebhook(_payload: unknown, _signature: string): Promise<WebhookEvent> {
    throw new Error('NullPaymentAdapter does not support webhooks')
  }

  async getBillingPortalUrl(_tenantId: string): Promise<string | null> {
    return null
  }
}
