/**
 * Delivery Settings Config - Single source for channel field definitions
 *
 * API → UI mapping (aligned with adiona-ui / cap-campaigns-v2 SenderDetails):
 *
 * SMS:
 *   - SMS Domain → domainProperties (select; label=domainName, value=domainId); Sender ID filtered by selected domain
 *   - Sender ID  → contactInfo type gsm_sender_id (fallback cdma_sender_id); options only from selected domain
 *
 * EMAIL:
 *   - Email Domain → domainProperties (select; label=domainName, value=domainId); Sender ID/Reply-to/Sender name filtered by selected domain
 *   - Sender ID   → contactInfo type sender_id; value = email address
 *   - Sender name → contactInfo type sender_id .label (display name)
 *   - Reply-to ID → contactInfo type reply_to_id; value = reply email
 *
 * WHATSAPP / RCS:
 *   - Sender number → contactInfo type gsm_sender_id (or cdma_sender_id); .value = phone number
 *
 * VIBER / ZALO / LINE:
 *   - Sender ID → contactInfo type gsm_sender_id (fallback cdma_sender_id); .value
 *
 * Entity structure from domainProperties API:
 * { SMS: [...], EMAIL: [...], WHATSAPP: [...], VIBER: [...], ZALO: [...], LINE: [...] }
 * Each channel array contains domain objects with domainProperties.contactInfo
 */
import {
  SMS, EMAIL, WHATSAPP, VIBER, RCS,
} from '../../../CreativesContainer/constants';

// --- Generic helpers for API response structure ---
const toArray = (val) => {
  if (Array.isArray(val)) return val;
  if (val) return [val];
  return [];
};

const getChannelData = (entity, channelKey) => {
  const domainList = toArray(entity?.[channelKey]);
  return domainList[0] || null;
};

/**
 * Pick the preferred contact entry for a given type:
 * returns the first entry flagged as default, or the first valid entry, or null.
 * Replaces the invalid single-argument .sort() pattern (Array.sort requires a
 * two-argument comparator; a single-argument form produces undefined behaviour).
 */
const pickPreferredContact = (contactInfoList, type) => {
  const validMatches = contactInfoList.filter(
    (contactEntry) => contactEntry?.type === type && contactEntry?.valid,
  );
  return validMatches.find((contactEntry) => contactEntry?.default) || validMatches[0] || null;
};

/** Extract value from contactInfo by type (e.g. gsm_sender_id, sender_id) */
const getValueFromContactInfo = (channelData, preferredType, fallbackTypes = []) => {
  const contactInfo = channelData?.domainProperties?.contactInfo || [];
  if (!Array.isArray(contactInfo)) return '';
  const types = [preferredType, ...fallbackTypes];
  const match = types.reduce((found, senderType) => {
    if (found) return found;
    return pickPreferredContact(contactInfo, senderType);
  }, null);
  return match ? (match.value || match.label) : '';
};

/** Extract all options from contactInfo by type */
const getOptionsFromContactInfo = (channelData, preferredType, fallbackTypes = []) => {
  const contactInfo = channelData?.domainProperties?.contactInfo || [];
  if (!Array.isArray(contactInfo)) return [];
  const types = [preferredType, ...fallbackTypes];
  const seen = new Set();
  return types.reduce((accumulatedOptions, senderType) => {
    const contactMatches = contactInfo.filter((contactEntry) => contactEntry?.type === senderType && contactEntry?.valid) || [];
    contactMatches.forEach((contactMatch) => {
      const senderValue = contactMatch.value || contactMatch.label;
      const label = contactMatch.label || contactMatch.value;
      if (senderValue && !seen.has(senderValue)) {
        seen.add(senderValue);
        accumulatedOptions.push({ label, value: senderValue });
      }
    });
    return accumulatedOptions;
  }, []);
};

// --- SMS extractors ---
const getSmsData = (entity) => getChannelData(entity, 'SMS');

