import type { Channel, NormalizedMessage, ResolvedCredentials } from '@zyphon/shared-types';
import type {
  FieldSchema,
  ProviderAdapter,
  ProviderHealth,
  ProviderResult,
} from '@zyphon/provider-contracts';

export class CatalogStubProvider implements ProviderAdapter {
  public readonly id: string;
  public readonly channel: Channel;
  public readonly fieldSchema: FieldSchema[];
  private readonly adapterType: string;

  constructor(options: {
    id: string;
    channel: Channel;
    adapterType: string;
    fieldSchema: FieldSchema[];
  }) {
    this.id = options.id;
    this.channel = options.channel;
    this.adapterType = options.adapterType;
    this.fieldSchema = options.fieldSchema;
  }

  public async validateConfiguration(c: ResolvedCredentials): Promise<void> {
    const required = this.fieldSchema.filter((f) => f.required !== false && !f.optional && f.type === 'secret');
    for (const field of required) {
      const val = c[field.key];
      if (val === undefined || val === null || String(val).trim() === '') {
        throw new Error(`${this.adapterType} is not configured: missing '${field.key}'`);
      }
    }
  }

  public async send(
    _m: NormalizedMessage,
    c: ResolvedCredentials,
    _signal: AbortSignal,
  ): Promise<ProviderResult> {
    try {
      await this.validateConfiguration(c);
    } catch (err: any) {
      return {
        success: false,
        error: {
          code: 'CREDENTIAL_ERROR',
          message: err.message || 'Provider credentials are not configured',
        },
      };
    }
    return {
      success: false,
      error: {
        code: 'PROVIDER_REJECTED',
        message: `Adapter '${this.adapterType}' is catalog-only; outbound send is not implemented yet`,
      },
    };
  }

  public async healthCheck(c: ResolvedCredentials): Promise<ProviderHealth> {
    try {
      await this.validateConfiguration(c);
      return {
        status: 'degraded',
        latency_ms: 0,
        checked_at: Date.now(),
        message: 'Catalog stub: credentials present but send not implemented',
      };
    } catch (err: any) {
      return {
        status: 'down',
        latency_ms: 0,
        checked_at: Date.now(),
        message: err.message,
      };
    }
  }
}
