const WhatsAppQueue = require('../../models/WhatsAppQueue');
const eventBus = require('./EventBus');
const Events = require('./CoreEvents');
const queueDispatcher = require('./QueueDispatcher');
const { logInfo, logError } = require('./LogContext');

const normalizePayload = (payload = {}) => {
  const tenantId = payload.tenantId ?? payload.tenant_id ?? null;
  const channel = payload.channel || payload.provider || null;
  const to = payload.to || payload.phoneNumber || payload.contactPhone || null;
  return {
    tenantId,
    channel,
    to,
    messageType: payload.type || payload.messageType || 'text',
    content: payload.content || payload.message || payload.text || null,
    mediaPath: payload.mediaPath || payload.mediaUrl || null,
    caption: payload.caption || null,
    conversationId: payload.conversationId || null,
    accountId: payload.accountId || payload.account_id || null,
    sessionId: payload.sessionId || null,
    metadata: payload.metadata || {},
    priority: payload.priority || 0,
    scheduledAt: payload.scheduledAt || null
  };
};

const enqueueMessage = async (payload = {}) => {
  const normalized = normalizePayload(payload);
  const logBase = {
    tenant_id: normalized.tenantId,
    session_id: normalized.sessionId,
    message_id: null,
    module: 'message_service',
    event: 'message_enqueue',
    step: 'validate'
  };

  if (!normalized.tenantId || !normalized.channel || !normalized.to) {
    logError('Message payload invalid', {
      ...logBase,
      error: 'Missing tenantId/channel/to'
    });
    return { success: false, error: 'Invalid message payload' };
  }

  const queueItem = await WhatsAppQueue.create(normalized.tenantId, {
    phone_number: normalized.to,
    message_type: normalized.messageType,
    content: normalized.content,
    media_path: normalized.mediaPath,
    caption: normalized.caption,
    priority: normalized.priority,
    scheduled_at: normalized.scheduledAt,
    metadata: {
      channel: normalized.channel,
      conversationId: normalized.conversationId,
      accountId: normalized.accountId,
      sessionId: normalized.sessionId,
      shadow: normalized.metadata.shadow || false,
      rateLimitMs: normalized.metadata.rateLimitMs || null,
      maxAttempts: normalized.metadata.maxAttempts || null,
      payload: normalized.metadata.payload || null,
      options: normalized.metadata.options || null,
      tags: normalized.metadata.tags || null,
      context: normalized.metadata.context || null
    }
  });

  logInfo('Message queued', {
    ...logBase,
    message_id: queueItem?.id || null,
    step: 'queued'
  });

  eventBus.emit(Events.MESSAGE_QUEUED, {
    tenantId: normalized.tenantId,
    itemId: queueItem?.id || null,
    channel: normalized.channel
  });

  if (payload.awaitSend) {
    const result = await queueDispatcher.processItem(normalized.tenantId, queueItem);
    return {
      success: result?.success || false,
      queueId: queueItem?.id || null,
      messageId: result?.messageId || null,
      error: result?.error || null
    };
  }

  queueDispatcher.dispatchTenant(normalized.tenantId).catch(error => {
    logError('Queue dispatch failed', {
      tenant_id: normalized.tenantId,
      module: 'message_service',
      event: 'queue_dispatch',
      step: 'error',
      error: error.message || String(error)
    });
  });

  return { success: true, queueId: queueItem?.id || null };
};

module.exports = {
  enqueueMessage
};
