import type { ProviderCatalogEntry } from '@zyphon/provider-contracts';
import { FROM_EMAIL, sl, sx, tx } from './field-helpers.js';

const AWS_REGIONS = [
  { value: 'ap-south-1', label: 'Asia Pacific (Mumbai)' },
  { value: 'ap-south-2', label: 'Asia Pacific (Hyderabad)' },
  { value: 'ap-southeast-1', label: 'Asia Pacific (Singapore)' },
  { value: 'us-east-1', label: 'US East (N. Virginia)' },
  { value: 'us-west-2', label: 'US West (Oregon)' },
  { value: 'eu-west-1', label: 'Europe (Ireland)' },
  { value: 'eu-central-1', label: 'Europe (Frankfurt)' },
];

const DLT_SECTION = 'India DLT';
const DLT_NOTE = 'Required by TRAI for every SMS to Indian numbers.';

const dltHeader = (required = true) =>
  tx('sender_id', 'Sender ID (header)', {
    placeholder: 'ACMEIN',
    validator: 'header',
    dlt: true,
    section: DLT_SECTION,
    required,
  });

const dltPe = (optional = false) =>
  tx('pe_id', 'Principal Entity ID', {
    placeholder: '19-digit number',
    validator: 'digits19',
    dlt: true,
    section: DLT_SECTION,
    optional,
    help: 'Shown at the top of your DLT portal.',
  });

const HTTP_FIELDS = [
  tx('url', 'Endpoint URL', { placeholder: 'https://api.example.com/send', validator: 'url' }),
  sx('auth', 'Authorization header', { placeholder: 'Bearer …', optional: true }),
  tx('body', 'Body template', {
    placeholder: '{"to":"{{to}}","text":"{{body}}"}',
    type: 'textarea',
  }),
];

function httpEntry(channel: ProviderCatalogEntry['channel']): ProviderCatalogEntry {
  return {
    type: 'http',
    name: 'Custom HTTP provider',
    description: 'Any provider with a REST API (e.g. Jio / enterprise SMS URL). You define the request.',
    channel,
    markets: ['india', 'global'],
    fieldSchema: HTTP_FIELDS,
    max_rps: 30,
    cost_per_message: 0,
  };
}