/** Find domain by id in SMS array */
const getSmsDomainById = (entity, domainId) => {
  const smsDomainList = toArray(entity?.SMS);
  if (domainId == null) return smsDomainList[0] || null;
  const idStr = String(domainId);
  return smsDomainList.find((domainEntry) => {
    const dId = domainEntry.domainProperties?.id ?? domainEntry.domainId ?? domainEntry.id;
    return dId != null && String(dId) === idStr;
  }) || smsDomainList[0] || null;
};

// SMS Domain options (label = domainName, value = domainId) - unique by domainName (like Email)
const getSmsDomainOptions = (entity) => {
  const smsDomainList = toArray(entity?.SMS);
  const seen = new Set();
  const options = [];
  smsDomainList.forEach((domainEntry, domainIndex) => {
    const domainId = domainEntry.domainProperties?.id ?? domainEntry.domainId ?? domainEntry.id ?? String(domainIndex);
    const label = domainEntry.domainProperties?.domainName || domainEntry.domainName || domainEntry.domainProperties?.hostName;
    if (!seen.has(label)) {
      seen.add(label);
      options.push({ label, value: domainId });
    }
  });
  return options;
};

const getSmsDomainValue = (entity) => {
  const smsData = getSmsData(entity);
  if (!smsData) return '';
  return smsData.domainProperties?.id ?? smsData.domainId ?? smsData.id ?? '';
};

// Sender ID - options only from selected domain (like Email)
const getSmsSenderIdOptions = (entity, context = {}) => {
  const selectedDomainId = context?.fieldValues?.smsDomain;
  const domainData = selectedDomainId ? getSmsDomainById(entity, selectedDomainId) : getSmsData(entity);
  if (!domainData) return [];
  return getOptionsFromContactInfo(domainData, 'gsm_sender_id', ['cdma_sender_id']);
};

const getSmsSenderIdValue = (entity) => {
  const smsData = getSmsData(entity);
  return getValueFromContactInfo(smsData, 'gsm_sender_id', ['cdma_sender_id']);
};

/** Get default sender ID for a domain - for SMS domain change / reset */
const getSmsDefaultForDomain = (domainData) => {
  if (!domainData) return '';
  return getValueFromContactInfo(domainData, 'gsm_sender_id', ['cdma_sender_id']);
};

export const getSmsDefaultsForDomainId = (entity, domainId) => {
  if (!entity) return { senderId: '' };
  const domainData = getSmsDomainById(entity, domainId);
  return { senderId: getSmsDefaultForDomain(domainData) };
};

// --- EMAIL extractors ---
const getEmailData = (entity) => getChannelData(entity, 'EMAIL');

/** Find domain by id in EMAIL array */
const getEmailDomainById = (entity, domainId) => {
  const emailDomainList = toArray(entity?.EMAIL);
  if (domainId == null) return emailDomainList[0] || null;
  const idStr = String(domainId);
  return emailDomainList.find((domainEntry) => {
    const dId = domainEntry.domainProperties?.id ?? domainEntry.domainId ?? domainEntry.id;
    return dId != null && String(dId) === idStr;
  }) || emailDomainList[0] || null;
};

// Email Domain options (label = domainName, value = domainId) - unique by domainName
const getEmailDomainOptions = (entity) => {
  const emailDomainList = toArray(entity?.EMAIL);
  const seen = new Set();
  const options = [];
  emailDomainList.forEach((domainEntry, domainIndex) => {
    const domainId = domainEntry.domainProperties?.id ?? domainEntry.domainId ?? domainEntry.id ?? String(domainIndex);
    const label = domainEntry.domainProperties?.domainName || domainEntry.domainName || domainEntry.domainProperties?.hostName;
    if (!seen.has(label)) {
      seen.add(label);
      options.push({ label, value: domainId });
    }
  });
  return options;
};

const getEmailDomainValue = (entity) => {
  const emailData = getEmailData(entity);
  if (!emailData) return '';
  return emailData.domainProperties?.id ?? emailData.domainId ?? emailData.id ?? '';
};

