/**
 * ModifyDeliverySettings — CapSlideBox content for Test and Preview delivery settings.
 * Channel-specific dropdowns (SMS: domain + sender number; Email: domain + sender + reply-to; WhatsApp: account + sender number).
 * Reference: cap-campaigns-v2 ModifyDeliverySettings + SenderDetails (field layout and options shape).
 */

import React, {
  useState, useCallback, useMemo, useEffect,
} from 'react';
import PropTypes from 'prop-types';
import CapRow from '@capillarytech/cap-ui-library/CapRow';
import CapHeader from '@capillarytech/cap-ui-library/CapHeader';
import CapSelect from '@capillarytech/cap-ui-library/CapSelect';
import CapButton from '@capillarytech/cap-ui-library/CapButton';
import CapSpin from '@capillarytech/cap-ui-library/CapSpin';
import CapLabel from '@capillarytech/cap-ui-library/CapLabel';
import { FormattedMessage } from 'react-intl';
import get from 'lodash/get';
import find from 'lodash/find';
import cloneDeep from 'lodash/cloneDeep';
import messages from './messages';
import {
  CHANNELS,
  DEFAULT_DELIVERY_SETTINGS_BY_CHANNEL,
  ROW_KEY_PREFIX,
  DELIVERY_SETTING_KEY_DOMAIN_ID,
  DELIVERY_SETTING_KEY_DOMAIN_GATEWAY_MAP_ID,
  DELIVERY_SETTING_KEY_GSM_SENDER_ID,
  DELIVERY_SETTING_KEY_CDMA_SENDER_ID,
  DELIVERY_SETTING_KEY_SENDER_EMAIL,
  DELIVERY_SETTING_KEY_SENDER_LABEL,
  DELIVERY_SETTING_KEY_SENDER_REPLY_TO,
  DELIVERY_SETTING_KEY_SOURCE_ACCOUNT_IDENTIFIER,
  DELIVERY_SETTING_KEY_SENDER_MOB_NUM,
} from './constants';
import './ModifyDeliverySettings.scss';

const findDefault = (array) => find(array, { default: true }) || (array && array[0]) || {};