const ENTRIES: ProviderCatalogEntry[] = [
  // Email
  {
    type: 'smtp',
    name: 'SMTP server',
    description: 'Gmail, Zoho Mail, or any SMTP host. Standard host / port / login.',
    channel: 'email',
    markets: ['india', 'global'],
    max_rps: 20,
    cost_per_message: 0,
    help: 'Gmail: smtp.gmail.com, STARTTLS 587, use an App Password (not your Google password). Zoho Mail: smtp.zoho.in, STARTTLS 587.',
    fieldSchema: [
      tx('host', 'Host', {
        section: 'Server',
        placeholder: 'smtp.gmail.com',
        validator: 'host',
        help: 'smtp.gmail.com · smtp.zoho.in · your company SMTP',
      }),
      sl('security', 'Security', [
        { value: 'starttls', label: 'STARTTLS (port 587)' },
        { value: 'ssl', label: 'SSL/TLS (port 465)' },
        { value: 'none', label: 'None (port 25)' },
      ], { section: 'Server', default: 'starttls' }),
      tx('port', 'Port', { section: 'Server', default: '587', validator: 'port' }),
      tx('username', 'Username', { section: 'Login', help: 'Usually your full email address.' }),
      sx('password', 'Password or app password', {
        section: 'Login',
        help: 'Gmail and Zoho need an app-specific password when 2FA is on.',
      }),
      tx('from_name', 'From name', { section: 'Sender', optional: true }),
      tx('from', 'From address', { section: 'Sender', validator: 'email' }),
    ],
  },
  {
    type: 'sendgrid',
    name: 'SendGrid',
    description: 'Twilio SendGrid v3 Mail Send API.',
    channel: 'email',
    markets: ['india', 'global'],
    max_rps: 100,
    cost_per_message: 0.0001,
    fieldSchema: [sx('api_key', 'API key', { placeholder: 'SG.…' }), FROM_EMAIL],
  },
  {
    type: 'ses',
    name: 'Amazon SES',
    description: 'AWS Simple Email Service v2 (Mumbai / Hyderabad regions supported).',
    channel: 'email',
    markets: ['india', 'global'],
    max_rps: 50,
    cost_per_message: 0.0001,
    fieldSchema: [
      sl('region', 'AWS region', AWS_REGIONS, { default: 'ap-south-1' }),
      tx('access_key', 'Access key ID'),
      sx('secret', 'Secret access key'),
      FROM_EMAIL,
    ],
  },
  {
    type: 'zoho',
    name: 'Zoho ZeptoMail',
    description: 'Zoho transactional email API (India data centre available).',
    channel: 'email',
    markets: ['india', 'global'],
    max_rps: 40,
    cost_per_message: 0.0001,
    help: 'Create a Send Mail token in ZeptoMail. Prefer India (.in) for Indian senders.',
    fieldSchema: [
      sx('token', 'Send Mail token', { help: 'From ZeptoMail → SMTP & API → Send Mail Token.' }),
      sl('region', 'Data centre', [
        { value: 'zeptomail.zoho.in', label: 'India (.in)' },
        { value: 'zeptomail.zoho.com', label: 'Global (.com)' },
        { value: 'zeptomail.zoho.eu', label: 'Europe (.eu)' },
      ], { default: 'zeptomail.zoho.in' }),
      FROM_EMAIL,
    ],
  },
  {
    type: 'mailgun',
    name: 'Mailgun',
    description: 'Mailgun transactional email API.',
    channel: 'email',
    markets: ['india', 'global'],
    max_rps: 80,
    cost_per_message: 0.0008,
    fieldSchema: [sx('api_key', 'API key'), tx('domain', 'Sending domain', { placeholder: 'mg.company.com' }), FROM_EMAIL],
  },
  {
    type: 'postmark',
    name: 'Postmark',
    description: 'Fast transactional email.',
    channel: 'email',
    max_rps: 60,
    cost_per_message: 0.001,
    fieldSchema: [sx('token', 'Server token'), FROM_EMAIL],
  },
  {
    type: 'brevo',
    name: 'Brevo (Sendinblue)',
    description: 'Brevo transactional email API.',
    channel: 'email',
    max_rps: 50,
    cost_per_message: 0.0005,
    fieldSchema: [sx('api_key', 'API key'), FROM_EMAIL],
  },
  {
    type: 'resend',
    name: 'Resend',
    description: 'Developer-friendly email API.',
    channel: 'email',
    max_rps: 50,
    cost_per_message: 0.0004,
    fieldSchema: [sx('api_key', 'API key', { placeholder: 're_…' }), FROM_EMAIL],
  },
  {
    type: 'mailjet',
    name: 'Mailjet',
    description: 'Mailjet Send API v3.1.',
    channel: 'email',
    max_rps: 40,
    cost_per_message: 0.0005,
    fieldSchema: [tx('api_key', 'API key'), sx('secret', 'Secret key'), FROM_EMAIL],
  },
  {
    type: 'sparkpost',
    name: 'SparkPost',
    description: 'SparkPost / Bird email.',
    channel: 'email',
    max_rps: 40,
    cost_per_message: 0.0005,
    fieldSchema: [sx('api_key', 'API key'), FROM_EMAIL],
  },
  {
    type: 'm365',
    name: 'Microsoft 365',
    description: 'Send through Microsoft Graph.',
    channel: 'email',
    max_rps: 30,
    cost_per_message: 0,
    fieldSchema: [
      tx('tenant', 'Tenant ID'),
      tx('client_id', 'Client ID'),
      sx('client_secret', 'Client secret'),
      FROM_EMAIL,
    ],
  },
  {
    type: 'mandrill',
    name: 'Mailchimp Transactional',
    description: 'Mandrill API.',
    channel: 'email',
    max_rps: 40,
    cost_per_message: 0.0002,
    fieldSchema: [sx('api_key', 'API key'), FROM_EMAIL],
  },
  httpEntry('email'),

  // SMS
  {
    type: 'twilio',
    name: 'Twilio SMS',
    description: 'Global programmable SMS (Twilio Console / Messaging API).',
    channel: 'sms',
    markets: ['global'],
    max_rps: 30,
    cost_per_message: 0.0075,
    help: 'Trial Twilio accounts cannot send free-form SMS. Body must be a Twilio trial template key (sms_2fa, sms_order_confirmation, …) — the same keys used on Twilio Console → Try out SMS. Upgrade the Twilio account for custom message text. Recipient must be a verified number on trial.',
    fieldSchema: [
      tx('sid', 'Account SID', { placeholder: 'AC…', section: 'Account' }),
      sx('token', 'Auth token', { section: 'Account' }),
      tx('from', 'From number', {
        placeholder: '+14155550100',
        validator: 'phone',
        section: 'Account',
        help: 'Use your Twilio trial SMS number while on trial.',
      }),
      sl(
        'account_mode',
        'Account mode',
        [
          { value: 'trial', label: 'Trial (use Twilio template keys as Body)' },
          { value: 'paid', label: 'Paid / upgraded (free-form Body allowed)' },
        ],
        {
          section: 'Trial',
          help: 'Trial mode sends Twilio template keys (sms_2fa, …) instead of custom text.',
        },
      ),
      sl(
        'default_template',
        'Default trial template',
        [
          { value: 'sms_2fa', label: 'sms_2fa — Two-factor / OTP' },
          { value: 'sms_appointment_reminders', label: 'sms_appointment_reminders' },
          { value: 'sms_order_confirmation', label: 'sms_order_confirmation' },
          { value: 'sms_delivery_updates', label: 'sms_delivery_updates' },
          { value: 'sms_customer_support', label: 'sms_customer_support' },
          { value: 'sms_marketing_promotions', label: 'sms_marketing_promotions' },
          { value: 'sms_event_notifications', label: 'sms_event_notifications' },
          { value: 'sms_account_alerts', label: 'sms_account_alerts' },
          { value: 'sms_feedback_surveys', label: 'sms_feedback_surveys' },
          { value: 'sms_internal_alerts', label: 'sms_internal_alerts' },
        ],
        {
          section: 'Trial',
          optional: true,
          help: 'Used when sending without an explicit template on a trial account.',
        },
      ),
    ],
  },
  {
    type: 'msg91',
    name: 'MSG91',
    description: 'India. Flow / DLT SMS (most common for OTP and alerts).',
    channel: 'sms',
    dlt: true,
    markets: ['india'],
    max_rps: 25,
    cost_per_message: 0.002,
    help: 'Sends via MSG91 Flow API. Body must match a DLT-approved template; pass template_id and variable names exactly as in MSG91 (case-sensitive). Whitelist this server IP under MSG91 → API → IP Security.',
    fieldSchema: [
      sx('auth_key', 'Auth key', {
        section: 'Account',
        help: 'From MSG91 dashboard → API.',
      }),
      sl(
        'route',
        'Route',
        [
          { value: '4', label: 'Transactional (route 4)' },
          { value: '1', label: 'Promotional (route 1)' },
          { value: 'otp', label: 'OTP' },
        ],
        { section: 'Account', default: '4' },
      ),
      {
        ...dltHeader(),
        help: 'DLT-approved sender header, usually 6 letters (e.g. ACMEIN).',
      },
      {
        ...dltPe(),
        help: '19-digit Principal Entity ID from your DLT portal (Jio / Airtel / VI / BSNL).',
      },
      tx('template_id', 'Default MSG91 template / flow ID', {
        section: DLT_SECTION,
        sectionNote: DLT_NOTE,
        optional: true,
        dlt: true,
        help: 'Used when a send does not pass its own template_id. Must be the MSG91 template mapped to your DLT content.',
      }),
      tx('country', 'Default country code', {
        default: '91',
        validator: 'num',
        help: 'Mobiles are sent as 91XXXXXXXXXX.',
      }),
    ],
  },
  {
    type: 'fast2sms',
    name: 'Fast2SMS',
    description: 'India. DLT SMS via Fast2SMS Dev API.',
    channel: 'sms',
    dlt: true,
    markets: ['india'],
    max_rps: 20,
    cost_per_message: 0.0015,
    help: 'DLT route does not take free-form text: "message" is the Message ID from Fast2SMS DLT Manager. Variable values are pipe-separated (var1|var2).',
    fieldSchema: [
      sx('api_key', 'API key (Authorization header)', {
        section: 'Account',
        help: 'From Fast2SMS → Dev API.',
      }),
      sl(
        'route',
        'Route',
        [
          { value: 'dlt', label: 'DLT SMS (Message ID in DLT Manager)' },
          { value: 'dlt_manual', label: 'DLT manual (entity + template + text)' },
          { value: 'q', label: 'Quick SMS (no DLT, limited)' },
          { value: 'otp', label: 'OTP' },
        ],
        { section: 'Account', default: 'dlt' },
      ),
      {
        ...dltHeader(),
        help: '3–6 letter DLT header registered in Fast2SMS DLT Manager.',
      },
      tx('entity_id', 'Principal Entity ID', {
        section: DLT_SECTION,
        sectionNote: DLT_NOTE,
        validator: 'digits19',
        dlt: true,
        optional: true,
        help: 'Required for dlt_manual if the template is not already in DLT Manager.',
      }),
      tx('template_id', 'Default DLT template / message ID', {
        section: DLT_SECTION,
        optional: true,
        dlt: true,
        help: 'Default Fast2SMS Message ID or DLT Template ID when a send does not specify one.',
      }),
    ],
  },
  {
    type: 'vonage',
    name: 'Vonage SMS',
    description: 'Vonage SMS API.',
    channel: 'sms',
    max_rps: 30,
    cost_per_message: 0.006,
    fieldSchema: [tx('api_key', 'API key'), sx('api_secret', 'API secret'), tx('sender', 'Sender ID or number')],
  },
  {
    type: 'plivo',
    name: 'Plivo',
    description: 'Plivo SMS API.',
    channel: 'sms',
    max_rps: 25,
    cost_per_message: 0.005,
    fieldSchema: [tx('auth_id', 'Auth ID'), sx('auth_token', 'Auth token'), tx('from', 'From number', { validator: 'phone' })],
  },
  {
    type: 'sns',
    name: 'Amazon SNS',
    description: 'AWS text messages.',
    channel: 'sms',
    dlt: true,
    max_rps: 20,
    cost_per_message: 0.006,
    fieldSchema: [
      sl('region', 'AWS region', AWS_REGIONS, { default: 'ap-south-1' }),
      tx('access_key', 'Access key ID'),
      sx('secret', 'Secret access key'),
      dltHeader(),
      dltPe(),
    ],
  },
  {
    type: 'sinch',
    name: 'Sinch',
    description: 'Sinch SMS REST API.',
    channel: 'sms',
    max_rps: 25,
    cost_per_message: 0.005,
    fieldSchema: [tx('plan_id', 'Service plan ID'), sx('api_token', 'API token'), tx('from', 'From number', { validator: 'phone' })],
  },
  {
    type: 'infobip',
    name: 'Infobip',
    description: 'Infobip SMS API.',
    channel: 'sms',
    max_rps: 30,
    cost_per_message: 0.004,
    fieldSchema: [
      tx('base_url', 'Base URL', { placeholder: 'xxxx.api.infobip.com', validator: 'host' }),
      sx('api_key', 'API key'),
      tx('sender', 'Sender'),
    ],
  },
  {
    type: 'bird',
    name: 'Bird (MessageBird)',
    description: 'Bird SMS API.',
    channel: 'sms',
    max_rps: 25,
    cost_per_message: 0.005,
    fieldSchema: [sx('access_key', 'Access key'), tx('sender', 'Originator')],
  },
  {
    type: 'gupshup-sms',
    name: 'Gupshup Enterprise SMS',
    description: 'India. Enterprise SMS GatewayAPI with DLT.',
    channel: 'sms',
    dlt: true,
    markets: ['india'],
    max_rps: 20,
    cost_per_message: 0.002,
    help: 'API uses userid + password. Each send needs principalEntityId + dltTemplateId; message text must match the DLT-approved template exactly.',
    fieldSchema: [
      tx('userid', 'User ID', { section: 'Account', help: 'Gupshup Enterprise SMS account user id.' }),
      sx('password', 'Password', { section: 'Account' }),
      {
        ...dltHeader(),
        help: 'Sender header registered on DLT and with Gupshup.',
      },
      {
        ...dltPe(),
        key: 'pe_id',
        label: 'Principal Entity ID',
        help: 'principalEntityId from your DLT operator portal.',
      },
      tx('template_id', 'Default DLT template ID', {
        section: DLT_SECTION,
        optional: true,
        dlt: true,
        help: 'dltTemplateId used when a send does not pass its own template id.',
      }),
    ],
  },
  {
    type: 'kaleyra',
    name: 'Kaleyra',
    description: 'India / APAC SMS API with DLT support.',
    channel: 'sms',
    dlt: true,
    markets: ['india'],
    max_rps: 25,
    cost_per_message: 0.003,
    fieldSchema: [
      sx('api_key', 'API key', { section: 'Account' }),
      tx('sid', 'SID', { section: 'Account' }),
      tx('host', 'API host', { section: 'Account', default: 'api.kaleyra.io', validator: 'host' }),
      dltHeader(),
      dltPe(true),
      tx('template_id', 'Default DLT template ID', {
        section: DLT_SECTION,
        optional: true,
        dlt: true,
        help: 'template_id used when a send does not pass its own DLT template id.',
      }),
    ],
  },
  {
    type: 'exotel',
    name: 'Exotel',
    description: 'India Exotel SMS API.',
    channel: 'sms',
    dlt: true,
    markets: ['india'],
    max_rps: 20,
    cost_per_message: 0.002,
    fieldSchema: [
      tx('sid', 'Account SID', { section: 'Account' }),
      tx('api_key', 'API key', { section: 'Account' }),
      sx('api_token', 'API token', { section: 'Account' }),
      dltHeader(),
      dltPe(),
      tx('template_id', 'Default DLT template ID', {
        section: DLT_SECTION,
        optional: true,
        dlt: true,
        help: 'DltTemplateId used when a send does not pass its own DLT template id.',
      }),
    ],
  },
  {
    type: '24x7sms',
    name: '24x7SMS',
    description: 'India. 24x7SMS Enterprise Bulk SMS Gateway API with DLT.',
    channel: 'sms',
    dlt: true,
    markets: ['india'],
    max_rps: 30,
    cost_per_message: 0.0018,
    help: 'API uses APIKEY from 24x7sms user panel. Each message requires an approved Sender ID and DLT Template ID.',
    fieldSchema: [
      sx('api_key', 'API Key', { section: 'Account', help: 'Your 24x7sms API Key from the user panel.' }),
      dltHeader(),
      dltPe(),
      tx('template_id', 'Default DLT Template ID', {
        section: DLT_SECTION,
        optional: true,
        dlt: true,
        help: 'DLT Template ID registered with 24x7sms and telecom operators.',
      }),
      tx('service_name', 'Service / Route Name', {
        section: 'Account',
        default: 'TEMPLATE_BASED',
        optional: true,
        help: 'Service route name (e.g. TEMPLATE_BASED).',
      }),
      tx('host', 'API Host', {
        section: 'Account',
        default: 'websms.24x7sms.com',
        optional: true,
        validator: 'host',
      }),
    ],
  },
  httpEntry('sms'),

  // WhatsApp
  {
    type: 'meta',
    name: 'WhatsApp Cloud API',
    description: 'Meta WhatsApp Business Platform (used across India).',
    channel: 'whatsapp',
    markets: ['india', 'global'],
    max_rps: 40,
    cost_per_message: 0.005,
    help: 'Outside the 24h customer window you must send pre-approved WhatsApp templates, not free-form text. Phone number ID and WABA ID are from Meta Business Suite.',
    fieldSchema: [
      tx('phone_id', 'Phone number ID', {
        section: 'Meta',
        help: 'WhatsApp → API Setup → Phone number ID.',
      }),
      tx('waba', 'WhatsApp Business Account ID', { section: 'Meta' }),
      sx('token', 'Permanent access token', {
        section: 'Meta',
        help: 'System user permanent token (not a short-lived user token).',
      }),
      sx('app_secret', 'App secret', { section: 'Meta', optional: true }),
    ],
  },
  {
    type: 'meta-cloud',
    name: 'WhatsApp Cloud API',
    description: 'Meta WhatsApp Business Platform.',
    channel: 'whatsapp',
    markets: ['global'],
    max_rps: 40,
    cost_per_message: 0.005,
    fieldSchema: [
      tx('phone_id', 'Phone number ID'),
      tx('waba', 'WhatsApp Business Account ID'),
      sx('token', 'Permanent access token'),
    ],
  },
  {
    type: 'twilio-wa',
    name: 'Twilio WhatsApp',
    description: 'WhatsApp through Twilio.',
    channel: 'whatsapp',
    markets: ['global'],
    max_rps: 30,
    cost_per_message: 0.005,
    fieldSchema: [tx('sid', 'Account SID'), sx('token', 'Auth token'), tx('from', 'WhatsApp number', { validator: 'phone' })],
  },
  {
    type: 'gupshup',
    name: 'Gupshup WhatsApp',
    description: 'India-friendly Gupshup WhatsApp Business API.',
    channel: 'whatsapp',
    markets: ['india'],
    max_rps: 25,
    cost_per_message: 0.004,
    help: 'Template messages must use Gupshup-approved template names; free-form only inside an open session.',
    fieldSchema: [
      sx('api_key', 'API key', { section: 'Account' }),
      tx('app', 'App name', { section: 'Account', help: 'Gupshup app / bot name.' }),
      tx('source', 'WhatsApp number', {
        section: 'Account',
        validator: 'phone',
        help: 'Business WhatsApp number in international format.',
      }),
    ],
  },
  {
    type: 'd360',
    name: '360dialog',
    description: '360dialog WhatsApp Business API (common BSP in India).',
    channel: 'whatsapp',
    markets: ['india'],
    max_rps: 25,
    cost_per_message: 0.004,
    fieldSchema: [
      sx('api_key', 'D360 API key'),
      tx('base_url', 'Base URL', { default: 'https://waba-v2.360dialog.io', validator: 'url' }),
    ],
  },
  {
    type: 'infobip-wa',
    name: 'Infobip WhatsApp',
    description: 'Infobip WhatsApp channel.',
    channel: 'whatsapp',
    max_rps: 25,
    cost_per_message: 0.005,
    fieldSchema: [
      tx('base_url', 'Base URL', { validator: 'host' }),
      sx('api_key', 'API key'),
      tx('sender', 'Sender number', { validator: 'phone' }),
    ],
  },
  {
    type: 'bird-wa',
    name: 'Bird WhatsApp',
    description: 'Bird WhatsApp.',
    channel: 'whatsapp',
    max_rps: 25,
    cost_per_message: 0.005,
    fieldSchema: [sx('access_key', 'Access key'), tx('channel_id', 'Channel ID')],
  },
  httpEntry('whatsapp'),

  // Push
  {
    type: 'fcm',
    name: 'Firebase Cloud Messaging',
    description: 'Android, iOS and web push.',
    channel: 'push',
    max_rps: 100,
    cost_per_message: 0,
    fieldSchema: [tx('project_id', 'Project ID'), sx('service_account', 'Service account JSON', { type: 'textarea' })],
  },
  {
    type: 'onesignal',
    name: 'OneSignal',
    description: 'Push and in-app messaging.',
    channel: 'push',
    max_rps: 80,
    cost_per_message: 0,
    fieldSchema: [tx('app_id', 'App ID'), sx('rest_key', 'REST API key')],
  },
  {
    type: 'apns',
    name: 'Apple Push (APNs)',
    description: 'Direct iOS push.',
    channel: 'push',
    max_rps: 50,
    cost_per_message: 0,
    fieldSchema: [
      tx('team_id', 'Team ID'),
      tx('key_id', 'Key ID'),
      tx('bundle', 'Bundle ID'),
      sx('private_key', 'Private key (.p8)'),
    ],
  },
  {
    type: 'expo',
    name: 'Expo Push',
    description: 'React Native and Expo apps.',
    channel: 'push',
    max_rps: 60,
    cost_per_message: 0,
    fieldSchema: [sx('token', 'Access token', { optional: true })],
  },
  httpEntry('push'),

  // Chat
  {
    type: 'slack',
    name: 'Slack',
    description: 'Incoming webhook to a channel.',
    channel: 'chat',
    max_rps: 30,
    cost_per_message: 0,
    fieldSchema: [sx('webhook', 'Webhook URL', { validator: 'url' })],
  },
  {
    type: 'teams',
    name: 'Microsoft Teams',
    description: 'Workflow webhook to Teams.',
    channel: 'chat',
    max_rps: 30,
    cost_per_message: 0,
    fieldSchema: [sx('webhook', 'Webhook URL', { validator: 'url' })],
  },
  {
    type: 'telegram',
    name: 'Telegram Bot',
    description: 'Send via BotFather bot token.',
    channel: 'chat',
    markets: ['india', 'global'],
    max_rps: 30,
    cost_per_message: 0,
    help: 'Create a bot with @BotFather and paste the token. Recipient is a chat_id (user or group).',
    fieldSchema: [
      sx('bot_token', 'Bot token', { help: 'From BotFather → /newbot.' }),
    ],
  },
  {
    type: 'discord',
    name: 'Discord',
    description: 'Channel webhook.',
    channel: 'chat',
    max_rps: 30,
    cost_per_message: 0,
    fieldSchema: [sx('webhook', 'Webhook URL', { validator: 'url' })],
  },
  httpEntry('chat'),

  // Mock / dev
  {
    type: 'mock',
    name: 'Mock provider',
    description: 'Simulated delivery for tests and development.',
    channel: 'email',
    max_rps: 1000,
    cost_per_message: 0,
    fieldSchema: [],
  },
];

