import type { InvoiceProvider } from '../port.js'
import type { DocumentSpec, InvoiceDocumentResult } from '../types.js'
import { createMorningClient, type MorningClient } from './client.js'
import {
  validateMorningCredentials,
  type MorningClientOptions,
} from './types.js'

export class MorningProvider implements InvoiceProvider {
  readonly kind = 'morning'
  readonly client: MorningClient

  constructor(options: MorningClientOptions = {}) {
    this.client = createMorningClient(options)
  }

  async validateCredentials(
    credential: unknown,
  ): Promise<{ ok: true } | { ok: false; reason: string }> {
    const result = validateMorningCredentials(credential)
    if (!result.ok) {
      return { ok: false, reason: result.error.message }
    }

    return { ok: true }
  }

  async issue(credential: unknown, spec: DocumentSpec): Promise<InvoiceDocumentResult> {
    const result = validateMorningCredentials(credential)
    if (!result.ok) {
      throw result.error
    }

    const accessToken = await this.client.exchangeToken(result.credentials)
    return this.client.createDocument(accessToken, result.credentials, spec)
  }
}

export { createMorningClient } from './client.js'
export {
  invalidMorningCredentialsError,
  isMorningCredentials,
  validateMorningCredentials,
} from './types.js'
export type { MorningClient } from './client.js'
export type {
  MorningClientOptions,
  MorningCredentials,
  MorningDocumentResponse,
  MorningTokenResponse,
} from './types.js'