/** Domain name for summary display (parseEntityForDisplay) */
const getEmailDomainNameForDisplay = (entity) => {
  const emailData = getEmailData(entity);
  if (!emailData) return '';
  return emailData.domainProperties?.domainName || emailData.domainName || emailData.domainProperties?.hostName || '';
};

// Sender ID (from sender_id - email address). Options only from selected domain - no cross-domain selection.
const getEmailSenderIdOptions = (entity, context = {}) => {
  const selectedDomainId = context?.fieldValues?.emailDomain;
  const domainData = selectedDomainId ? getEmailDomainById(entity, selectedDomainId) : getEmailData(entity);
  if (!domainData) return [];
  const options = getOptionsFromContactInfo(domainData, 'sender_id', []);
  return options?.map((option) => ({ label: option.value || option.label, value: option.value || option.label }));
};

const getEmailSenderIdValue = (entity) => {
  const emailData = getEmailData(entity);
  return getValueFromContactInfo(emailData, 'sender_id', []);
};

// Sender name (from sender_id label). Options only from selected domain - no cross-domain selection.
const getEmailSenderNameOptions = (entity, context = {}) => {
  const selectedDomainId = context?.fieldValues?.emailDomain;
  const domainData = selectedDomainId ? getEmailDomainById(entity, selectedDomainId) : getEmailData(entity);
  if (!domainData) return [];
  const contactInfo = domainData?.domainProperties?.contactInfo || [];
  const seen = new Set();
  const options = [];
  contactInfo
    .filter((contact) => contact?.type === 'sender_id' && contact?.valid)
    .forEach((contact) => {
      const value = contact?.label || contact?.value;
      if (value && !seen.has(value)) {
        seen.add(value);
        options.push({ label: value, value });
      }
    });
  return options;
};

const getEmailSenderNameValue = (entity) => {
  const emailData = getEmailData(entity);
  const contactInfo = emailData?.domainProperties?.contactInfo || [];
  const contactMatch = pickPreferredContact(contactInfo, 'sender_id');
  return contactMatch ? (contactMatch.label || contactMatch.value) : '';
};

// Reply-to ID. Options only from selected domain - no cross-domain selection.
const getEmailReplyToIdOptions = (entity, context = {}) => {
  const selectedDomainId = context?.fieldValues?.emailDomain;
  const domainData = selectedDomainId ? getEmailDomainById(entity, selectedDomainId) : getEmailData(entity);
  if (!domainData) return [];
  const options = getOptionsFromContactInfo(domainData, 'reply_to_id', []);
  return options?.map((option) => ({ label: option.value || option.label, value: option.value || option.label }));
};

const getEmailReplyToIdValue = (entity) => {
  const emailData = getEmailData(entity);
  return getValueFromContactInfo(emailData, 'reply_to_id', []);
};

/** Get default values for a domain (contactInfo items with default: true) - adiona-ui/cap-campaigns-v2 pattern */
const getEmailDefaultsForDomain = (domainData) => {
  if (!domainData) return { senderId: '', senderName: '', replyToId: '' };
  const contactInfo = domainData?.domainProperties?.contactInfo || [];
  const findDefault = (type) => pickPreferredContact(contactInfo, type);
  const senderMatch = findDefault('sender_id');
  const replyMatch = findDefault('reply_to_id');
  return {
    senderId: senderMatch ? (senderMatch.value || senderMatch.label) : '',
    senderName: senderMatch ? (senderMatch.label || senderMatch.value) : '',
    replyToId: replyMatch ? (replyMatch.value || replyMatch.label) : '',
  };
};

/**
 * Get default value for a field (for Reset). (entity, context) => value
 * context.fieldValues has current form state (e.g. selected emailDomain)
 * Aligned with adiona-ui/cap-campaigns-v2: default = contactInfo item with default:true, or first
 */
