/**
 * CommunicationFlow - Orchestrator Component
 *
 * Manages the step flow, validation, and data aggregation.
 * Renders steps based on config and calls callbacks with aggregated data.
 */

import React, {
  useState, useCallback, useMemo, useEffect,
} from 'react';
import PropTypes from 'prop-types';
import { injectIntl } from 'react-intl';
import { compose } from 'redux';
import { connect } from 'react-redux';
import { createStructuredSelector } from 'reselect';
// import { CouponsCapContainer } from '@capillarytech/cap-coupons'; // Commented - cap-coupons flows disabled
import CapRow from '@capillarytech/cap-ui-library/CapRow';
import CapDivider from '@capillarytech/cap-ui-library/CapDivider';
import CapButton from '@capillarytech/cap-ui-library/CapButton';
// import injectSaga from '../../utils/injectSaga';   // cap-coupons flows disabled
// import injectReducer from '../../utils/injectReducer';
import { makeSelectAuthenticated } from '../Cap/selectors';
import DynamicControlsStep from './steps/DynamicControlsStep';
import MessageTypeStep from './steps/MessageTypeStep';
import CommunicationStrategyStep from './steps/CommunicationStrategyStep';
import ChannelSelectionStep from './steps/ChannelSelectionStep';
import {
  STEPS,
  CHANNEL_PRIORITY,
  AB_TEST,
} from './constants';
import { getEnabledSteps } from './utils/getEnabledSteps';
import messages from './messages';
import './CommunicationFlow.scss';

// Inject couponsCap reducer and saga - commented out (cap-coupons flows disabled)
// const withCouponsReducer = injectReducer({
//   key: 'couponsCap',
//   reducer: CouponsCapContainer.couponsCapReducer,
// });
// const withCouponsSaga = injectSaga({
//   key: 'couponsCapSaga',
//   saga: CouponsCapContainer.couponsCapSaga,
// });

