// GetGabs WhatsApp Business API transport (https://app.getgabs.com/).
//
// Unlike `whatsappTransport` (a free-text stub), GetGabs sends pre-approved
// WhatsApp *template* messages, keyed by a campaign_id, with structured
// HEADER/BODY parameters that the provider maps onto the approved template.
//
// All credentials/config come from env so nothing sensitive lives in the repo:
//   GETGABS_API_URL   — the send endpoint URL (from the GetGabs API docs)
//   GETGABS_API_KEY   — account API key
//   GETGABS_SENDER    — the registered WhatsApp sender number (digits)
// Per-template campaign ids are read by the caller (e.g. GETGABS_CAMPAIGN_INVITE).
//
// The api_key is sent in the request body (matching the provider's documented
// payload). If a deployment also needs it as a bearer header, set
// GETGABS_AUTH_HEADER=1.

export interface GabsTemplateSend {
  /** Recipient number in international format; normalised to digits here. */
  to: string;
  receiverName?: string;
  /** GetGabs campaign id for the approved template being sent. */
  campaignId: string;
  /** Approved WhatsApp template name, e.g. "gp_entry_qr_templete". */
  templateName: string;
  /** Template language code, e.g. "en_US". */
  languageCode: string;
  /** Optional HEADER image link (rendered inline by the recipient's client). */
  headerImageUrl?: string;
  /** Positional BODY text parameters, in template order. */
  bodyParams: string[];
}

export interface GabsResult {
  ok: boolean;
  skipped?: boolean;
  reason?: string;
  status?: number;
}

const clean = (s?: string) => (s || '').trim();

// True when the provider has enough config to actually dispatch. When false,
// callers should fall back to the stub transport (dev) so wiring can be
// integration-tested without live credentials.
export function isGabsConfigured(): boolean {
  return !!(clean(process.env.GETGABS_API_URL) && clean(process.env.GETGABS_API_KEY) && clean(process.env.GETGABS_SENDER));
}

export async function sendGabsTemplate(msg: GabsTemplateSend): Promise<GabsResult> {
  const to = (msg.to || '').replace(/\D+/g, '');
  if (!to) return { ok: false, skipped: true, reason: 'missing-destination' };

  if (!isGabsConfigured()) {
    if (process.env.WHATSAPP_LOG !== 'false') {
      console.log(`[WA/GetGabs not configured] would send template '${msg.templateName}' (campaign ${msg.campaignId}) to +${to}`);
    }
    return { ok: true, skipped: true, reason: 'transport-not-configured' };
  }

  const url = clean(process.env.GETGABS_API_URL);
  const apiKey = clean(process.env.GETGABS_API_KEY);
  const sender = clean(process.env.GETGABS_SENDER);
  // Send numeric campaign ids as numbers, ids with other chars as strings.
  const campaignId: string | number = /^\d+$/.test(msg.campaignId) ? Number(msg.campaignId) : msg.campaignId;

  const components: unknown[] = [];
  if (msg.headerImageUrl) {
    components.push({ type: 'HEADER', parameters: [{ type: 'IMAGE', image: { link: msg.headerImageUrl } }] });
  }
  if (msg.bodyParams && msg.bodyParams.length) {
    components.push({ type: 'BODY', parameters: msg.bodyParams.map((text) => ({ type: 'text', text: text ?? '' })) });
  }

  const payload = {
    api_key: apiKey,
    sender,
    campaign_id: campaignId,
    messaging_product: 'whatsapp',
    recipient_type: 'individual',
    to,
    receiver_name: msg.receiverName || '',
    type: 'template',
    template: {
      name: msg.templateName,
      language: { code: msg.languageCode || 'en_US' },
      components,
    },
  };

  // Log the outgoing request (api_key redacted) so the full payload is visible
  // in the API console for debugging.
  console.log('[WA/GetGabs] → POST', url);
  console.log('[WA/GetGabs] → payload:', JSON.stringify({ ...payload, api_key: '***redacted***' }));

  try {
    const res = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Accept: 'application/json',
        ...(process.env.GETGABS_AUTH_HEADER ? { Authorization: `Bearer ${apiKey}` } : {}),
      },
      body: JSON.stringify(payload),
    });
    // Always log the raw response so both success bodies and provider error
    // details are visible in the console.
    const text = await res.text().catch(() => '');
    console.log(`[WA/GetGabs] ← ${res.status} ${res.statusText}: ${text.slice(0, 800)}`);
    if (!res.ok) {
      console.error(`[WA/GetGabs] send FAILED ${res.status} for +${to} (campaign ${campaignId}, template '${msg.templateName}')`);
      return { ok: false, status: res.status, reason: 'provider-error' };
    }
    console.log(`[WA/GetGabs] sent '${msg.templateName}' to +${to} (campaign ${campaignId})`);
    return { ok: true, status: res.status };
  } catch (e) {
    console.error('[WA/GetGabs] send EXCEPTION:', (e as Error)?.message || e);
    return { ok: false, reason: 'exception' };
  }
}