export const getDefaultValueForField = (fieldKey, entity, context = {}) => {
  if (!entity) return '';
  const fieldValues = context?.fieldValues || {};
  if (fieldKey === 'smsDomain' || fieldKey === 'emailDomain') {
    const options = fieldKey === 'emailDomain' ? getEmailDomainOptions(entity) : getSmsDomainOptions(entity);
    return options?.[0]?.value ?? (fieldKey === 'emailDomain' ? getEmailDomainValue(entity) : getSmsDomainValue(entity)) ?? '';
  }
  if (fieldKey === 'smsSenderId') {
    const domainId = fieldValues.smsDomain || getSmsDomainValue(entity);
    const domainData = getSmsDomainById(entity, domainId);
    return getSmsDefaultForDomain(domainData);
  }
  if (fieldKey === 'emailSenderId' || fieldKey === 'emailSenderName' || fieldKey === 'emailReplyToId') {
    const domainId = fieldValues.emailDomain || getEmailDomainValue(entity);
    const domainData = getEmailDomainById(entity, domainId);
    const defs = getEmailDefaultsForDomain(domainData);
    if (fieldKey === 'emailSenderId') return defs.senderId;
    if (fieldKey === 'emailSenderName') return defs.senderName;
    if (fieldKey === 'emailReplyToId') return defs.replyToId;
  }
  return '';
};

/** Get defaults for domain change (populate sender id, reply to, sender name when domain changes) */
export const getEmailDefaultsForDomainId = (entity, domainId) => {
  if (!entity) return { senderId: '', senderName: '', replyToId: '' };
  const domainData = getEmailDomainById(entity, domainId);
  return getEmailDefaultsForDomain(domainData);
};

// --- WHATSAPP sender number (WABA-bound via sourceAccountIdentifier) ---
// The domainProperties API returns WHATSAPP domains with:
//   connectionProperties.sourceAccountIdentifier (WABA ID)
//   contactInfo with gsm_sender_id entries (phone numbers for that WABA)
// The WhatsApp template (in contentItems) provides sourceAccountIdentifier to bind to the right domain.

/** Extract sourceAccountIdentifier from a domain entry */
const getDomainSourceAccountId = (domainData) => {
  const { connectionProperties = {} } = domainData?.domainProperties || {};
  const { sourceAccountIdentifier = '', wabaId = '', userid = '' } = connectionProperties;
  return sourceAccountIdentifier || wabaId || userid || '';
};

/** Find the WHATSAPP domain matching a sourceAccountIdentifier */
const getWhatsappDomainBySourceAccount = (entity, sourceAccountId) => {
  const whatsappDomains = toArray(entity?.WHATSAPP);
  if (!sourceAccountId) return whatsappDomains?.length ? whatsappDomains[0] : null;
  const matchedDomain = whatsappDomains.find((domain) => getDomainSourceAccountId(domain) === sourceAccountId);
  return matchedDomain || (whatsappDomains?.length ? whatsappDomains[0] : null);
};

/** Get WhatsApp account name from the matched domain */
export const getWhatsappAccountName = (entity, sourceAccountId) => {
  const domain = getWhatsappDomainBySourceAccount(entity, sourceAccountId);
  if (!domain) return '';
  return domain.domainProperties?.domainName || domain.domainName || domain.label || '';
};

/** Get sender number value from the WABA-matched domain */
const getWhatsappSenderNumberValue = (entity, context = {}) => {
  const sourceAccountId = context?.whatsappSourceAccountId || '';
  const domain = getWhatsappDomainBySourceAccount(entity, sourceAccountId);
  if (!domain) return '';
  return getValueFromContactInfo(domain, 'gsm_sender_id', ['cdma_sender_id', 'whatsapp_sender_id']);
};

/** Get sender number options filtered to the WABA-matched domain only.
 *  Aligned with campaigns/adiona: both label and value use the phone number. */
const getWhatsappSenderNumberOptions = (entity, context = {}) => {
  const sourceAccountId = context?.whatsappSourceAccountId || '';
  const domain = getWhatsappDomainBySourceAccount(entity, sourceAccountId);
  if (!domain) return [];
  const options = getOptionsFromContactInfo(domain, 'gsm_sender_id', ['cdma_sender_id', 'whatsapp_sender_id']);
  return options?.map((option) => ({ label: option.value || option.label, value: option.value || option.label }));
};

