/**
 * SenderDetails - Config-driven sender details slidebox for all channels
 *
 * Renders fields from deliverySettingsConfig. Add new channels/fields in config.
 * Supports theme via BEM classes (sender-details__*).
 */

import React, {
  useState, useEffect, useCallback, useMemo,
} from 'react';
import PropTypes from 'prop-types';
import { injectIntl } from 'react-intl';
import CapSlideBox from '@capillarytech/cap-ui-library/CapSlideBox';
import CapRow from '@capillarytech/cap-ui-library/CapRow';
import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
import CapIcon from '@capillarytech/cap-ui-library/CapIcon';
import CapButton from '@capillarytech/cap-ui-library/CapButton';
import CapSelect from '@capillarytech/cap-ui-library/CapSelect';
import CapLabel from '@capillarytech/cap-ui-library/CapLabel';
import CapLink from '@capillarytech/cap-ui-library/CapLink';
import CapSpin from '@capillarytech/cap-ui-library/CapSpin';
import CapTooltip from '@capillarytech/cap-ui-library/CapTooltip';
import CapError from '@capillarytech/cap-ui-library/CapError';
import {
  getFieldsForChannels,
  FIELD_TYPE,
  parseEntityForDisplay,
  getDefaultValueForField,
  getEmailDefaultsForDomainId,
  getSmsDefaultsForDomainId,
  getRcsAccountName,
} from './deliverySettingsConfig';
import messages from '../../messages';
import './SenderDetails.scss';

/** Re-export for DeliverySettingsSection - uses config's parseEntityForDisplay */
export const parseSenderDetailsFromEntity = parseEntityForDisplay;

