import crypto from 'node:crypto';
import type {
  Channel,
  SendRequest,
  NormalizedMessage,
  ContentPayload,
} from '@zyphon/shared-types';

const EMAIL_REGEX = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/;
const E164_PHONE_REGEX = /^\+[1-9]\d{6,14}$/;

export function generateMessageId(): string {
  const ts = Date.now().toString(36);
  const rand = crypto.randomBytes(8).toString('hex');
  return `msg_${ts}_${rand}`;
}

export function generateRequestId(): string {
  const ts = Date.now().toString(36);
  const rand = crypto.randomBytes(6).toString('hex');
  return `req_${ts}_${rand}`;
}

export function validateRecipient(channel: Channel, recipient: string): { valid: boolean; error?: string } {
  if (!recipient || typeof recipient !== 'string') {
    return { valid: false, error: 'Recipient is required and must be a string' };
  }

  const trimmed = recipient.trim();

  if (channel === 'email') {
    if (!EMAIL_REGEX.test(trimmed)) {
      return { valid: false, error: `Invalid email recipient format: '${recipient}' (expected RFC 5322 compliant email)` };
    }
  } else if (channel === 'sms' || channel === 'whatsapp') {
    if (!E164_PHONE_REGEX.test(trimmed)) {
      return { valid: false, error: `Invalid phone recipient format: '${recipient}' (expected E.164 format, e.g. +14155552671)` };
    }
  }

  return { valid: true };
}

export function maskRecipient(recipient: string): string {
  if (!recipient) return '';

  if (recipient.includes('@')) {
    const parts = recipient.split('@');
    const local = parts[0] || '';
    const domain = parts[1] || '';
    const maskedLocal = local.length <= 2 ? `${local[0] || ''}***` : `${local[0]}***${local[local.length - 1]}`;
    return `${maskedLocal}@${domain}`;
  }

  if (recipient.startsWith('+')) {
    if (recipient.length <= 6) return recipient;
    const prefix = recipient.slice(0, 5);
    const suffix = recipient.slice(-3);
    return `${prefix}****${suffix}`;
  }

  return recipient.length <= 4 ? '****' : `${recipient.slice(0, 2)}****${recipient.slice(-2)}`;
}

export function normalizeMessage(
  req: SendRequest,
  appId: string,
  requestId = generateRequestId(),
  messageId = generateMessageId()
): NormalizedMessage {
  const content: ContentPayload = {
    type: req.content.type || 'text',
    body: req.content.body,
    subject: req.content.subject,
    template: req.content.template,
    variables: req.content.variables,
    attachments: req.content.attachments,
  };

  return {
    message_id: messageId,
    request_id: requestId,
    application_id: appId,
    channel: req.channel,
    recipient: req.recipient.trim(),
    content,
    metadata: req.metadata || {},
    created_at: Date.now(),
  };
}