const getRcsSenderNumberValue = (entity) => {
  const channelData = getChannelData(entity, 'RCS');
  if (!channelData) return '';
  return getValueFromContactInfo(channelData, 'gsm_sender_id', ['cdma_sender_id']);
};

/** Get RCS account name from first domain (like campaigns-v2: rcsSender display) */
export const getRcsAccountName = (entity) => {
  const rcsData = getChannelData(entity, 'RCS');
  if (!rcsData) return '';
  return rcsData.domainProperties?.domainName || rcsData.domainName || rcsData.label || '';
};


// --- VIBER account (disabled) + sender ID ---
// Aligned with adiona-ui/cap-campaigns-v2: domainId + sender (VIBER_SENDER_ID = 'sender')
// API entity: VIBER array with domainProperties.{ id, domainName, contactInfo } per domain
// When domainProperties.id is 0/missing (e.g. Iris DGM), use domainEntry.id (domain gateway mapping id)
const getViberDomainId = (domainEntry) => {
  const dpId = domainEntry.domainProperties?.id;
  if (dpId != null && dpId !== 0) return dpId;
  return domainEntry.domainId ?? domainEntry.id ?? '';
};

const getViberAccountValue = (entity) => {
  const viberData = getChannelData(entity, 'VIBER');
  if (!viberData) return '';
  return getViberDomainId(viberData) || '';
};

const getViberAccountOptions = (entity, context = {}) => {
  const viberDomainList = toArray(entity?.VIBER);
  const seen = new Set();
  const options = [];
  viberDomainList.forEach((viberDomainEntry) => {
    const domainId = getViberDomainId(viberDomainEntry);
    const label = viberDomainEntry.domainProperties?.domainName
      || viberDomainEntry.domainName
      || viberDomainEntry.domainProperties?.hostName
      || viberDomainEntry.label;
    if (domainId !== '' && domainId != null && !seen.has(domainId)) {
      seen.add(domainId);
      options.push({ label, value: domainId });
    }
  });
  // Use saved account from form state (editing existing campaign) or fall back to API-derived value.
  // Prepends a synthetic entry when the saved account is no longer present in the API options
  // (e.g. after domain deactivation), preserving the user's existing selection.
  const currentVal = context?.fieldValues?.viberAccount || getViberAccountValue(entity);
  if (currentVal && !options.some((option) => option.value === currentVal)) {
    const firstDomain = viberDomainList[0];
    const firstLabel = firstDomain?.domainProperties?.domainName
      || firstDomain?.domainName
      || String(currentVal);
    return [{ label: firstLabel, value: currentVal }, ...options];
  }
  return options;
};

// --- VIBER/ZALO/LINE sender ID (gsm_sender_id from contactInfo) ---
// VIBER may use viber_sender_id in some API responses; others use gsm_sender_id
const getSenderIdFromContactInfo = (entity, channelKey) => {
  const channelData = getChannelData(entity, channelKey);
  const fallbacks = channelKey === 'VIBER'
    ? ['cdma_sender_id', 'viber_sender_id']
    : ['cdma_sender_id'];
  return getValueFromContactInfo(channelData, 'gsm_sender_id', fallbacks);
};

const getSenderIdOptionsFromContactInfo = (entity, channelKey) => {
  const channelDomainList = toArray(entity?.[channelKey]);
  const seen = new Set();
  const options = [];
  const fallbacks = channelKey === 'VIBER' ? ['cdma_sender_id', 'viber_sender_id'] : ['cdma_sender_id'];
  channelDomainList.forEach((domainEntry) => {
    getOptionsFromContactInfo(domainEntry, 'gsm_sender_id', fallbacks).forEach((senderOption) => {
      if (senderOption.value && !seen.has(senderOption.value)) {
        seen.add(senderOption.value);
        options.push(senderOption);
      }
    });
  });
  const currentVal = getSenderIdFromContactInfo(entity, channelKey);
  /* istanbul ignore next -- synthetic prepend only occurs when persisted sender ID is absent from the newly loaded API options (stale save); valid API data always includes the current value */
  if (currentVal && !options.some((senderOption) => senderOption.value === currentVal)) {
    return [{ label: currentVal, value: currentVal }, ...options];
  }
  return options;
};

