/**
 * Twilio WhatsApp Provider
 *
 * Uses Twilio's WhatsApp API for sending messages.
 * Docs: https://www.twilio.com/docs/whatsapp
 */

import type { WhatsAppProvider, WhatsAppResult } from './index'

export class TwilioWhatsAppProvider implements WhatsAppProvider {
  private baseUrl: string

  constructor(
    private accountSid: string,
    private authToken: string,
    private fromNumber: string
  ) {
    this.baseUrl = `https://api.twilio.com/2010-04-01/Accounts/${accountSid}/Messages.json`
  }

  /**
   * Send a text message via Twilio WhatsApp
   */
  async sendText(to: string, body: string): Promise<WhatsAppResult> {
    try {
      const formData = new URLSearchParams({
        From: `whatsapp:${formatPhoneNumber(this.fromNumber)}`,
        To: `whatsapp:${formatPhoneNumber(to)}`,
        Body: body,
      })

      const response = await fetch(this.baseUrl, {
        method: 'POST',
        headers: {
          Authorization: `Basic ${Buffer.from(`${this.accountSid}:${this.authToken}`).toString('base64')}`,
          'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: formData.toString(),
      })

      const data = await response.json()

      if (!response.ok) {
        return {
          success: false,
          error: data.message || `API error: ${response.status}`,
        }
      }

      return {
        success: true,
        messageId: data.sid,
      }
    } catch (error) {
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Unknown error',
      }
    }
  }

  /**
   * Send a template message via Twilio WhatsApp
   *
   * Twilio uses Content Templates for WhatsApp templates.
   * The template name should be the Content SID.
   */
  async sendTemplate(
    to: string,
    template: string,
    params: Record<string, string>
  ): Promise<WhatsAppResult> {
    try {
      const formData = new URLSearchParams({
        From: `whatsapp:${formatPhoneNumber(this.fromNumber)}`,
        To: `whatsapp:${formatPhoneNumber(to)}`,
        ContentSid: template,
      })

      // Add template variables
      if (Object.keys(params).length > 0) {
        formData.append('ContentVariables', JSON.stringify(params))
      }

      const response = await fetch(this.baseUrl, {
        method: 'POST',
        headers: {
          Authorization: `Basic ${Buffer.from(`${this.accountSid}:${this.authToken}`).toString('base64')}`,
          'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: formData.toString(),
      })

      const data = await response.json()

      if (!response.ok) {
        return {
          success: false,
          error: data.message || `API error: ${response.status}`,
        }
      }

      return {
        success: true,
        messageId: data.sid,
      }
    } catch (error) {
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Unknown error',
      }
    }
  }

  /**
   * Test the connection to Twilio API
   */
  async testConnection(): Promise<{ success: boolean; error?: string }> {
    try {
      // Try to fetch account info to verify credentials
      const response = await fetch(
        `https://api.twilio.com/2010-04-01/Accounts/${this.accountSid}.json`,
        {
          headers: {
            Authorization: `Basic ${Buffer.from(`${this.accountSid}:${this.authToken}`).toString('base64')}`,
          },
        }
      )

      if (!response.ok) {
        const data = await response.json()
        return {
          success: false,
          error: data.message || `API error: ${response.status}`,
        }
      }

      return { success: true }
    } catch (error) {
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Connection failed',
      }
    }
  }
}

/**
 * Format phone number for Twilio WhatsApp
 * Ensures + prefix and removes any other non-digit characters
 */
function formatPhoneNumber(phone: string): string {
  const digits = phone.replace(/[^\d]/g, '')
  return `+${digits}`
}