const SenderDetails = ({
  show,
  onClose,
  channels = [],
  preloadedDomainProperties,
  savedFieldValues,
  onSave,
  whatsappSourceAccountId,
  whatsappAccountName,
  intl,
}) => {
  const { formatMessage } = intl || {};

  const [entity, setEntity] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [fieldValues, setFieldValues] = useState({});
  const [initialFieldValues, setInitialFieldValues] = useState({});

  const channelKey = (channels || []).join(',');
  const fieldConfigs = useMemo(() => getFieldsForChannels(channels), [channelKey]);

  // Context for WABA-bound fields (WhatsApp sender number filtered by sourceAccountIdentifier)
  const wabaContext = useMemo(() => ({
    whatsappSourceAccountId: whatsappSourceAccountId || '',
  }), [whatsappSourceAccountId]);

  // Only use preloaded data from parent (DeliverySettingsSection) - no fetch here to avoid duplicate API calls
  // When reopening, use savedFieldValues to restore user's last saved selections
  useEffect(() => {
    if (!show || !channels?.length) return;
    if (preloadedDomainProperties) {
      setEntity(preloadedDomainProperties);
      const initial = {};
      fieldConfigs.forEach((config) => {
        const fromEntity = config.getValue(preloadedDomainProperties, wabaContext) || '';
        const fromSaved = savedFieldValues?.[config.fieldKey];
        initial[config.fieldKey] = (fromSaved != null && fromSaved !== '') ? fromSaved : fromEntity;
      });
      // Set WhatsApp account name (disabled field, driven by template)
      if (whatsappAccountName) {
        initial.whatsappAccount = whatsappAccountName;
      }
      // Set RCS account name (disabled field)
      const rcsAccName = getRcsAccountName(preloadedDomainProperties);
      if (rcsAccName) {
        initial.rcsAccount = rcsAccName;
      }
      setFieldValues(initial);
      setInitialFieldValues(initial);
      setLoading(false);
      setError(null);
    } else {
      // preloadedDomainProperties is not yet available (or the parent's fetch failed).
      // Show nothing rather than an eternal spinner — the parent controls data availability.
      setLoading(false);
      setEntity(null);
      setFieldValues({});
      setInitialFieldValues({});
    }
  }, [show, channels, preloadedDomainProperties, savedFieldValues, fieldConfigs, whatsappAccountName, wabaContext]);

  const handleFieldChange = useCallback((fieldKey, value) => {
    setFieldValues((prev) => {
      const next = { ...prev, [fieldKey]: value };
      if (fieldKey === 'smsDomain' && entity) {
        const defs = getSmsDefaultsForDomainId(entity, value);
        next.smsSenderId = defs.senderId;
      }
      if (fieldKey === 'emailDomain' && entity) {
        const defs = getEmailDefaultsForDomainId(entity, value);
        next.emailSenderId = defs.senderId;
        next.emailSenderName = defs.senderName;
        next.emailReplyToId = defs.replyToId;
      }
      return next;
    });
  }, [entity]);

  const handleReset = useCallback((fieldKey) => {
    setFieldValues((prev) => {
      const next = { ...prev };
      if (fieldKey === 'smsDomain') {
        const defaultDomain = getDefaultValueForField('smsDomain', entity, { fieldValues: prev });
        const defs = getSmsDefaultsForDomainId(entity, defaultDomain);
        next.smsDomain = defaultDomain;
        next.smsSenderId = defs.senderId;
      } else if (fieldKey === 'emailDomain') {
        const defaultDomain = getDefaultValueForField('emailDomain', entity, { fieldValues: prev });
        const defs = getEmailDefaultsForDomainId(entity, defaultDomain);
        next.emailDomain = defaultDomain;
        next.emailSenderId = defs.senderId;
        next.emailSenderName = defs.senderName;
        next.emailReplyToId = defs.replyToId;
      } else {
        next[fieldKey] = getDefaultValueForField(fieldKey, entity, { fieldValues: prev });
      }
      return next;
    });
  }, [entity]);

  const handleSave = () => {
    if (onSave) {
      const saveValues = { ...fieldValues };
      // Include WhatsApp domainId derived from sourceAccountIdentifier for persistence
      if (whatsappSourceAccountId && entity) {
        const whatsappDomains = entity?.WHATSAPP || [];
        const matchedDomain = (Array.isArray(whatsappDomains) ? whatsappDomains : [whatsappDomains]).find((domain) => {
          const connectionProperties = domain?.domainProperties?.connectionProperties || {};
          return (connectionProperties.sourceAccountIdentifier || connectionProperties.wabaId || connectionProperties.userid) === whatsappSourceAccountId;
        });
        if (matchedDomain) {
          saveValues.whatsappDomainId = matchedDomain?.domainProperties?.id ?? matchedDomain?.domainId ?? matchedDomain?.id;
        }
      }
      onSave(saveValues);
    }
    onClose();
  };

  const hasChanges = useMemo(() => {
    const editableKeys = new Set(
      fieldConfigs.filter((fieldConfig) => fieldConfig.type !== FIELD_TYPE.DISPLAY && !fieldConfig.disabled).map((fieldConfig) => fieldConfig.fieldKey),
    );
    return [...editableKeys].some((fieldKey) => (fieldValues[fieldKey] ?? '') !== (initialFieldValues[fieldKey] ?? ''));
  }, [fieldValues, initialFieldValues, fieldConfigs]);

  const hasAllValues = useMemo(
    () => fieldConfigs
      .filter((config) => config.type !== FIELD_TYPE.DISPLAY && !config.disabled)
      .every((config) => (fieldValues[config.fieldKey] ?? '').toString().trim() !== ''),
    [fieldValues, fieldConfigs],
  );

  const header = (
    <CapRow type="flex" align="middle" justify="space-between" className="sender-details__header">
      <CapRow type="flex" align="middle" className="sender-details__header-left">
        <CapIcon type="arrow-left" size="s" onClick={onClose} className="sender-details__back-icon" aria-label="Back" />
        <CapHeading type="h1">{formatMessage(messages.senderDetails)}</CapHeading>
      </CapRow>
    </CapRow>
  );

  const footer = (
    <CapRow className="sender-details__footer">
      <CapButton type="primary" onClick={handleSave} disabled={!hasChanges || !hasAllValues}>
        {formatMessage(messages.saveChanges)}
      </CapButton>
    </CapRow>
  );

  const renderField = (config) => {
    const {
      fieldKey, messageKey, type, getOptions, disabled: isDisabled,
    } = config;
    const value = fieldValues[fieldKey] ?? '';
    const optionContext = { fieldValues, ...wabaContext };
    const options = entity && getOptions ? (getOptions(entity, optionContext) || []) : [];

    // WhatsApp/RCS account: disabled field showing account name, build options from value
    if (isDisabled && (fieldKey === 'whatsappAccount' || fieldKey === 'rcsAccount') && value) {
      const accountOptions = [{ label: value, value }];
      const selectNode = (
        <CapSelect
          value={value}
          placeholder={formatMessage(messages.select)}
          className="sender-details__select"
          options={accountOptions}
          style={{ width: '20.375rem' }}
          disabled
        />
      );
      return (
        <CapRow key={fieldKey} className="sender-details__field">
          <CapHeading type="h4">{formatMessage(messages[messageKey] || { defaultMessage: messageKey })}</CapHeading>
          <CapRow type="flex" align="middle" className="sender-details__field-row">
            {fieldKey === 'whatsappAccount' ? (
              <CapTooltip title={formatMessage(messages.whatsappAccountTooltip)} overlayClassName="sender-details__account-name-tooltip">
                {selectNode}
              </CapTooltip>
            ) : selectNode}
          </CapRow>
        </CapRow>
      );
    }

    if (type === FIELD_TYPE.DISPLAY) {
      return (
        <CapHeading type="h4">{formatMessage(messages[messageKey] || { defaultMessage: messageKey }, { domain: value })}</CapHeading>
      );
    }

    if (type === FIELD_TYPE.SELECT) {
      const isSingleOption = options.length <= 1;
      const isDomainField = fieldKey === 'smsDomain' || fieldKey === 'emailDomain';
      const showEmptyOptionsError = !isDisabled && entity && options?.length === 0;
      const emptyOptionsErrorMsg = isDomainField
        ? formatMessage(messages.domainGatewayError)
        : formatMessage(messages.senderNotConfiguredError);
      return (
        <CapRow key={fieldKey} className="sender-details__field">
          <CapHeading type="h4">{formatMessage(messages[messageKey] || { defaultMessage: messageKey })}</CapHeading>
          <CapRow type="flex" align="middle" className="sender-details__field-row">
            <CapSelect
              value={value}
              onChange={(val) => handleFieldChange(fieldKey, val)}
              placeholder={formatMessage(messages.select)}
              className="sender-details__select"
              options={options}
              style={{ width: '20.375rem' }}
              disabled={isDisabled}
            />
            {!isDisabled && (
              <CapLink
                type="false"
                fontWeight="m"
                className="sender-details__reset-link"
                title={formatMessage(messages.reset)}
                onClick={() => { if (!isSingleOption) handleReset(fieldKey); }}
              />
            )}
          </CapRow>
          {showEmptyOptionsError && (
            <CapError type="error" className="sender-details__field-error">
              {emptyOptionsErrorMsg}
            </CapError>
          )}
        </CapRow>
      );
    }
    return null;
  };

  const content = (
    <CapSpin spinning={loading}>
      <CapRow className="sender-details__content">
        {error && <CapLabel type="label2" className="sender-details__error">{error}</CapLabel>}
        {!loading && !error && entity && fieldConfigs.length > 0 && (
        <>
          {fieldConfigs?.map((config) => renderField(config))}
        </>
        )}
      </CapRow>
    </CapSpin>
  );

  return (
    <CapSlideBox
      show={show}
      handleClose={onClose}
      header={header}
      footer={footer}
      content={content}
      className="sender-details"
      closeIconPosition="right"
    />
  );
};

SenderDetails.propTypes = {
  show: PropTypes.bool.isRequired,
  onClose: PropTypes.func.isRequired,
  channels: PropTypes.arrayOf(PropTypes.string),
  preloadedDomainProperties: PropTypes.object,
  savedFieldValues: PropTypes.object,
  onSave: PropTypes.func,
  whatsappSourceAccountId: PropTypes.string,
  whatsappAccountName: PropTypes.string,
  intl: PropTypes.object.isRequired,
};

SenderDetails.defaultProps = {
  channels: [],
  preloadedDomainProperties: null,
  savedFieldValues: null,
  onSave: null,
  whatsappSourceAccountId: '',
  whatsappAccountName: '',
};

export default injectIntl(SenderDetails);
