/**
 * ChannelSelectionStep Component
 *
 * Content template selection with channel dropdown
 */

import React, { useState, useCallback, useMemo } from 'react';
import PropTypes from 'prop-types';
import { injectIntl } from 'react-intl';
import CapButton from '@capillarytech/cap-ui-library/CapButton';
import CapRow from '@capillarytech/cap-ui-library/CapRow';
import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
import CapDropdown from '@capillarytech/cap-ui-library/CapDropdown';
import CapMenu from '@capillarytech/cap-ui-library/CapMenu';
import CapIcon from '@capillarytech/cap-ui-library/CapIcon';
import CapLabel from '@capillarytech/cap-ui-library/CapLabel';
import CapHeader from '@capillarytech/cap-ui-library/CapHeader';
import CapCustomCard from '@capillarytech/cap-ui-library/CapCustomCard';
import CreativesContainer from '../../../CreativesContainer';
import { DeliverySettingsSection } from '../DeliverySettingsStep';
import { CHANNELS } from '../../constants';
import { VIBER, MOBILE_PUSH, MPUSH, SMS, EMAIL } from '../../../CreativesContainer/constants';
// TemplatesV2 pane keys (for channelsToHide) - derived from CHANNELS + FTP
const CREATIVES_PANE_KEYS = [...CHANNELS?.map((channel) => channel?.paneKey), 'FTP'];
// Channels that TemplatesV2 shows only when enableNewChannels includes them (not in commonChannels)
const ENABLE_NEW_CHANNELS = CHANNELS.filter((channel) => channel.requiresEnableNewChannels).map((channel) => channel?.value);
import messages from '../../messages';
import './ChannelSelectionStep.scss';

// cap-coupons flows commented out
// import { CouponsWrapper, CouponsPointsStrategy } from '@capillarytech/cap-coupons';

const generateContentId = () => `content_${Date.now()}`;