// --- Field type constants ---
export const FIELD_TYPE = {
  SELECT: 'select',
  INPUT: 'input',
  DISPLAY: 'display', // Read-only label + value (e.g. Email Domain)
};

/**
 * Channel field config
 */
export const DELIVERY_SETTINGS_FIELDS = [
  {
    channel: 'SMS',
    fieldKey: 'smsDomain',
    messageKey: 'smsDomain',
    type: FIELD_TYPE.SELECT,
    getValue: getSmsDomainValue,
    getOptions: getSmsDomainOptions,
  },
  {
    channel: 'SMS',
    fieldKey: 'smsSenderId',
    messageKey: 'senderIdLabel',
    type: FIELD_TYPE.SELECT,
    getValue: getSmsSenderIdValue,
    getOptions: getSmsSenderIdOptions,
  },
  // EMAIL - order: Email Domain (select with Reset), Sender ID, Sender name, Reply-to ID (selects)
  {
    channel: 'EMAIL',
    fieldKey: 'emailDomain',
    messageKey: 'emailDomainLabel',
    type: FIELD_TYPE.SELECT,
    getValue: getEmailDomainValue,
    getOptions: getEmailDomainOptions,
  },
  {
    channel: 'EMAIL',
    fieldKey: 'emailSenderId',
    messageKey: 'senderIdLabel',
    type: FIELD_TYPE.SELECT,
    getValue: getEmailSenderIdValue,
    getOptions: getEmailSenderIdOptions,
  },
  {
    channel: 'EMAIL',
    fieldKey: 'emailSenderName',
    messageKey: 'emailSenderName',
    type: FIELD_TYPE.SELECT,
    getValue: getEmailSenderNameValue,
    getOptions: getEmailSenderNameOptions,
  },
  {
    channel: 'EMAIL',
    fieldKey: 'emailReplyToId',
    messageKey: 'emailReplyToId',
    type: FIELD_TYPE.SELECT,
    getValue: getEmailReplyToIdValue,
    getOptions: getEmailReplyToIdOptions,
  },
  // WHATSAPP - Business Account (disabled, driven by template) + Sender Number (filtered by WABA)
  {
    channel: 'WHATSAPP',
    fieldKey: 'whatsappAccount',
    messageKey: 'whatsappBusinessAccount',
    type: FIELD_TYPE.SELECT,
    disabled: true,
    getValue: () => '',
    getOptions: () => [],
  },
  {
    channel: 'WHATSAPP',
    fieldKey: 'whatsappSenderNumber',
    messageKey: 'senderNumberLabel',
    type: FIELD_TYPE.SELECT,
    getValue: (entity, context) => getWhatsappSenderNumberValue(entity, context),
    getOptions: (entity, context) => getWhatsappSenderNumberOptions(entity, context),
  },
  // RCS - Account (disabled) + Sender Number
  {
    channel: 'RCS',
    fieldKey: 'rcsAccount',
    messageKey: 'rcsAccountLabel',
    type: FIELD_TYPE.SELECT,
    disabled: true,
    getValue: () => '',
    getOptions: () => [],
  },
  // RCS sender number: display-only in summary (DeliverySettingsSection); no select/reset in slidebox
  // VIBER - Viber account (disabled) + Sender ID (select with Reset) - per Figma
  {
    channel: 'VIBER',
    fieldKey: 'viberAccount',
    messageKey: 'viberAccountLabel',
    type: FIELD_TYPE.SELECT,
    disabled: true,
    getValue: getViberAccountValue,
    getOptions: (entity, context) => getViberAccountOptions(entity, context),
  },
  {
    channel: 'VIBER',
    fieldKey: 'viberSenderId',
    messageKey: 'senderIdLabel',
    type: FIELD_TYPE.SELECT,
    getValue: (entity) => getSenderIdFromContactInfo(entity, 'VIBER'),
    getOptions: (entity) => getSenderIdOptionsFromContactInfo(entity, 'VIBER'),
  },
  // ZALO
  {
    channel: 'ZALO',
    fieldKey: 'zaloSenderId',
    messageKey: 'senderIdLabel',
    type: FIELD_TYPE.SELECT,
    getValue: (entity) => getSenderIdFromContactInfo(entity, 'ZALO'),
    getOptions: (entity) => getSenderIdOptionsFromContactInfo(entity, 'ZALO'),
  },
  // LINE
  {
    channel: 'LINE',
    fieldKey: 'lineSenderId',
    messageKey: 'senderIdLabel',
    type: FIELD_TYPE.SELECT,
    getValue: (entity) => getSenderIdFromContactInfo(entity, 'LINE'),
    getOptions: (entity) => getSenderIdOptionsFromContactInfo(entity, 'LINE'),
  },
];