const ModifyDeliverySettings = (props) => {
  const {
    channel,
    deliverySettings: initialSettings = {},
    senderDetailsOptions = [],
    wecrmAccounts = [],
    onSaveDeliverySettings,
    onClose,
    isLoading,
    formatMessage,
    smsTraiDltEnabled,
    registeredSenderIds = [],
    whatsappAccountFromForm,
  } = props;

  const defaultForChannel = DEFAULT_DELIVERY_SETTINGS_BY_CHANNEL[channel] || {};
  const [localSettings, setLocalSettings] = useState(() => ({
    ...defaultForChannel,
    ...initialSettings,
  }));

  const isWhatsappAccountLocked = channel === CHANNELS.WHATSAPP && !!whatsappAccountFromForm?.accountName;

  useEffect(() => {
    if (!isWhatsappAccountLocked || !whatsappAccountFromForm?.accountName) return;
    const accountByName = (wecrmAccounts || []).find(
      (a) => (a.name || '') === whatsappAccountFromForm.accountName,
    );
    const sourceAccountId = accountByName?.sourceAccountIdentifier;
    if (!sourceAccountId) return;
    setLocalSettings((prev) => {
      if (prev[DELIVERY_SETTING_KEY_SOURCE_ACCOUNT_IDENTIFIER] === sourceAccountId) return prev;
      const next = cloneDeep(prev);
      next[DELIVERY_SETTING_KEY_SOURCE_ACCOUNT_IDENTIFIER] = sourceAccountId;
      const domain = (senderDetailsOptions || []).find(
        (senderDetails) => senderDetails.sourceAccountIdentifier === sourceAccountId,
      );
      const first = domain?.gsmSenders?.[0];
      if (first?.value != null) {
        next[DELIVERY_SETTING_KEY_SENDER_MOB_NUM] = first.value;
      }
      return next;
    });
  }, [
    isWhatsappAccountLocked,
    whatsappAccountFromForm?.accountName,
    wecrmAccounts,
    senderDetailsOptions,
  ]);

  const noOptionsLabel = formatMessage(messages.noOptions);

  const allDomainOptions = useMemo(
    () => (senderDetailsOptions || []).map((senderDetails) => ({
      label: senderDetails.domainName || senderDetails.domainId,
      value: senderDetails.domainId,
      ...senderDetails,
    })),
    [senderDetailsOptions],
  );

  const domainOptions = useMemo(() => {
    if (!(channel === CHANNELS.SMS && smsTraiDltEnabled)) {
      return allDomainOptions;
    }

    return allDomainOptions.filter((domain) => (domain.gsmSenders || []).some(
      (gsmId) => registeredSenderIds.includes(gsmId.value),
    ));
  }, [allDomainOptions, channel, registeredSenderIds, smsTraiDltEnabled]);

  const selectedDomain = useMemo(
    () => (senderDetailsOptions || []).find(
      (d) => d.domainId === get(localSettings, DELIVERY_SETTING_KEY_DOMAIN_ID),
    ) || {},
    [senderDetailsOptions, localSettings.domainId],
  );
  const {
    gsmSenders: selectedDomainGsmSenders = [],
    emailSenders: selectedDomainEmailSenders = [],
    emailRepliers: selectedDomainEmailRepliers = [],
  } = selectedDomain;

  const gsmOptions = useMemo(
    () => {
      const smsGsmSenders = channel === CHANNELS.SMS && smsTraiDltEnabled
        ? selectedDomainGsmSenders.filter((gsmId) => registeredSenderIds.includes(gsmId.value))
        : selectedDomainGsmSenders;

      return smsGsmSenders.map((o) => ({
        label: o.value || o.label,
        value: o.value,
      }));
    },
    [channel, registeredSenderIds, selectedDomainGsmSenders, smsTraiDltEnabled],
  );

  const emailSenderOptions = useMemo(
    () => selectedDomainEmailSenders.map((o) => ({
      label: o.value || o.label,
      value: o.value,
      senderLabel: o.label,
    })),
    [selectedDomainEmailSenders],
  );

  const emailSenderIdOptions = useMemo(
    () => selectedDomainEmailSenders.map((emailSender) => ({
      label: emailSender.label || emailSender.value,
      value: emailSender.label || emailSender.value,
      senderEmail: emailSender.value,
    })),
    [selectedDomainEmailSenders],
  );

  const emailReplyToOptions = useMemo(
    () => selectedDomainEmailRepliers.map((emailReplyTo) => ({
      label: emailReplyTo.value || emailReplyTo.label,
      value: emailReplyTo.value,
    })),
    [selectedDomainEmailRepliers],
  );

  const wecrmAccountOptions = useMemo(
    () => (wecrmAccounts || []).map((wecrmAccount) => ({
      label: wecrmAccount.name || wecrmAccount.sourceAccountIdentifier,
      value: wecrmAccount.sourceAccountIdentifier,
      ...wecrmAccount,
    })),
    [wecrmAccounts],
  );

  const whatsappAccountOptionsForDisplay = useMemo(() => {
    if (!isWhatsappAccountLocked || !whatsappAccountFromForm?.accountName) return wecrmAccountOptions;
    const name = whatsappAccountFromForm.accountName;
    const match = wecrmAccountOptions.find(
      (a) => (a.label === name || a.name === name),
    );
    if (match) return [match];
    return [{ label: name, value: name }];
  }, [isWhatsappAccountLocked, whatsappAccountFromForm?.accountName, wecrmAccountOptions]);

  const whatsappSenderOptions = useMemo(() => {
    const selectedAccId = get(localSettings, DELIVERY_SETTING_KEY_SOURCE_ACCOUNT_IDENTIFIER);
    if (!selectedAccId) {
      return (senderDetailsOptions || []).flatMap((senderDetails) => (senderDetails.gsmSenders || []).map((gsmSender) => ({
        label: gsmSender.value,
        value: gsmSender.value,
      })));
    }
    const domainForAccount = (senderDetailsOptions || []).find(
      (senderDetails) => senderDetails?.sourceAccountIdentifier === selectedAccId,
    );
    return (domainForAccount?.gsmSenders || []).map((gsmSender) => ({
      label: gsmSender.value,
      value: gsmSender.value,
    }));
  }, [senderDetailsOptions, localSettings.sourceAccountIdentifier]);

  const updateSetting = useCallback((key, value) => {
    setLocalSettings((prev) => {
      const next = cloneDeep(prev);
      next[key] = value;
      return next;
    });
  }, []);

  const onDomainChange = useCallback(
    (value) => {
      const domain = domainOptions.find((d) => d.value === value);
      updateSetting(DELIVERY_SETTING_KEY_DOMAIN_ID, value);
      if (domain?.dgmId != null) updateSetting(DELIVERY_SETTING_KEY_DOMAIN_GATEWAY_MAP_ID, domain.dgmId);
      if (channel === CHANNELS.SMS && domain) {
        const smsGsmSenders = smsTraiDltEnabled
          ? (domain.gsmSenders || []).filter((gsmId) => registeredSenderIds.includes(gsmId.value))
          : domain.gsmSenders;
        const def = findDefault(smsGsmSenders);
        updateSetting(DELIVERY_SETTING_KEY_GSM_SENDER_ID, def?.value || '');
        const defCdma = findDefault(domain.cdmaSenders);
        updateSetting(DELIVERY_SETTING_KEY_CDMA_SENDER_ID, defCdma?.value || '');
      }
      if (channel === CHANNELS.EMAIL && domain) {
        const defSender = findDefault(domain.emailSenders);
        const defReply = findDefault(domain.emailRepliers);
        updateSetting(DELIVERY_SETTING_KEY_SENDER_EMAIL, defSender?.value || '');
        updateSetting(DELIVERY_SETTING_KEY_SENDER_LABEL, defSender?.label || '');
        updateSetting(DELIVERY_SETTING_KEY_SENDER_REPLY_TO, defReply?.value || '');
      }
    },
    [channel, domainOptions, registeredSenderIds, smsTraiDltEnabled, updateSetting],
  );

  const handleDone = useCallback(() => {
    onSaveDeliverySettings(localSettings);
    if (onClose) onClose();
  }, [localSettings, onSaveDeliverySettings, onClose]);

  const renderSelectRow = useCallback(
    ({
      titleMessage, options, value, onChange, rowKey, disabled,
    }) => (
      <CapRow className="modify-delivery-settings__field-row" key={rowKey}>
        <CapHeader
          size="label"
          title={<FormattedMessage {...titleMessage} />}
          className="modify-delivery-settings__field-header"
        />
        <CapSelect
          options={options}
          value={value}
          onChange={onChange}
          placeholder={noOptionsLabel}
          componentClassName={`modify-delivery-settings__select${disabled ? ' modify-delivery-settings__select--disabled' : ''}`}
          disabled={disabled}
        />
        {disabled && <CapLabel type="label3">{formatMessage(messages.disabledMessage)}</CapLabel>}
      </CapRow>
    ),
    [noOptionsLabel],
  );

  const getChannelFields = useCallback(() => {
    const smsFields = [
      {
        titleMessage: messages.senderDomainLabel,
        options: domainOptions,
        value: get(localSettings, DELIVERY_SETTING_KEY_DOMAIN_ID),
        onChange: (val) => onDomainChange(val),
      },
      {
        titleMessage: messages.senderIdLabel,
        options: gsmOptions,
        value: get(localSettings, DELIVERY_SETTING_KEY_GSM_SENDER_ID),
        onChange: (val) => updateSetting(DELIVERY_SETTING_KEY_GSM_SENDER_ID, val),
      },
    ];
    const emailFields = [
      {
        titleMessage: messages.emailDomainLabel,
        options: domainOptions,
        value: get(localSettings, DELIVERY_SETTING_KEY_DOMAIN_ID),
        onChange: (val) => onDomainChange(val),
      },
      {
        titleMessage: messages.senderIdLabel,
        options: emailSenderOptions,
        value: get(localSettings, DELIVERY_SETTING_KEY_SENDER_EMAIL),
        onChange: (val) => {
          const sender = selectedDomainEmailSenders.find(
            (s) => s.value === val,
          );
          updateSetting(DELIVERY_SETTING_KEY_SENDER_EMAIL, val);
          updateSetting(DELIVERY_SETTING_KEY_SENDER_LABEL, sender?.label || val);
        },
      },
      {
        titleMessage: messages.senderNameLabelEmail,
        options: emailSenderIdOptions,
        value: get(localSettings, DELIVERY_SETTING_KEY_SENDER_LABEL) || '',
        onChange: (val) => {
          const sender = selectedDomainEmailSenders.find(
            (s) => (s.label || s.value) === val,
          );
          if (sender) {
            updateSetting(DELIVERY_SETTING_KEY_SENDER_EMAIL, sender.value);
            updateSetting(DELIVERY_SETTING_KEY_SENDER_LABEL, sender.label || sender.value);
          } else {
            updateSetting(DELIVERY_SETTING_KEY_SENDER_LABEL, val);
          }
        },
      },
      {
        titleMessage: messages.replyToIdLabel,
        options: emailReplyToOptions,
        value: get(localSettings, DELIVERY_SETTING_KEY_SENDER_REPLY_TO),
        onChange: (val) => updateSetting(DELIVERY_SETTING_KEY_SENDER_REPLY_TO, val),
      },
    ];
    const whatsappAccountValue = isWhatsappAccountLocked && whatsappAccountOptionsForDisplay.length > 0
      ? whatsappAccountOptionsForDisplay[0]?.value
      : get(localSettings, DELIVERY_SETTING_KEY_SOURCE_ACCOUNT_IDENTIFIER);
    const whatsappFields = [
      {
        titleMessage: messages.accountLabel,
        options: whatsappAccountOptionsForDisplay,
        value: whatsappAccountValue,
        onChange: (val) => {
          updateSetting(DELIVERY_SETTING_KEY_SOURCE_ACCOUNT_IDENTIFIER, val);
          const domain = (senderDetailsOptions || []).find(
            (d) => d.sourceAccountIdentifier === val,
          );
          const first = domain?.gsmSenders?.[0];
          updateSetting(DELIVERY_SETTING_KEY_SENDER_MOB_NUM, first?.value || '');
        },
        disabled: isWhatsappAccountLocked,
      },
      {
        titleMessage: messages.senderNumberLabel,
        options: whatsappSenderOptions,
        value: get(localSettings, DELIVERY_SETTING_KEY_SENDER_MOB_NUM),
        onChange: (val) => updateSetting(DELIVERY_SETTING_KEY_SENDER_MOB_NUM, val),
      },
    ];
    const byChannel = {
      [CHANNELS.SMS]: smsFields,
      [CHANNELS.EMAIL]: emailFields,
      [CHANNELS.WHATSAPP]: whatsappFields,
    };
    return byChannel[channel] || [];
  }, [
    channel,
    domainOptions,
    gsmOptions,
    emailSenderOptions,
    emailSenderIdOptions,
    emailReplyToOptions,
    wecrmAccountOptions,
    whatsappAccountOptionsForDisplay,
    whatsappSenderOptions,
    localSettings,
    selectedDomainEmailSenders,
    senderDetailsOptions,
    onDomainChange,
    updateSetting,
    isWhatsappAccountLocked,
    whatsappAccountFromForm,
  ]);

  if (isLoading) {
    return (
      <CapRow className="modify-delivery-settings__loading-row">
        <CapSpin spinning />
      </CapRow>
    );
  }

  return (
    <CapRow className="modify-delivery-settings">
      {getChannelFields().map((field, idx) => renderSelectRow({
        ...field,
        rowKey: field.titleMessage?.id || `${ROW_KEY_PREFIX}${idx}`,
        disabled: field.disabled,
      }))}
      <CapRow className="modify-delivery-settings__actions">
        <CapButton type="primary" onClick={handleDone}>
          <FormattedMessage {...messages.done} />
        </CapButton>
      </CapRow>
    </CapRow>
  );
};

ModifyDeliverySettings.propTypes = {
  channel: PropTypes.oneOf([CHANNELS.SMS, CHANNELS.EMAIL, CHANNELS.WHATSAPP]).isRequired,
  deliverySettings: PropTypes.object,
  senderDetailsOptions: PropTypes.array,
  wecrmAccounts: PropTypes.array,
  onSaveDeliverySettings: PropTypes.func.isRequired,
  onClose: PropTypes.func,
  isLoading: PropTypes.bool,
  formatMessage: PropTypes.func,
  smsTraiDltEnabled: PropTypes.bool,
  registeredSenderIds: PropTypes.array,
  whatsappAccountFromForm: PropTypes.shape({
    accountName: PropTypes.string,
  }),
};

ModifyDeliverySettings.defaultProps = {
  deliverySettings: {},
  senderDetailsOptions: [],
  wecrmAccounts: [],
  onClose: undefined,
  isLoading: false,
  formatMessage: undefined,
  smsTraiDltEnabled: false,
  registeredSenderIds: [],
  whatsappAccountFromForm: undefined,
};

export default ModifyDeliverySettings;