const ChannelSelectionStep = ({
  value,
  channels, // eslint-disable-line
  communicationStrategy, // eslint-disable-line
  onChange,
  channelsToHide = [],
  channelsToDisable = [],
  creativesMode = 'create',
  selectedOfferDetails = [],
  incentivesData,
  deliverySettingsData,
  error,
  intl,
  capData, // From Redux - contains user/org info needed by CouponsWrapper
}) => {
  const contentItems = value?.contentItems || [];
  const [showCreativesContainer, setShowCreativesContainer] = useState(false);
  const [selectedChannel, setSelectedChannel] = useState(null);
  const [editingContentId, setEditingContentId] = useState(null);
  const [showChannelsMenu, setShowChannelsMenu] = useState(false);
  // Keyed by contentId (or 'standalone' for the empty-state button) so each dropdown controls its own open state
  const [showIncentivesMenuMap, setShowIncentivesMenuMap] = useState({});
  const { formatMessage } = intl || {};

  // Available channels (filter out hidden ones)
  // Fallback to CHANNELS constant if channels prop is not provided
  const channelsList = channels || CHANNELS;
  const availableChannels = useMemo(() => channelsList?.filter((channel) => channel?.isActive), [channelsList]);
  const availableIncentiveTypes = useMemo(() => incentivesData?.types?.filter((incentive) => incentive?.isActive), [incentivesData]);
  // Derive channel config from CHANNELS for CreativesContainer
  const selectedChannelConfig = useMemo(() => {
    if (!selectedChannel) return null;
    const selectedChannelLowerCase = selectedChannel?.toLowerCase();
    return CHANNELS.find((channel) => channel?.value?.toLowerCase() === selectedChannelLowerCase || channel?.channelProp === selectedChannelLowerCase) || null;
  }, [selectedChannel]);
  /**
   * Handle CreativesContainer close
   */
  const handleCloseCreatives = useCallback(() => {
    setShowCreativesContainer(false);
    setSelectedChannel(null);
    setEditingContentId(null);
    setShowChannelsMenu(false);
  }, []);

  /**
   * Handle CreativesContainer data callback - persist content for create/edit
   */
  const handleCreativesData = useCallback((data) => {
    if (!selectedChannel || !data) return;
    const channelValue = CHANNELS.find((channel) => channel?.channelProp === selectedChannel)?.value || selectedChannel.toUpperCase();
    const newItem = {
      contentId: editingContentId || generateContentId(),
      channel: channelValue,
      templateData: data,
    };
    const updatedItems = editingContentId
      ? contentItems.map((item) => (item.contentId === editingContentId ? { ...item, ...newItem, templateData: data } : item))
      : [...contentItems, newItem];
    onChange({ contentItems: updatedItems });
    setShowCreativesContainer(false);
    setSelectedChannel(null);
    setEditingContentId(null);
  }, [selectedChannel, editingContentId, contentItems, onChange]);

  const handleEditContent = useCallback((contentId) => {
    const item = contentItems.find((c) => c.contentId === contentId);
    if (!item) return;
    const channelConfig = CHANNELS.find((channel) => channel?.value === item?.channel || channel?.channelProp === item?.channel?.toLowerCase());
    if (channelConfig) {
      setSelectedChannel(channelConfig.channelProp);
      setEditingContentId(contentId);
      setShowCreativesContainer(true);
    }
  }, [contentItems]);

  const handleDeleteContent = useCallback((contentId) => {
    onChange({ contentItems: contentItems.filter((c) => c.contentId !== contentId) });
  }, [contentItems, onChange]);

  /** Get short preview text for content card */
  const getContentPreview = (item) => {
    const templateData = item?.templateData || {};
    const channel = item?.channel?.toUpperCase();
    if (templateData?.messageBody) return templateData.messageBody?.substring?.(0, 100) || templateData.messageBody;
    if (templateData?.emailSubject) return templateData.emailSubject;
    if (templateData?.smsBody) return templateData.smsBody?.substring?.(0, 100) || templateData.smsBody;
    if (templateData?.message) return templateData.message?.substring?.(0, 100) || templateData.message;
    // Mobile push: notificationTitle, notificationBody, or android/ios content
    if (channel === MOBILE_PUSH || channel === MPUSH) {
      const title = templateData?.notificationTitle || templateData?.androidContent?.notificationTitle || templateData?.iosContent?.notificationTitle;
      const body = templateData?.notificationBody || templateData?.androidContent?.body || templateData?.iosContent?.body || templateData?.androidContent?.notificationBody || templateData?.iosContent?.notificationBody;
      if (title) return title;
      if (body) return body?.substring?.(0, 100) || body;
    }
    // Viber: messageBody is JSON string, extract content.text (campaigns pattern)
    if (channel === VIBER) {
      try {
        const parsed = typeof templateData?.messageBody === 'string' ? JSON.parse(templateData?.messageBody || '{}') : templateData?.messageBody;
        const text = parsed?.content?.text || '';
        return text ? text?.substring?.(0, 100) : item?.channel || '';
      } catch {
        return templateData?.messageBody?.substring?.(0, 100) || item?.channel || '';
      }
    }
    return item?.channel || '';
  };

  /** Get sender details display for card footer (e.g. SMS sender ID) */
  const getSenderDetailsDisplay = (item) => {
    const templateData = item?.templateData || {};
    const channel = item?.channel?.toUpperCase();
    if (channel === SMS) {
      const senderId = templateData?.templateConfigs?.registeredSenderIds || templateData?.header;
      return senderId ? `SMS sender ID ${senderId}` : null;
    }
    if (channel === EMAIL) return templateData?.emailFrom || null;
    // Viber: sender from templateConfigs (campaigns/adiona pattern)
    if (channel === VIBER) {
      const senderId = templateData?.templateConfigs?.viberSenderId || templateData?.viberSenderId;
      return senderId ? `Viber sender ID ${senderId}` : null;
    }
    return null;
  };

  /** Map channel to CapCustomCard type for styling (like adiona getEngagementCardType) */
  const getCardType = (channel) => {
    const upperCaseChannel = channel?.toUpperCase();
    const mapping = { MOBILEPUSH: MPUSH, MPUSH: MPUSH };
    return mapping[upperCaseChannel] || channel;
  };

  const handlePreviewContent = useCallback((item) => {
    // Placeholder for preview - can be wired to Preview slidebox when available
    // eslint-disable-next-line no-console
    console.log('Preview content', item?.contentId);
  }, []);

  const handleChannelSelect = (channelValue) => {
    // Check if channel is supported (not in channelsToHide or channelsToDisable)
    if (channelsToHide.includes(channelValue) || channelsToDisable.includes(channelValue)) {
      return;
    }

    // Find the channel object to verify it's active
    const selectedChannelObj = availableChannels?.find((channel) => channel?.value === channelValue);
    if (!selectedChannelObj || !selectedChannelObj?.isActive) {
      return;
    }

    // Update parent component with selected channel
    onChange({ channel: channelValue, channels: [] });

    // Open CreativesContainer - derive channelProp from config
    const lowerCaseChannelValue = channelValue?.toLowerCase();
    const channelConfig = lowerCaseChannelValue && CHANNELS.find((channel) => channel?.value?.toLowerCase() === lowerCaseChannelValue || channel?.channelProp === lowerCaseChannelValue);
    if (!channelConfig?.channelProp || channelConfig.channelProp === 'ftp') {
      return;
    }

    setSelectedChannel(channelConfig.channelProp);
    setShowCreativesContainer(true);
  };

  const handleChannelMenuClick = ({ key }) => {
    // key should be the channel value (e.g., 'SMS', 'EMAIL', etc.)
    handleChannelSelect(key);
    setShowChannelsMenu(false);
  };

  const handleIncentiveSelect = (incentiveType) => {
    // Update selectedOfferDetails with the selected incentive
    const updatedOfferDetails = [...(selectedOfferDetails || []), { type: incentiveType }];
    onChange({ selectedOfferDetails: updatedOfferDetails });
  };

  const handleIncentiveMenuClick = ({ key }, cardId) => {
    setShowIncentivesMenuMap((prev) => ({ ...prev, [cardId]: false }));
    // cap-coupons flows disabled - skip coupons/points
    if (key === 'coupons' || key === 'points') return;
    handleIncentiveSelect(key);
  };

  const handleChannelsVisibleChange = (visible) => {
    setShowChannelsMenu(visible);
  };

  const handleIncentivesVisibleChange = (visible, cardId) => {
    setShowIncentivesMenuMap((prev) => ({ ...prev, [cardId]: visible }));
  };

  /* cap-coupons flows disabled - handlers commented out
  const handleClaimCoupon = useCallback((claimedCouponData) => {...}, [selectedOfferDetails, onChange]);
  const handleEditCoupon = useCallback(() => {}, []);
  const handleCreateCoupon = useCallback(() => {}, []);
  const handleViewCoupon = useCallback(() => {}, []);
  const handleEditCouponAction = useCallback(() => {}, []);
  const handleTogglePreview = useCallback(() => {}, []);
  const handleToggleAdvanceView = useCallback(() => {}, []);
  const handleCancelCreateCoupon = useCallback(() => {}, []);
  const handleClaimPoints = useCallback((claimedPointsData) => {...}, [selectedOfferDetails, onChange]);
  const handleCloseCouponsSlidebox = useCallback(() => {}, []);
  const handleClosePointsSlidebox = useCallback(() => {}, []);
  */

  const renderChannelDropdownOverlay = () => {
    if (!availableChannels || availableChannels.length === 0) {
      return null;
    }

    // Filter out FTP and ensure only active channels are shown
    const filteredChannels = availableChannels.filter((channel) => {
      const isFTP = channel.value === 'FTP' || channel.value === 'ftp';
      const isHidden = channelsToHide.includes(channel.value);
      const isDisabled = channelsToDisable.includes(channel.value);
      return !isFTP && !isHidden && channel.isActive;
    });

    if (filteredChannels.length === 0) {
      return null;
    }

    return (
      <CapMenu onClick={handleChannelMenuClick} className="channel-dropdown-content">
        {filteredChannels.map((channel) => {
          const isDisabled = channelsToDisable.includes(channel.value);
          const iconType = channel.iconType;
          const displayLabel = channel.label || channel.value;

          return (
            <CapMenu.Item key={channel.value} disabled={isDisabled}>
              <CapRow align="middle" type="flex" className="channel-row">
                <CapIcon type={iconType} className="channel-icon" size="s" />
                <CapHeading type="h5">{displayLabel}</CapHeading>
              </CapRow>
            </CapMenu.Item>
          );
        })}
      </CapMenu>
    );
  };

  const renderIncentiveDropdownOverlay = (onMenuClick) => {
    if (availableIncentiveTypes?.length === 0) {
      return null;
    }
    const filteredIncentiveTypes = availableIncentiveTypes?.filter(
      (incentive) => incentive?.value !== 'coupons' && incentive?.value !== 'points',
    );
    if (filteredIncentiveTypes?.length === 0) return null;

    return (
      <CapMenu onClick={onMenuClick} className="incentive-dropdown-content">
        {filteredIncentiveTypes.map((incentive) => {
          const isDisabled = incentive?.disabled || false;
          return (
            <CapMenu.Item key={incentive.value} disabled={isDisabled}>
              {incentive.label}
            </CapMenu.Item>
          );
        })}
      </CapMenu>
    );
  };

  /** Configured state: CapCustomCard per content item - matches campaigns-ui structure */
  const renderConfiguredCard = (item) => {
    const channelConfig = CHANNELS.find((c) => c.value === item.channel || c.channelProp === item.channel?.toLowerCase());
    const iconType = channelConfig?.iconType || 'sms';
    const channelLabel = channelConfig?.label || item.channel;
    const senderDetailsText = getSenderDetailsDisplay(item);
    const hasIncentiveOptions = incentivesData && availableIncentiveTypes?.some((i) => i.value !== 'coupons' && i.value !== 'points');

    const card = {
      title: (
        <CapRow align="middle" type="flex" className="card-title-row">
          <CapIcon type={iconType} className="channel-icon" size="s" />
          <CapHeader size="label1" titleClass="truncate-text" title={<span title={channelLabel}>{channelLabel}</span>} />
        </CapRow>
      ),
      content: (
        <CapRow className="content-card-body">
          <CapLabel type="label2" className="content-preview-text">
            {getContentPreview(item)}
          </CapLabel>
          {senderDetailsText && (
            <CapRow type="flex" align="middle" justify="space-between" className="sender-details-row">
              <CapLabel type="label2">{senderDetailsText}</CapLabel>
              <CapIcon type="arrow-right" size="s" className="sender-details-arrow" />
            </CapRow>
          )}
        </CapRow>
      ),
      cardType: getCardType(item.channel),
      extra: (
        <CapDropdown
          overlay={
            <CapMenu>
              <CapMenu.Item
                id="edit-menu-item"
                className="ant-dropdown-menu-item"
                onClick={() => handleEditContent(item.contentId)}
              >
                 {formatMessage(messages.edit)}
              </CapMenu.Item>
              <CapMenu.Item
                id="preview-menu-item"
                className="ant-dropdown-menu-item"
                onClick={() => handlePreviewContent(item)}
              >
                {formatMessage(messages.previewAndTest)}
              </CapMenu.Item>
              <CapMenu.Item
                id="delete-menu-item"
                onClick={() => handleDeleteContent(item.contentId)}
              >
                {formatMessage(messages.remove)}
              </CapMenu.Item>
            </CapMenu>
          }
        >
          <CapIcon type="more" aria-label="Show more content options icon" />
        </CapDropdown>
      ),
    };

    // Add incentive in actions (campaigns-ui style: cap-card-action-container)
    if (hasIncentiveOptions) {
      card.actions = [
        <CapRow className="cap-card-action-container add-incentive-action-row" key="add-incentive">
          <CapDropdown
            overlay={renderIncentiveDropdownOverlay((menuClickEvent) => handleIncentiveMenuClick(menuClickEvent, item.contentId))}
            onVisibleChange={(visible) => handleIncentivesVisibleChange(visible, item.contentId)}
            visible={!!showIncentivesMenuMap[item.contentId]}
          >
            <CapButton isAddBtn type="flat" className="add-incentives-button add-incentive-link">
              {formatMessage(messages.addIncentive)}
            </CapButton>
          </CapDropdown>
          <CapLabel type="label1" className="optional-incentive-label">
            {formatMessage(messages.optional)}
          </CapLabel>
        </CapRow>,
      ];
    }

    return card;
  };

  return (
    <>
      <CapRow className="channel-selection-step">
        <CapHeading type="h3" className="margin-b-8">
          {formatMessage(messages.contentTemplate)}
        </CapHeading>

        <CapRow
          className={`content-template-container ${contentItems?.length > 0 ? 'content-template-container--has-content' : ''}`}
        >
          {contentItems?.length === 0 ? (
            <CapRow className="content-template-section">
              <CapHeading type="h5">
                {formatMessage(messages.addMessageContentAndIncentive)}
              </CapHeading>

              <CapDropdown
                overlay={renderChannelDropdownOverlay()}
                onVisibleChange={handleChannelsVisibleChange}
                visible={showChannelsMenu}
              >
                <CapButton
                  isAddBtn
                  type="primary"
                  className="add-content-template-button"
                >
                  {formatMessage(messages.addContentTemplate)}
                </CapButton>
              </CapDropdown>
            </CapRow>
          ) : (
            <CapCustomCard.CapCustomCardList
              cardList={contentItems.map(renderConfiguredCard)}
              className="content-items-list"
            />
          )}

          {contentItems?.length === 0 &&
            incentivesData &&
            availableIncentiveTypes?.some((i) => i.value !== 'coupons' && i.value !== 'points') && (
              <CapRow type="flex" justify="center" align="middle" className="incentive-section">
                <CapDropdown
                  overlay={renderIncentiveDropdownOverlay((menuClickEvent) => handleIncentiveMenuClick(menuClickEvent, 'standalone'))}
                  onVisibleChange={(visible) => handleIncentivesVisibleChange(visible, 'standalone')}
                  visible={!!showIncentivesMenuMap.standalone}
                >
                  <CapButton isAddBtn type="flat" className="add-incentive-button">
                    {formatMessage(messages.addIncentive)}
                  </CapButton>
                </CapDropdown>
                <CapHeading type="label4" className="optional-text">
                  {formatMessage(messages.optional)}
                </CapHeading>
              </CapRow>
            )}

          {contentItems?.length > 0 && (
            <DeliverySettingsSection
              contentItems={contentItems}
              deliverySettingsData={deliverySettingsData}
              deliverySetting={value?.deliverySetting}
              onDeliverySettingChange={(deliverySetting) => onChange({ deliverySetting })}
              intl={intl}
            />
          )}
        </CapRow>

        {error && (
          <CapRow className="validation-error">
            {error}
          </CapRow>
        )}
      </CapRow>

      {showCreativesContainer && selectedChannelConfig && (
        <CreativesContainer
          key={`creatives-${selectedChannel}-${editingContentId || 'create'}`}
          channel={selectedChannelConfig.channelProp}
          creativesMode={editingContentId ? 'edit' : creativesMode}
          getCreativesData={handleCreativesData}
          handleCloseCreatives={handleCloseCreatives}
          isFullMode={false}
          messageDetails={{ type: 'default' }}
          templateData={editingContentId ? contentItems.find((c) => c.contentId === editingContentId)?.templateData : null}
          selectedOfferDetails={selectedOfferDetails}
          channelsToHide={[
            ...(channelsToHide || []),
            ...CREATIVES_PANE_KEYS.filter((key) => key !== selectedChannelConfig.paneKey),
          ]}
          channelsToDisable={channelsToDisable}
          enableNewChannels={ENABLE_NEW_CHANNELS}
        />
      )}

      {/* cap-coupons flows disabled - Coupons and Points slideboxes commented out */}
    </>
  );
};