const byType = new Map<string, ProviderCatalogEntry>();
for (const e of ENTRIES) {
  if (!byType.has(e.type)) {
    byType.set(e.type, e);
  }
}

export function getProviderCatalog(): ProviderCatalogEntry[] {
  return ENTRIES;
}

export function getCatalogEntryByType(type: string): ProviderCatalogEntry | undefined {
  return byType.get(type);
}

export function isDltAdapterType(type: string): boolean {
  return Boolean(byType.get(type)?.dlt);
}

/** Connect dialog shows all providers by default (India DLT + Global like Twilio/SES/SendGrid + Custom HTTP). */
const CATALOG_MARKET: 'india' | 'global' | 'all' = 'all';

export function buildAdminCatalogResponse(
  market: 'india' | 'global' | 'all' = CATALOG_MARKET,
): Record<string, ProviderCatalogEntry[]> {
  const grouped: Record<string, ProviderCatalogEntry[]> = {
    email: [],
    sms: [],
    whatsapp: [],
    push: [],
    chat: [],
  };
  for (const entry of ENTRIES) {
    if (entry.type === 'mock') continue;
    const markets = entry.markets ?? ['global'];
    if (market !== 'all' && !markets.includes(market as 'india' | 'global')) continue;
    const ch = entry.channel;
    if (!grouped[ch]) grouped[ch] = [];
    if (!grouped[ch]!.some((e) => e.type === entry.type || e.name === entry.name)) {
      grouped[ch]!.push(entry);
    }
  }
  return grouped;
}
