import type { Channel } from '@zyphon/shared-types';
import type { ProviderAdapter } from '@zyphon/provider-contracts';
import { MockProvider } from '@zyphon/provider-mock';
import { SmtpProviderAdapter } from '@zyphon/provider-email-smtp';
import { SendGridProviderAdapter } from '@zyphon/provider-email-sendgrid';
import { SesProviderAdapter } from '@zyphon/provider-email-ses';
import { ZohoEmailProviderAdapter } from '@zyphon/provider-email-zoho';
import { MailgunProviderAdapter } from '@zyphon/provider-email-mailgun';
import { TwilioSmsProviderAdapter } from '@zyphon/provider-sms-twilio';
import { Msg91SmsProviderAdapter } from '@zyphon/provider-sms-msg91';
import { Fast2SmsProviderAdapter } from '@zyphon/provider-sms-fast2sms';
import { MetaWhatsAppProviderAdapter } from '@zyphon/provider-whatsapp-meta';
import { TwilioWhatsAppProviderAdapter } from '@zyphon/provider-whatsapp-twilio';
import {
  CatalogStubProvider,
  GenericHttpProvider,
  GupshupSmsProviderAdapter,
  KaleyraSmsProviderAdapter,
  ExotelSmsProviderAdapter,
  GupshupWhatsAppProviderAdapter,
  Dialog360WhatsAppProviderAdapter,
  TelegramBotProviderAdapter,
  TwentyFourSevenSmsProviderAdapter,
} from '@zyphon/provider-generic';
import { getCatalogEntryByType } from '../catalog/provider-catalog.js';

export function createAdapter(provDef: {
  id: string;
  channel: Channel;
  adapter?: string;
  type?: string;
  latency_ms?: number;
  failure_rate?: number;
}): ProviderAdapter {
  const adapterType = provDef.adapter || provDef.type || 'mock';
  switch (adapterType) {
    case 'smtp':
      return new SmtpProviderAdapter({ id: provDef.id });
    case 'sendgrid':
      return new SendGridProviderAdapter({ id: provDef.id });
    case 'ses':
      return new SesProviderAdapter({ id: provDef.id });
    case 'zoho':
      return new ZohoEmailProviderAdapter({ id: provDef.id });
    case 'mailgun':
      return new MailgunProviderAdapter({ id: provDef.id });
    case 'twilio':
      return new TwilioSmsProviderAdapter({ id: provDef.id });
    case 'msg91':
      return new Msg91SmsProviderAdapter({ id: provDef.id });
    case 'fast2sms':
      return new Fast2SmsProviderAdapter({ id: provDef.id });
    case 'gupshup-sms':
      return new GupshupSmsProviderAdapter({ id: provDef.id });
    case 'kaleyra':
      return new KaleyraSmsProviderAdapter({ id: provDef.id });
    case 'exotel':
      return new ExotelSmsProviderAdapter({ id: provDef.id });
    case '24x7sms':
    case '247sms':
      return new TwentyFourSevenSmsProviderAdapter({ id: provDef.id });
    case 'meta-cloud':
    case 'meta':
      return new MetaWhatsAppProviderAdapter({ id: provDef.id });
    case 'twilio-wa':
      return new TwilioWhatsAppProviderAdapter({ id: provDef.id });
    case 'gupshup':
      return new GupshupWhatsAppProviderAdapter({ id: provDef.id });
    case 'd360':
      return new Dialog360WhatsAppProviderAdapter({ id: provDef.id });
    case 'telegram':
      return new TelegramBotProviderAdapter({ id: provDef.id, channel: provDef.channel });
    case 'http':
      return new GenericHttpProvider({ id: provDef.id, channel: provDef.channel });
    case 'mock':
      return new MockProvider({
        id: provDef.id,
        channel: provDef.channel,
        latencyMs: provDef.latency_ms ?? 10,
        failureRate: provDef.failure_rate ?? 0,
      });
    default: {
      const catalogEntry = getCatalogEntryByType(adapterType);
      if (catalogEntry) {
        return new CatalogStubProvider({
          id: provDef.id,
          channel: provDef.channel,
          adapterType,
          fieldSchema: catalogEntry.fieldSchema,
        });
      }
      return new MockProvider({
        id: provDef.id,
        channel: provDef.channel,
        latencyMs: provDef.latency_ms ?? 10,
        failureRate: provDef.failure_rate ?? 0,
      });
    }
  }
}