ChannelSelectionStep.propTypes = {
  value: PropTypes.object, // stepData (channel, contentItems, etc.)
  channels: PropTypes.arrayOf(PropTypes.shape({
    value: PropTypes.string.isRequired,
    label: PropTypes.string,
    isActive: PropTypes.bool,
    iconType: PropTypes.string,
    channelProp: PropTypes.string,
    paneKey: PropTypes.string,
  })),
  communicationStrategy: PropTypes.string,
  onChange: PropTypes.func.isRequired,
  channelsToHide: PropTypes.array,
  channelsToDisable: PropTypes.array,
  creativesMode: PropTypes.oneOf(['create', 'edit', 'preview']),
  selectedOfferDetails: PropTypes.array,
  incentivesData: PropTypes.shape({
    types: PropTypes.array,
    required: PropTypes.bool,
  }),
  deliverySettingsData: PropTypes.object,
  error: PropTypes.string,
  intl: PropTypes.object.isRequired,
  capData: PropTypes.object, // Cap data from Redux (user/org info)
};

ChannelSelectionStep.defaultProps = {
  value: null,
  channels: [],
  communicationStrategy: null,
  error: null,
  channelsToHide: [],
  channelsToDisable: [],
  creativesMode: 'create',
  selectedOfferDetails: [],
  incentivesData: null,
  capData: {},
};

export default injectIntl(ChannelSelectionStep);