const CommunicationFlow = ({
  config,
  initialData,
  onSave,
  onCancel, // eslint-disable-line
  onChange,
  intl,
  capData, // From Redux - contains user/org info needed by CouponsWrapper
}) => {
  const { formatMessage } = intl || {};
  const { messageTypeData = {}, communicationStrategyData = {}, contentTemplateData = {} } = config?.features || {};
  // Initialize step data from initialData or defaults
  const [stepData, setStepData] = useState(() => {
    const defaultMessageType = messageTypeData.defaultOption?.value || null;
    return {
      messageType: initialData?.messageType || defaultMessageType,
      communicationStrategy: initialData?.communicationStrategy || null,
      channel: initialData?.channel || config.channel || null,
      channels: initialData?.channels || [],
      selectedOfferDetails: initialData?.selectedOfferDetails || [],
      contentItems: initialData?.contentItems || [],
      deliverySetting: initialData?.deliverySetting || {},
      dynamicControls: initialData?.dynamicControls || {},
    };
  });
  const [validationErrors, setValidationErrors] = useState({});

  // Memoize enabled steps
  const enabledSteps = useMemo(() => getEnabledSteps(config), [config]);

  /**
   * Get aggregated data from all steps
   */
  const getAggregatedData = useCallback(() => {
    const { communicationStrategy } = stepData;
    const isMultiChannel = [CHANNEL_PRIORITY, AB_TEST].includes(communicationStrategy);

    return {
      messageType: stepData.messageType,
      communicationStrategy: stepData.communicationStrategy,
      channel: isMultiChannel ? null : stepData.channel,
      channels: isMultiChannel ? stepData.channels : [],
      selectedOfferDetails: stepData.selectedOfferDetails,
      contentItems: stepData.contentItems || [],
      deliverySetting: stepData.deliverySetting,
      dynamicControls: stepData.dynamicControls,
    };
  }, [stepData]);

  /**
   * Handle step data change
   */
  const handleStepChange = useCallback((step, data) => {
    setStepData((prevStepData) => ({
      ...prevStepData,
      ...data,
    }));
    setValidationErrors((prevErrors) => ({
      ...prevErrors,
      [step]: null, // Clear validation error for this step
    }));
  }, []);

  // Call onChange callback when stepData changes
  useEffect(() => {
    if (onChange) {
      onChange(getAggregatedData());
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [stepData]);

  /**
   * Render all enabled steps
   */
  const renderSteps = useCallback(() => enabledSteps.map((step) => {
    const commonProps = {
      value: stepData,
      onChange: (data) => handleStepChange(step, data),
      error: validationErrors[step],
    };

    switch (step) {
      case STEPS.MESSAGE_TYPE:
        return (
          <CapRow useLegacy key={step}>
            <MessageTypeStep
              {...commonProps}
              value={stepData.messageType}
              options={messageTypeData.options}
              defaultOption={messageTypeData.defaultOption}
              onChange={(messageType) => handleStepChange(step, { messageType })}
            />
            <CapDivider />
          </CapRow>
        );
      case STEPS.COMMUNICATION_STRATEGY:
        return (
          <CapRow useLegacy key={step}>
            <CommunicationStrategyStep
              {...commonProps}
              value={stepData.communicationStrategy}
              // messageType={stepData.messageType}
              options={communicationStrategyData.options}
              disabled={communicationStrategyData.disabled}
              onChange={(communicationStrategy) => handleStepChange(step, { communicationStrategy })}
            />
            <CapDivider />
          </CapRow>
        );
      case STEPS.CHANNEL_SELECTION:
        // Only show ChannelSelectionStep if communication strategy is selected
        if (!stepData.communicationStrategy) {
          return null;
        }
        return (
          <CapRow useLegacy key={step}>
            <ChannelSelectionStep
              {...commonProps}
              value={stepData}
              channels={contentTemplateData.channels}
              onChange={(data) => handleStepChange(step, data)}
              channelsToHide={contentTemplateData.channelsToHide}
              channelsToDisable={contentTemplateData.channelsToDisable}
              creativesMode={config.mode || 'create'}
              selectedOfferDetails={stepData.selectedOfferDetails}
              incentivesData={config.features?.incentivesData}
              deliverySettingsData={config.features?.deliverySettingsData}
              config={config}
              capData={capData}
            />
            <CapDivider />
          </CapRow>
        );
      // This will be added back in when coupons/points are integrated so keeping it commented out for now
      // case STEPS.INCENTIVES:
      //   return (
      //     <IncentivesStep
      //       key={step}
      //       {...commonProps}
      //       value={stepData.selectedOfferDetails}
      //       onChange={(selectedOfferDetails) => handleStepChange(step, { selectedOfferDetails })}
      //     />
      //   );
      case STEPS.DYNAMIC_CONTROLS:
        // Only show DynamicControlsStep if communication strategy is selected
        if (!stepData.communicationStrategy) {
          return null;
        }
        return (
          <DynamicControlsStep
            key={step}
            {...commonProps}
            value={{ dynamicControls: stepData.dynamicControls }}
            controls={config.features?.dynamicControlsData?.controls || []}
            onChange={(data) => handleStepChange(step, { dynamicControls: data.dynamicControls })}
          />
        );
      default:
        return null;
    }
  }), [enabledSteps, stepData, validationErrors, config, handleStepChange, messageTypeData, communicationStrategyData, contentTemplateData]);

  return (
    <CapRow useLegacy className="communication-flow-container">
      {renderSteps()}
      {onSave && (
        <CapRow useLegacy className="communication-flow-container__footer">
          <CapButton type="primary" onClick={() => onSave(getAggregatedData())}>
            {formatMessage(messages.save)}
          </CapButton>
        </CapRow>
      )}
    </CapRow>
  );
};

CommunicationFlow.propTypes = {
  config: PropTypes.shape({
    consumer: PropTypes.oneOf(['campaigns', 'loyalty', 'adiona']).isRequired,
    channel: PropTypes.string,
    mode: PropTypes.oneOf(['create', 'edit', 'preview']).isRequired,
    channelsToHide: PropTypes.arrayOf(PropTypes.string),
    channelsToDisable: PropTypes.arrayOf(PropTypes.string),
    features: PropTypes.shape({
      enableMessageType: PropTypes.bool,
      enableCommunicationStrategy: PropTypes.bool,
      messageTypeData: PropTypes.shape({
        options: PropTypes.arrayOf(PropTypes.shape({
          value: PropTypes.string.isRequired,
          label: PropTypes.node.isRequired,
        })),
        defaultOption: PropTypes.shape({
          value: PropTypes.string.isRequired,
          label: PropTypes.node.isRequired,
        }),
        required: PropTypes.bool,
      }),
      communicationStrategyData: PropTypes.shape({
        options: PropTypes.arrayOf(PropTypes.shape({
          value: PropTypes.string.isRequired,
          label: PropTypes.node.isRequired,
        })),
        defaultOption: PropTypes.shape({
          value: PropTypes.string.isRequired,
          label: PropTypes.node.isRequired,
        }),
        required: PropTypes.bool,
        disabled: PropTypes.bool,
      }),
      contentTemplateData: PropTypes.shape({
        required: PropTypes.bool,
        channels: PropTypes.object,
      }),
      enableIncentives: PropTypes.bool,
      enableDeliverySettings: PropTypes.bool,
      enableOtherSettings: PropTypes.bool,
      incentivesTypes: PropTypes.arrayOf(PropTypes.oneOf(['coupons', 'points', 'promotions', 'giftVouchers', 'badges'])),
    }),
    context: PropTypes.object,
  }).isRequired,
  initialData: PropTypes.object,
  onSave: PropTypes.func.isRequired,
  onCancel: PropTypes.func.isRequired,
  onChange: PropTypes.func,
  intl: PropTypes.object.isRequired,
  capData: PropTypes.object,
};

CommunicationFlow.defaultProps = {
  initialData: null,
  onChange: null,
  capData: {},
};

const mapStateToProps = createStructuredSelector({
  capData: makeSelectAuthenticated(),
});

const withConnect = connect(mapStateToProps);

export default compose(
  // withCouponsReducer, // cap-coupons flows disabled
  // withCouponsSaga,   // cap-coupons flows disabled
  withConnect,
  injectIntl,
)(CommunicationFlow);