/**
 * Get field configs for the given channels
 */
export const getFieldsForChannels = (channels = []) => {
  const channelSet = new Set(channels.map((channelName) => (channelName)?.toUpperCase())?.filter(Boolean));
  return DELIVERY_SETTINGS_FIELDS.filter((fieldConfig) => channelSet.has(fieldConfig.channel));
};

/**
 * Parse entity for display in DeliverySettingsSection summary
 * Returns per-channel sender IDs and sender number
 */
export const parseEntityForDisplay = (entity, context = {}) => {
  if (!entity) return null;
  const whatsappSourceAccountId = context?.whatsappSourceAccountId || '';
  return {
    senderDetails: entity,
    smsSenderId: getSmsSenderIdValue(entity),
    smsDomain: getSmsDomainValue(entity),
    emailDomain: getEmailDomainNameForDisplay(entity),
    emailSenderId: getEmailSenderIdValue(entity),
    viberSenderId: getSenderIdFromContactInfo(entity, 'VIBER'),
    zaloSenderId: getSenderIdFromContactInfo(entity, 'ZALO'),
    lineSenderId: getSenderIdFromContactInfo(entity, 'LINE'),
    whatsappSenderNumber: getWhatsappSenderNumberValue(entity, { whatsappSourceAccountId }),
    whatsappAccountName: getWhatsappAccountName(entity, whatsappSourceAccountId),
    rcsSenderNumber: getRcsSenderNumberValue(entity),
    rcsAccountName: getRcsAccountName(entity),
    senderNumber: getWhatsappSenderNumberValue(entity, { whatsappSourceAccountId }) || getRcsSenderNumberValue(entity),
  };
};

/**
 * Build channelSetting (adiona/campaigns format) from SenderDetails fieldValues for persistence
 */
export const buildChannelSettingFromFieldValues = (fieldValues = {}) => {
  const channelSetting = {};
  if (fieldValues.smsDomain != null || fieldValues.smsSenderId != null) {
    channelSetting.SMS = {
      domainId: fieldValues.smsDomain,
      gsmSenderId: fieldValues.smsSenderId,
    };
  }
  if (fieldValues.emailDomain != null || fieldValues.emailSenderId != null || fieldValues.emailSenderName != null || fieldValues.emailReplyToId != null) {
    channelSetting.EMAIL = {
      domainId: fieldValues.emailDomain,
      senderEmail: fieldValues.emailSenderId,
      senderLabel: fieldValues.emailSenderName,
      senderReplyTo: fieldValues.emailReplyToId,
    };
  }
  if (fieldValues.whatsappSenderNumber != null || fieldValues.whatsappAccount != null) {
    channelSetting.WHATSAPP = {
      domainId: fieldValues.whatsappDomainId,
      senderMobNum: fieldValues.whatsappSenderNumber,
    };
  }
  if (fieldValues.rcsSenderNumber != null || fieldValues.rcsAccount != null) {
    channelSetting.RCS = {
      senderMobNum: fieldValues.rcsSenderNumber,
      rcsSender: fieldValues.rcsSenderNumber,
    };
  }
  // VIBER: aligned with adiona-ui (domainId + sender), campaigns-v2 (gsmSenderId/senderViber)
  if (fieldValues.viberSenderId != null || fieldValues.viberAccount != null) {
    channelSetting.VIBER = {
      domainId: fieldValues.viberAccount,
      sender: fieldValues.viberSenderId,
      // Include gsmSenderId for campaigns API compatibility
      gsmSenderId: fieldValues.viberSenderId,
    };
  }
  if (fieldValues.zaloSenderId != null) {
    channelSetting.ZALO = { zaloSenderId: fieldValues.zaloSenderId };
  }
  if (fieldValues.lineSenderId != null) {
    channelSetting.LINE = { lineSenderId: fieldValues.lineSenderId };
  }
  return channelSetting;
};

