/**
 * Payment link service — invoice-payment-link-generation (wave-12).
 *
 * Functions:
 *   paymentLinkStatusForInvoice — derives link state from invoice status (stateless)
 *   tenantHasActiveGateway      — checks payment_gateway_configs for an active row
 *   resolveCustomerPrimaryEmail — reads primary contact email from customer_contacts
 */
import { and, eq } from '@zync/db'
import type { Db } from '@zync/db/queries'
import { paymentGatewayConfigs } from '@zync/db/schema'
import { customerContacts } from '@zync/db/schema'

// ── Types ─────────────────────────────────────────────────────────────────────

export type PaymentLinkState = 'active' | 'inactive'

export interface PaymentLinkStatusResult {
  state: PaymentLinkState
  reason?: string
}

// ── paymentLinkStatusForInvoice ───────────────────────────────────────────────

/**
 * Derive the payment link state from an invoice's status.
 * Exhaustive over all 10 InvoiceStatus values.
 */
export function paymentLinkStatusForInvoice(status: string): PaymentLinkStatusResult {
  switch (status) {
    case 'SENT':
    case 'TAX_ISSUED':
    case 'PARTIALLY_PAID':
      return { state: 'active' }

    case 'PAID':
      return { state: 'inactive', reason: 'Invoice paid — payment link expired' }

    case 'VOID':
      return { state: 'inactive', reason: 'Invoice void' }

    case 'REJECTED':
      return { state: 'inactive', reason: 'Invoice rejected' }

    case 'DRAFT':
    case 'APPROVED':
      return { state: 'inactive', reason: 'Invoice not yet sent' }

    case 'WRITTEN_OFF':
    case 'BAD_DEBT':
      return { state: 'inactive', reason: 'Invoice closed' }

    default:
      // Guard for any future statuses — treat as inactive
      return { state: 'inactive', reason: 'Payment link unavailable' }
  }
}

// ── tenantHasActiveGateway ────────────────────────────────────────────────────

/**
 * Returns true if the tenant has at least one active payment gateway configured.
 */
export async function tenantHasActiveGateway(db: Db, tenantId: string): Promise<boolean> {
  const rows = await db
    .select({ id: paymentGatewayConfigs.id })
    .from(paymentGatewayConfigs)
    .where(
      and(
        eq(paymentGatewayConfigs.tenantId, tenantId),
        eq(paymentGatewayConfigs.isActive, true),
      ),
    )
    .limit(1)

  return rows.length > 0
}

// ── resolveCustomerPrimaryEmail ───────────────────────────────────────────────

/**
 * Resolves the primary email for a customer.
 * Reads from customer_contacts WHERE is_primary = true.
 * Returns null if no primary contact found.
 */
export async function resolveCustomerPrimaryEmail(
  db: Db,
  tenantId: string,
  customerId: string,
): Promise<string | null> {
  const rows = await db
    .select({ email: customerContacts.email })
    .from(customerContacts)
    .where(
      and(
        eq(customerContacts.tenantId, tenantId),
        eq(customerContacts.customerId, customerId),
        eq(customerContacts.isPrimary, true),
      ),
    )
    .limit(1)

  return rows[0]?.email ?? null
}