/**
 * Channels that require a domain gateway to be present in the API response.
 * Aligned with cap-campaigns-v2 and adiona-ui: ZALO and LINE are excluded from this check.
 */
const GATEWAY_CHECKED_CHANNELS = [SMS, EMAIL, WHATSAPP, VIBER, RCS];

/**
 * Returns true when the entity contains a valid domain gateway for the channel.
 * For WHATSAPP: also verifies the WABA-matched domain has at least one gsm_sender_id.
 * For all others: requires a non-empty array in the entity.
 */
export const hasDomainGateway = (entity, channel, context = {}) => {
  if (!entity) return false;
  if (!GATEWAY_CHECKED_CHANNELS.includes(channel)) return true;
  const domainList = toArray(entity[channel]);
  if (domainList?.length === 0) return false;
  if (channel === WHATSAPP) {
    const sourceAccountId = context?.whatsappSourceAccountId || '';
    const domain = getWhatsappDomainBySourceAccount(entity, sourceAccountId);
    if (!domain) return false;
    const options = getOptionsFromContactInfo(domain, 'gsm_sender_id', ['cdma_sender_id', 'whatsapp_sender_id']);
    return options?.length > 0;
  }
  return true;
};

/**
 * Extract display values from channelSetting for summary (reverse of buildChannelSettingFromFieldValues)
 */
export const parseChannelSettingForDisplay = (channelSetting = {}) => {
  const out = {};
  if (channelSetting.SMS) {
    out.smsSenderId = channelSetting.SMS.gsmSenderId;
    out.smsDomain = channelSetting.SMS.domainId;
  }
  if (channelSetting.EMAIL) {
    out.emailDomain = channelSetting.EMAIL.domainId;
    out.emailSenderId = channelSetting.EMAIL.senderEmail;
    out.emailSenderName = channelSetting.EMAIL.senderLabel;
    out.emailReplyToId = channelSetting.EMAIL.senderReplyTo;
  }
  if (channelSetting.WHATSAPP) {
    out.whatsappSenderNumber = channelSetting.WHATSAPP.senderMobNum;
    out.whatsappDomainId = channelSetting.WHATSAPP.domainId;
  }
  if (channelSetting.RCS) {
    out.rcsSenderNumber = channelSetting.RCS.senderMobNum || channelSetting.RCS.rcsSender;
  }
  // VIBER: read sender (adiona) or viberSenderId/gsmSenderId (campaigns compat)
  if (channelSetting.VIBER) {
    out.viberAccount = channelSetting.VIBER.domainId;
    const viberSetting = channelSetting.VIBER;
    out.viberSenderId = viberSetting.sender ?? viberSetting.viberSenderId ?? viberSetting.gsmSenderId;
  }
  if (channelSetting.ZALO) out.zaloSenderId = channelSetting.ZALO.zaloSenderId;
  if (channelSetting.LINE) out.lineSenderId = channelSetting.LINE.lineSenderId;
  return out;
};
