import React, {
  useState,
  useEffect,
  useRef,
  useCallback,
  useMemo,
  memo,
} from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from 'react-intl';
import { createStructuredSelector, createSelector } from 'reselect';
import { bindActionCreators } from 'redux';
import {
  injectReducer,
  injectSaga,
} from '@capillarytech/vulcan-react-sdk/utils';
import { DAEMON } from '@capillarytech/vulcan-react-sdk/utils/sagaInjectorTypes';
import CapRow from '@capillarytech/cap-ui-library/CapRow';
import CapColumn from '@capillarytech/cap-ui-library/CapColumn';
import TagList from '../../TagList';
import WebPushPreview from './preview/WebPushPreview';
import TemplateNameSection from './components/TemplateNameSection';
import NotificationTitleSection from './components/NotificationTitleSection';
import MessageSection from './components/MessageSection';
import MediaSection from './components/MediaSection';
import BrandIconSection from './components/BrandIconSection';
import ButtonsLinksSection from './components/ButtonsLinksSection';
import FormActions from './components/FormActions';
import { useCharacterCount } from './hooks/useCharacterCount';
import { useButtonManagement } from './hooks/useButtonManagement';
import { useImageUpload } from './hooks/useImageUpload';
import { useTagManagement } from './hooks/useTagManagement';
import isEmpty from 'lodash/isEmpty';
import get from 'lodash/get';
import * as templateActions from '../../Templates/actions';
import { makeSelectTemplates } from '../../Templates/selectors';

import {
  WEBPUSH_MEDIA_TYPES,
  BRAND_ICON_OPTIONS,
  IMAGE_UPLOAD_METHODS,
  UPLOAD_FIELD_TYPES,
  WEBPUSH_BUTTON_TYPES,
  ON_CLICK_BEHAVIOUR_OPTIONS,
  ACTION_TYPES,
  NOTIFICATION_TITLE_MAX_LENGTH,
  MESSAGE_MAX_LENGTH,
  EXTERNAL_URL,
  SITE_URL,
} from '../constants';
import * as actions from '../actions';
import {
  makeSelectWebPush,
  makeSelectCreateError,
  makeSelectCreateTemplateInProgress,
  makeSelectEditTemplateInProgress,
  makeSelectEditError,
} from '../selectors';
import webPushReducer from '../reducer';
import webPushSagas from '../sagas';
import { v2TemplateSaga } from '../../Templates/sagas';
import withCreatives from '../../../hoc/withCreatives';
import messages from './messages';
import { createWebPushPayload } from './utils/payloadBuilder';
import {
  validateTemplateName as validateTemplateNameUtil,
  validateTitle as validateTitleUtil,
  validateUrl as validateUrlUtil,
  validateMessageContent as validateMessageContentUtil,
} from './utils/validation';
import {
  makeSelectMetaEntities,
  setInjectedTags,
} from '../../Cap/selectors';
import './index.scss';
import { WEBPUSH } from '../../CreativesContainer/constants';
import { isAiContentBotDisabled } from '../../../utils/common';
import TestAndPreviewSlidebox from '../../../v2Components/TestAndPreviewSlidebox';
import creativesMessages from '../../CreativesContainer/messages';
import CapButton from '@capillarytech/cap-ui-library/CapButton';

// Memoized TagList wrapper components for better performance
const MemoizedTagList = memo(({
  moduleFilterEnabled,
  label,
  onContextChange,
  location,
  tags,
  injectedTags,
  selectedOfferDetails,
  eventContextTags,
  waitEventContextTags,
  forwardedTags,
  onTagSelect,
  restrictPersonalization = false,
  disabled = false,
  disableTooltipMsg,
}) => (
  <TagList
    moduleFilterEnabled={moduleFilterEnabled}
    label={label}
    onContextChange={onContextChange}
    location={location}
    tags={tags}
    injectedTags={injectedTags}
    selectedOfferDetails={selectedOfferDetails}
    eventContextTags={eventContextTags}
    waitEventContextTags={waitEventContextTags}
    forwardedTags={forwardedTags}
    onTagSelect={onTagSelect}
    restrictPersonalization={restrictPersonalization}
    disabled={disabled || restrictPersonalization}
    disableTooltipMsg={disableTooltipMsg}
  />
), (prevProps, nextProps) => {
  // Custom comparison function for better memoization
  return (
    prevProps.moduleFilterEnabled === nextProps.moduleFilterEnabled
    && prevProps.label === nextProps.label
    && prevProps.onContextChange === nextProps.onContextChange
    && prevProps.location === nextProps.location
    && prevProps.tags === nextProps.tags
    && prevProps.injectedTags === nextProps.injectedTags
    && prevProps.selectedOfferDetails === nextProps.selectedOfferDetails
    && prevProps.eventContextTags === nextProps.eventContextTags
    && prevProps.waitEventContextTags === nextProps.waitEventContextTags
    && prevProps.forwardedTags === nextProps.forwardedTags
    && prevProps.onTagSelect === nextProps.onTagSelect
    && prevProps.restrictPersonalization === nextProps.restrictPersonalization
    && prevProps.disabled === nextProps.disabled
    && prevProps.disableTooltipMsg === nextProps.disableTooltipMsg
  );
});

MemoizedTagList.displayName = 'MemoizedTagList';

const WebPushCreate = ({
  isFullMode,
  handleClose,
  intl,
  webPushActions,
  createTemplateInProgress,
  createTemplateError,
  editTemplateInProgress,
  editTemplateError,
  accountData,
  webPush,
  onCreateComplete,
  getFormData,
  isGetFormData,
  templateData,
  creativesMode,
  params,
  globalActions,
  location,
  metaEntities,
  injectedTags,
  getDefaultTags,
  supportedTags = [],
  forwardedTags,
  selectedOfferDetails = [],
  eventContextTags = [],
  waitEventContextTags = {},
  templateActions: templateActionsProps,
  Templates,
  restrictPersonalization = false,
}) => {
  const { formatMessage } = intl;
  const aiContentBotDisabled = isAiContentBotDisabled();

  // Form state - kept in main component for now
  const [templateName, setTemplateName] = useState('');
  const [notificationTitle, setNotificationTitle] = useState('');
  const [message, setMessage] = useState('');
  const [mediaType, setMediaType] = useState(WEBPUSH_MEDIA_TYPES.NONE);
  const [templateNameError, setTemplateNameError] = useState(false);
  const [titleError, setTitleError] = useState('');
  const [messageError, setMessageError] = useState('');
  const [fieldCompletion, setFieldCompletion] = useState({
    templateName: !isFullMode,
    notificationTitle: false,
    message: false,
  });
  const [brandIconOption, setBrandIconOption] = useState(BRAND_ICON_OPTIONS.DONT_SHOW);
  const [onClickBehaviour, setOnClickBehaviour] = useState(ON_CLICK_BEHAVIOUR_OPTIONS.SITE_URL);
  const [redirectUrl, setRedirectUrl] = useState('');
  const [redirectUrlError, setRedirectUrlError] = useState('');
  const [activeUploadField, setActiveUploadField] = useState(null);
  const [templateIdError, setTemplateIdError] = useState('');
  const [showTestAndPreviewSlidebox, setShowTestAndPreviewSlidebox] = useState(false);

  // Refs
  const titleCountRef = useRef(null);
  const messageCountRef = useRef(null);
  const saveInitiatedRef = useRef(false);
  const messageTextAreaRef = useRef(null);

  // Custom hooks
  const { updateCharacterCount } = useCharacterCount(formatMessage, messages);
  
  const buttonState = useButtonManagement([]);
  const { buttons, setButtons } = buttonState;
  
  const imageUpload = useImageUpload({
    webPush,
    webPushActions,
    index: 0,
    initialUploadMethod: IMAGE_UPLOAD_METHODS.UPLOAD_IMAGE,
  });
  const {
    imageSrc,
    imageUrl,
    isValidating: isImageValidating,
    isUploading: isImageUploading,
    setImageSrc,
    setImageUrl,
  } = imageUpload;
  
  const brandIconUpload = useImageUpload({
    webPush,
    webPushActions,
    index: 1,
    initialUploadMethod: IMAGE_UPLOAD_METHODS.UPLOAD_IMAGE,
  });
  const {
    imageSrc: brandIconSrc,
    imageUrl: brandIconUrl,
    isValidating: isBrandIconValidating,
    isUploading: isBrandIconUploading,
    setImageSrc: setBrandIconSrc,
    setImageUrl: setBrandIconUrl,
  } = brandIconUpload;
  
  // Memoize supportedTags to prevent unnecessary re-renders in useTagManagement
  const memoizedSupportedTags = useMemo(() => supportedTags, [supportedTags]);
  
  const tagState = useTagManagement({
    location,
    globalActions,
    metaEntities,
    getDefaultTags,
    supportedTags: memoizedSupportedTags,
    injectedTags,
    eventContextTags,
    waitEventContextTags,
  });
  const { tags, handleOnTagsContextChange, validationConfig } = tagState;
  const { weCrmAccounts } = Templates;

  // Edit mode detection: check creativesMode or presence of template ID
  const isEditMode = useMemo(
    () =>
      creativesMode === 'editTemplate'
      || creativesMode === 'edit'
      || !!(templateData?._id)
      || !!(params?.id),
    [creativesMode, templateData?._id, params?.id],
  );

  const accountId = useMemo(() => {
    const fallbackAccountId = get(templateData, 'definition.accountId');
    return (
      accountData?.accountId
      || accountData?.id
      || fallbackAccountId
      || get(accountData, 'sourceAccountIdentifier')
    );
  }, [
    accountData?.accountId,
    accountData?.id,
    accountData?.sourceAccountIdentifier,
    templateData,
  ]);

  const selectedWebPushAccount = useMemo(() => 
    weCrmAccounts?.find(account => account?.id === accountId), 
  [weCrmAccounts, accountId]);

  const websiteLink = useMemo(
    () => accountData?.configs?.websiteLink || selectedWebPushAccount?.configs?.websiteLink || '',
    [accountData?.configs?.websiteLink, selectedWebPushAccount?.configs?.websiteLink],
  );

  // Fetch account details when websiteLink is missing but accountId exists
  useEffect(() => {
    if (!websiteLink && accountId && templateActionsProps?.getWeCrmAccounts) {
      templateActionsProps.getWeCrmAccounts('WebPush');
    }
  }, [websiteLink, accountId, templateActionsProps?.getWeCrmAccounts]);

  const previewUrl = useMemo(
    () => (
      onClickBehaviour === ON_CLICK_BEHAVIOUR_OPTIONS.REDIRECT_TO_URL
        ? redirectUrl
        : websiteLink || redirectUrl
    ),
    [onClickBehaviour, redirectUrl, websiteLink],
  );

  const onClickBehaviourOptions = useMemo(
    () => ([
      { value: ON_CLICK_BEHAVIOUR_OPTIONS.SITE_URL, label: formatMessage(messages.openSite) },
      { value: ON_CLICK_BEHAVIOUR_OPTIONS.REDIRECT_TO_URL, label: formatMessage(messages.redirectToSpecificUrl) },
    ]),
    [formatMessage],
  );

  const validateTemplateName = useCallback((value) => validateTemplateNameUtil(value), []);

  const validateTitle = useCallback(
    (value) => validateTitleUtil(value, formatMessage, messages, restrictPersonalization, validationConfig, isFullMode),
    [formatMessage, restrictPersonalization, validationConfig, isFullMode],
  );

  const validateUrl = useCallback(
    (value) => validateUrlUtil(value, formatMessage, messages),
    [formatMessage],
  );

  const updateFieldCompletion = useCallback((field, hasValue) => {
    setFieldCompletion((prev) => {
      if (prev[field] === hasValue) {
        return prev;
      }
      return {
        ...prev,
        [field]: hasValue,
      };
    });
  }, []);



  const validateMessageContent = useCallback(
    (value) => validateMessageContentUtil(value, formatMessage, messages, validationConfig, isFullMode, restrictPersonalization),
    [formatMessage, validationConfig, isFullMode, restrictPersonalization],
  );

  useEffect(() => {
    if (!isEditMode) {
      return;
    }

    if (isEmpty(templateData)) {
      return;
    }

    const webpushContent = get(templateData, 'versions.base.content.webpush', {});

    const extractedTemplateName = templateData?.name || '';
    const extractedNotificationTitle = webpushContent?.title || '';
    const extractedMessage = webpushContent?.message || '';

    // Update state to populate form fields
    setTemplateName(extractedTemplateName);
    setNotificationTitle(extractedNotificationTitle);
    setMessage(extractedMessage);

    const nextMediaType = webpushContent?.mediaType || WEBPUSH_MEDIA_TYPES.NONE;
    setMediaType(nextMediaType);

    const existingImage = webpushContent?.image || '';
    if (existingImage) {
      setImageSrc(existingImage);
      setImageUrl('');
    } else {
      setImageSrc('');
      setImageUrl('');
    }

    const existingBrandIcon = webpushContent?.brandIcon || '';
    if (existingBrandIcon) {
      setBrandIconOption(BRAND_ICON_OPTIONS.UPLOAD_IMAGE);
      setBrandIconSrc(existingBrandIcon);
      setBrandIconUrl('');
    } else {
      setBrandIconOption(BRAND_ICON_OPTIONS.DONT_SHOW);
      setBrandIconSrc('');
      setBrandIconUrl('');
    }

    const webpushCtas = Array.isArray(webpushContent?.ctas) ? webpushContent.ctas : [];
    setButtons(
      webpushCtas.map((cta, index) => ({
        text: cta?.actionText || '',
        url: cta?.actionLink || '',
        type: index === 0 ? WEBPUSH_BUTTON_TYPES.PRIMARY : WEBPUSH_BUTTON_TYPES.SECONDARY,
      })),
    );

    const onClickAction = webpushContent?.onClickAction || {};
    if (onClickAction?.type === ACTION_TYPES.URL) {
      setOnClickBehaviour(ON_CLICK_BEHAVIOUR_OPTIONS.REDIRECT_TO_URL);
      setRedirectUrl(onClickAction?.url || '');
      setRedirectUrlError('');
    } else if (onClickAction?.type === ACTION_TYPES.SITE_URL) {
      setOnClickBehaviour(ON_CLICK_BEHAVIOUR_OPTIONS.SITE_URL);
      setRedirectUrl(websiteLink);
      setRedirectUrlError('');
    } else {
      setOnClickBehaviour(ON_CLICK_BEHAVIOUR_OPTIONS.SITE_URL);
      setRedirectUrl(websiteLink);
      setRedirectUrlError('');
    }

    updateFieldCompletion('notificationTitle', extractedNotificationTitle.trim().length > 0);
    updateFieldCompletion('message', extractedMessage.trim().length > 0);
    if (isFullMode) {
      updateFieldCompletion('templateName', extractedTemplateName.trim().length > 0);
      setTemplateNameError('');
    }
    setTitleError('');
    setMessageError('');

    updateCharacterCount(
      titleCountRef,
      extractedNotificationTitle.length,
      NOTIFICATION_TITLE_MAX_LENGTH,
    );
    updateCharacterCount(
      messageCountRef,
      extractedMessage.length,
      MESSAGE_MAX_LENGTH,
    );
  }, [
    isEditMode,
    templateData,
    isFullMode,
    updateFieldCompletion,
    updateCharacterCount,
  ]);

  const handleTemplateNameChange = useCallback((e) => {
    const { value } = e.target;
    setTemplateName(value);
    if (isFullMode) {
      const nextError = validateTemplateName(value);
      setTemplateNameError((prev) => (prev === nextError ? prev : nextError));
    }
    updateFieldCompletion('templateName', value.trim().length > 0);
  }, [isFullMode, updateFieldCompletion, validateTemplateName]);

  const handleNotificationTitleChange = useCallback((e) => {
    const { value } = e.target;
    setNotificationTitle(value);
    const nextError = validateTitle(value);
    setTitleError((prev) => (prev === nextError ? prev : nextError));
    updateFieldCompletion('notificationTitle', value.trim().length > 0);
    updateCharacterCount(titleCountRef, value.length, NOTIFICATION_TITLE_MAX_LENGTH);
  }, [updateCharacterCount, updateFieldCompletion, validateTitle]);

  // Handler to capture the textarea ref for CapEmojiPicker
  const handleMessageTextAreaRef = useCallback((node) => {
    if (!node) {
      messageTextAreaRef.current = null;
      return;
    }
    // Handles different TextArea implementations (antd's resizable, etc.)
    messageTextAreaRef.current = node?.resizableTextArea?.textArea || node?.textAreaRef || node;
  }, []);

  // Optimize message change handler - use functional updates where possible
  // Handles both event (from TextArea) and direct value (from CapEmojiPicker.Wrapper)
  const handleMessageChange = useCallback((eOrValue) => {
    const value = typeof eOrValue === 'string' ? eOrValue : eOrValue.target.value;
    // Cap length to maximum (maxLength not passed to TextArea to avoid embedded character count)
    const cappedValue = value.length > MESSAGE_MAX_LENGTH
      ? value.slice(0, MESSAGE_MAX_LENGTH)
      : value;
    if (typeof eOrValue !== 'string' && eOrValue.target && cappedValue !== value) {
      eOrValue.target.value = cappedValue;
    }
    setMessage(cappedValue);
    const nextError = validateMessageContent(cappedValue);
    setMessageError((prev) => (prev === nextError ? prev : nextError));
    updateFieldCompletion('message', cappedValue.trim().length > 0);
    updateCharacterCount(messageCountRef, cappedValue.length, MESSAGE_MAX_LENGTH);
  }, [updateCharacterCount, updateFieldCompletion, validateMessageContent]);

  const handleMediaTypeChange = useCallback((value) => {
    setMediaType(value);
    if (value === WEBPUSH_MEDIA_TYPES.NONE) {
      setImageSrc('');
      setImageUrl('');
    }
  }, [setImageSrc, setImageUrl]);

  // Brand icon option change handler (kept in main component)
  const handleBrandIconChange = useCallback((e) => {
    const option = e.target.value;
    setBrandIconOption(option);
    setBrandIconSrc('');
    setBrandIconUrl('');
  }, [setBrandIconSrc, setBrandIconUrl]);



  const handleOnClickBehaviourChange = useCallback((e) => {
    const value = e.target.value;
    setOnClickBehaviour(value);
    if (value !== ON_CLICK_BEHAVIOUR_OPTIONS.REDIRECT_TO_URL) {
      setRedirectUrl('');
      setRedirectUrlError('');
    }
  }, []);

  const handleRedirectUrlChange = useCallback((e) => {
    const { value } = e.target;
    setRedirectUrl(value);
    const nextError = validateUrl(value);
    setRedirectUrlError((prev) => (prev === nextError ? prev : nextError));
  }, [validateUrl]);

  // Optimized tag insertion handlers - split into separate callbacks
  const handleTagSelectTitle = useCallback((tagValue) => {
    const tagText = `{{${tagValue}}}`;
    setNotificationTitle((prevTitle) => {
      const nextTitle = `${prevTitle}${tagText}`.slice(0, NOTIFICATION_TITLE_MAX_LENGTH);
      // Use functional updates to avoid dependency on notificationTitle
      const nextError = validateTitle(nextTitle);
      setTitleError((prev) => (prev === nextError ? prev : nextError));
      updateFieldCompletion('notificationTitle', nextTitle.trim().length > 0);
      updateCharacterCount(titleCountRef, nextTitle.length, NOTIFICATION_TITLE_MAX_LENGTH);
      return nextTitle;
    });
  }, [updateCharacterCount, updateFieldCompletion, validateTitle]);

  const handleTagSelectMessage = useCallback((tagValue) => {
    const tagText = `{{${tagValue}}}`;
    setMessage((prevMessage) => {
      const nextMessage = `${prevMessage}${tagText}`.slice(0, MESSAGE_MAX_LENGTH);
      // Use functional updates to avoid dependency on message
      const nextError = validateMessageContent(nextMessage);
      setMessageError((prev) => (prev === nextError ? prev : nextError));
      updateFieldCompletion('message', nextMessage.trim().length > 0);
      updateCharacterCount(messageCountRef, nextMessage.length, MESSAGE_MAX_LENGTH);
      return nextMessage;
    });
  }, [updateCharacterCount, updateFieldCompletion, validateMessageContent]);


  useEffect(() => {
    updateCharacterCount(
      titleCountRef,
      notificationTitle.length,
      NOTIFICATION_TITLE_MAX_LENGTH,
    );
    updateCharacterCount(
      messageCountRef,
      message.length,
      MESSAGE_MAX_LENGTH,
    );
  }, [updateCharacterCount, notificationTitle, message]);

  useEffect(() => {
    setFieldCompletion((prev) => {
      const nextTemplateNameComplete = !isFullMode
        || templateName.trim().length > 0;
      if (prev.templateName === nextTemplateNameComplete) {
        return prev;
      }
      return {
        ...prev,
        templateName: nextTemplateNameComplete,
      };
    });
  }, [isFullMode, templateName]);

  // Pure validator that returns boolean without setting error state
  const validateFormSilent = () => {
    const templateNameInvalid = isFullMode && validateTemplateName(templateName);
    const titleValidation = validateTitle(notificationTitle, restrictPersonalization);
    const messageValidation = validateMessageContent(message);

    return !(templateNameInvalid || titleValidation || messageValidation);
  };

  const getTemplateContent = useCallback(() => {
    let cta = null;
    if (onClickBehaviour === ON_CLICK_BEHAVIOUR_OPTIONS.REDIRECT_TO_URL && redirectUrl) {
      cta = { type: EXTERNAL_URL, actionLink: redirectUrl?.trim() };
    } else if (onClickBehaviour === ON_CLICK_BEHAVIOUR_OPTIONS.SITE_URL && websiteLink) {
      cta = { type: SITE_URL, actionLink: websiteLink };
    }

    const hasImage = mediaType === WEBPUSH_MEDIA_TYPES.IMAGE && imageSrc;
    const hasCtas = buttons?.length > 0;
    let expandableDetails = null;
    if (hasImage || hasCtas) {
      expandableDetails = {
        media: hasImage ? [{ url: imageSrc, type: WEBPUSH_MEDIA_TYPES.IMAGE }] : [],
        ctas: hasCtas ? buttons.map((btn) => ({
          type: EXTERNAL_URL,
          action: '',
          title: btn.text || '',
          actionLink: btn.url || '',
        })) : [],
      };
    }

    const iconImageUrl = brandIconOption !== BRAND_ICON_OPTIONS.DONT_SHOW && brandIconSrc ? brandIconSrc : undefined;

    return {
      channel: WEBPUSH,
      accountId,
      content: {
        title: notificationTitle || '',
        message: message || '',
        ...(iconImageUrl ? { iconImageUrl } : {}),
        ...(cta ? { cta } : {}),
        ...(expandableDetails ? { expandableDetails } : {}),
      },
      messageSubject: templateName || notificationTitle || '',
      offers: [],
    };
  }, [
    notificationTitle,
    message,
    accountId,
    mediaType,
    imageSrc,
    brandIconOption,
    brandIconSrc,
    buttons,
    onClickBehaviour,
    redirectUrl,
    websiteLink,
    templateName,
  ]);

  const handleTestAndPreview = useCallback(() => {
    setShowTestAndPreviewSlidebox(true);
  }, []);

  const handleCloseTestAndPreview = useCallback(() => {
    setShowTestAndPreviewSlidebox(false);
  }, []);

  const isFormValid = () => {
    const templateNameInvalid = isFullMode && validateTemplateName(templateName);
    const titleValidation = validateTitle(notificationTitle);
    const messageValidation = validateMessageContent(message);

    setTemplateNameError((prev) => (prev === templateNameInvalid ? prev : templateNameInvalid));
    setTitleError((prev) => (prev === titleValidation ? prev : titleValidation));
    setMessageError((prev) => (prev === messageValidation ? prev : messageValidation));

    return !(templateNameInvalid || titleValidation || messageValidation);
  };

  const handleSave = () => {
    if (!isFormValid()) {
      return;
    }

    
    // Set flag to indicate save/edit operation has been initiated
    saveInitiatedRef.current = true;

    const payload = createWebPushPayload({
      templateName,
      notificationTitle,
      message,
      mediaType,
      accountId,
      isFullMode,
      imageSrc,
      imageUrl,
      imageUploadMethod: imageUpload.uploadMethod,
      brandIconOption,
      brandIconSrc,
      brandIconUrl,
      buttons,
      onClickBehaviour,
      redirectUrl,
      websiteLink,
    });

    // In library mode (not full mode), use getFormData to communicate with parent
    if (!isFullMode && getFormData) {
      const formDataForLibrary = {
        validity: true,
        value: payload,
        type: WEBPUSH,
      };
      getFormData(formDataForLibrary);
      if (handleClose) {
        handleClose();
      }
      return;
    }

    // Full mode: proceed with API calls
    if (isEditMode) {
      // Get template ID from params or templateData
      const templateId = params?.id || templateData?._id;
      if (templateId) {
        // Clear any previous template ID error
        setTemplateIdError('');
        webPushActions.editTemplate(
          {
            ...payload,
            _id: templateId,
          },
          (resp, errorMessage) => {
            if (!errorMessage) {
              // Clear flag before calling callbacks to prevent double-invocation
              // from the editResponse useEffect
              saveInitiatedRef.current = false;
              if (onCreateComplete) {
                onCreateComplete(true);
              }
              if (handleClose) {
                handleClose();
              }
            }
          },
        );
      } else {
        // Template ID is missing in edit mode - surface error
        const errorMsg = formatMessage(messages.templateIdMissingError);
        setTemplateIdError(errorMsg);
        // Reset save flag since we're not proceeding with the save
        saveInitiatedRef.current = false;
        // Notify parent component of failure
        if (onCreateComplete) {
          onCreateComplete(false);
        }
        return;
      }
    } else {
      webPushActions.createTemplate(payload);
    }
  };

  // Clear response state on mount to prevent stale responses from triggering callbacks
  useEffect(() => {
    webPushActions.clearCreateResponse();
    webPushActions.clearEditResponse();
    saveInitiatedRef.current = false;
  }, []);

  // Handle create response
  useEffect(() => {
    const response = webPush?.response || {};
    if (
      response &&
      Object.keys(response).length > 0 &&
      !isEditMode &&
      saveInitiatedRef.current
    ) {
      // Reset flag after handling response
      saveInitiatedRef.current = false;
      if (onCreateComplete) {
        onCreateComplete(true);
      }
      if (handleClose) {
        handleClose();
      }
    }
  }, [webPush?.response, onCreateComplete, handleClose, isEditMode]);

  // Handle edit response
  useEffect(() => {
    const editResponse = webPush?.editResponse || {};
    if (
      editResponse &&
      Object.keys(editResponse).length > 0 &&
      isEditMode &&
      saveInitiatedRef.current
    ) {
      // Reset flag after handling response
      saveInitiatedRef.current = false;
      if (onCreateComplete) {
        onCreateComplete(true);
      }
      if (handleClose) {
        handleClose();
      }
    }
  }, [webPush?.editResponse, onCreateComplete, handleClose, isEditMode]);

  // Handle getFormData request from parent (library mode)
  useEffect(() => {
    if (isGetFormData && getFormData && validateFormSilent()) {
      const payload = createWebPushPayload({
        templateName,
        notificationTitle,
        message,
        mediaType,
        accountId,
        isFullMode,
        imageSrc,
        imageUrl,
        imageUploadMethod: imageUpload?.uploadMethod,
        brandIconOption,
        brandIconSrc,
        brandIconUrl,
        buttons,
        onClickBehaviour,
        redirectUrl,
        websiteLink,
      });
      const formDataForLibrary = {
        validity: true,
        value: payload,
        type: WEBPUSH,
      };
      getFormData(formDataForLibrary);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isGetFormData, getFormData]);

  const isUploadingAsset = useMemo(
    () => webPush?.assetUploading || false,
    [webPush?.assetUploading],
  );

  // Track which field is currently controlling uploads/validation
  useEffect(() => {
    if (isImageValidating || isImageUploading) {
      setActiveUploadField(UPLOAD_FIELD_TYPES.IMAGE);
      return;
    }
    if (isBrandIconValidating || isBrandIconUploading) {
      setActiveUploadField(UPLOAD_FIELD_TYPES.BRAND_ICON);
      return;
    }
    if (!isUploadingAsset) {
      setActiveUploadField(null);
    }
  }, [
    isImageValidating,
    isImageUploading,
    isBrandIconValidating,
    isBrandIconUploading,
    isUploadingAsset,
  ]);

  const isImageFieldActive = useMemo(
    () => (
      isImageValidating
      || isImageUploading
      || (isUploadingAsset && activeUploadField === UPLOAD_FIELD_TYPES.IMAGE)
    ),
    [
      isImageValidating,
      isImageUploading,
      isUploadingAsset,
      activeUploadField,
    ],
  );

  const isBrandIconFieldActive = useMemo(
    () => (
      isBrandIconValidating
      || isBrandIconUploading
      || (isUploadingAsset && activeUploadField === UPLOAD_FIELD_TYPES.BRAND_ICON)
    ),
    [
      isBrandIconValidating,
      isBrandIconUploading,
      isUploadingAsset,
      activeUploadField,
    ],
  );

  const isAnyUploadActive = useMemo(
    () => isImageFieldActive || isBrandIconFieldActive,
    [isImageFieldActive, isBrandIconFieldActive],
  );

  const isMediaSectionLocked = useMemo(
    () => isBrandIconFieldActive,
    [isBrandIconFieldActive],
  );

  const isBrandIconSectionLocked = useMemo(
    () => isImageFieldActive,
    [isImageFieldActive],
  );

  // Optimize tagListCommonProps - split into stable and dynamic parts
  const moduleFilterEnabled = useMemo(
    () => location?.query?.type !== 'embedded',
    [location?.query?.type],
  );

  const tagListLabel = useMemo(
    () => formatMessage(messages.addLabels),
    [formatMessage],
  );

  // Stable props that don't change often
  const tagListStableProps = useMemo(
    () => ({
      moduleFilterEnabled,
      label: tagListLabel,
      onContextChange: handleOnTagsContextChange,
      location,
    }),
    [moduleFilterEnabled, tagListLabel, handleOnTagsContextChange, location],
  );

  // Dynamic props that change with tags
  const tagListDynamicProps = useMemo(
    () => ({
      tags,
      injectedTags,
      selectedOfferDetails,
      eventContextTags,
      waitEventContextTags,
      forwardedTags,
      restrictPersonalization,
      disabled: restrictPersonalization,
      disableTooltipMsg: restrictPersonalization ? formatMessage(messages.personalizationNotSupportedAnonymous) : undefined,
    }),
    [tags, injectedTags, selectedOfferDetails, eventContextTags, waitEventContextTags, forwardedTags, restrictPersonalization, formatMessage],
  );

  // Memoized TagList components with optimized props
  const titleTagList = useMemo(
    () => (
      <MemoizedTagList
        {...tagListStableProps}
        {...tagListDynamicProps}
        onTagSelect={handleTagSelectTitle}
      />
    ),
    [tagListStableProps, tagListDynamicProps, handleTagSelectTitle],
  );

  const messageTagList = useMemo(
    () => (
      <MemoizedTagList
        {...tagListStableProps}
        {...tagListDynamicProps}
        onTagSelect={handleTagSelectMessage}
      />
    ),
    [tagListStableProps, tagListDynamicProps, handleTagSelectMessage],
  );

  const isSaveDisabled = useMemo(
    () => (
      createTemplateInProgress
      || editTemplateInProgress
      || isUploadingAsset
      || isImageValidating
      || isImageUploading
      || isBrandIconValidating
      || isBrandIconUploading
      || buttonState.isAddingButton
      || (isFullMode && !fieldCompletion.templateName)
      || !fieldCompletion.notificationTitle
      || !fieldCompletion.message
      || !accountId
      || (
        mediaType === WEBPUSH_MEDIA_TYPES.IMAGE
        && (
          (imageUpload.uploadMethod === IMAGE_UPLOAD_METHODS.UPLOAD_IMAGE && !imageSrc)
          || (imageUpload.uploadMethod === IMAGE_UPLOAD_METHODS.ADD_IMAGE_URL && !imageUrl)
        )
      )
      || (
        brandIconOption !== BRAND_ICON_OPTIONS.DONT_SHOW
        && (
          (brandIconOption === BRAND_ICON_OPTIONS.UPLOAD_IMAGE && !brandIconSrc)
          || (brandIconOption === BRAND_ICON_OPTIONS.ADD_IMAGE_URL && !brandIconUrl)
        )
      )
      || (onClickBehaviour === ON_CLICK_BEHAVIOUR_OPTIONS.REDIRECT_TO_URL && (!redirectUrl.trim() || redirectUrlError))
      || !!titleError || !!messageError
    ),
    [
      createTemplateInProgress,
      editTemplateInProgress,
      isUploadingAsset,
      isImageValidating,
      isImageUploading,
      isBrandIconValidating,
      isBrandIconUploading,
      buttonState.isAddingButton,
      isFullMode,
      fieldCompletion.templateName,
      fieldCompletion.notificationTitle,
      fieldCompletion.message,
      accountId,
      mediaType,
      imageUpload.uploadMethod,
      imageSrc,
      imageUrl,
      brandIconOption,
      brandIconSrc,
      brandIconUrl,
      onClickBehaviour,
      redirectUrl,
      redirectUrlError,
      titleError,
      messageError,
    ],
  );

  const errorText = useMemo(() => {
    // Check for templateIdError first (validation error before API call)
    if (templateIdError) {
      return templateIdError;
    }
    const error = isEditMode ? editTemplateError : createTemplateError;
    if (!error) {
      return '';
    }
    if (typeof error === 'string') {
      return error;
    }
    if (error?.message) {
      return error.message;
    }
    if (typeof error?.toJS === 'function') {
      const errorObject = error.toJS();
      if (typeof errorObject === 'string') {
        return errorObject;
      }
      if (errorObject?.message) {
        return errorObject.message;
      }
      try {
        return JSON.stringify(errorObject);
      } catch (err) {
        return '';
      }
    }
    try {
      return JSON.stringify(error);
    } catch (err) {
      return '';
    }
  }, [templateIdError, createTemplateError, editTemplateError, isEditMode]);

  const accountErrorText = useMemo(
    () => (!accountId ? formatMessage(messages.accountRequired) : ''),
    [accountId, formatMessage],
  );
  
  return (
    <CapRow className="webpush-container">
      <CapColumn className="content-section" span={14}>
        <TemplateNameSection
          isFullMode={isFullMode}
          value={templateName}
          error={templateNameError}
          onChange={handleTemplateNameChange}
          formatMessage={formatMessage}
          messages={messages}
        />
        <NotificationTitleSection
          value={notificationTitle}
          error={titleError}
          onChange={handleNotificationTitleChange}
          formatMessage={formatMessage}
          messages={messages}
          tagList={titleTagList}
          titleCountRef={titleCountRef}
        />
        <MessageSection
          value={message}
          error={messageError}
          onChange={handleMessageChange}
          formatMessage={formatMessage}
          messages={messages}
          tagList={messageTagList}
          messageCountRef={messageCountRef}
          messageTextAreaRef={messageTextAreaRef}
          handleMessageTextAreaRef={handleMessageTextAreaRef}
          isAiContentBotDisabled={aiContentBotDisabled}
        />
        <MediaSection
          mediaType={mediaType}
          onMediaTypeChange={handleMediaTypeChange}
          imageUpload={imageUpload}
          isLocked={isMediaSectionLocked}
          isAnyUploadActive={isAnyUploadActive}
          formatMessage={formatMessage}
          messages={messages}
          webPush={webPush}
          isFullMode={isFullMode}
        />
        <BrandIconSection
          brandIconOption={brandIconOption}
          onBrandIconChange={handleBrandIconChange}
          brandIconUpload={brandIconUpload}
          isLocked={isBrandIconSectionLocked}
          isAnyUploadActive={isAnyUploadActive}
          formatMessage={formatMessage}
          messages={messages}
          webPush={webPush}
          isFullMode={isFullMode}
        />
        <ButtonsLinksSection
          onClickBehaviour={onClickBehaviour}
          onClickBehaviourOptions={onClickBehaviourOptions}
          onClickBehaviourChange={handleOnClickBehaviourChange}
          redirectUrl={redirectUrl}
          redirectUrlError={redirectUrlError}
          onRedirectUrlChange={handleRedirectUrlChange}
          buttonState={buttonState}
          formatMessage={formatMessage}
          messages={messages}
        />
        <CapRow className="webpush-test-preview-action">
          <FormActions
            onSave={handleSave}
            isSaveDisabled={isSaveDisabled}
            errorText={errorText}
            accountErrorText={accountErrorText}
            formatMessage={formatMessage}
            messages={messages}
          />
          <CapButton
            type="secondary"
            onClick={handleTestAndPreview}
            className="webpush-test-preview-btn"
          >
            {formatMessage(creativesMessages.testAndPreview)}
          </CapButton>
        </CapRow>
      </CapColumn>
      <CapColumn className="preview-section" span={10}>
        <WebPushPreview
          notificationTitle={notificationTitle}
          notificationBody={message}
          url={previewUrl}
          imageSrc={imageSrc}
          brandIconSrc={brandIconSrc}
          buttons={buttons}
        />
      </CapColumn>
      <TestAndPreviewSlidebox
        show={showTestAndPreviewSlidebox}
        onClose={handleCloseTestAndPreview}
        content={getTemplateContent()}
        currentChannel={WEBPUSH}
        accountId={accountId || null}
      />
    </CapRow>
  );
};

WebPushCreate.propTypes = {
  isFullMode: PropTypes.bool,
  handleClose: PropTypes.func,
  intl: intlShape.isRequired,
  webPushActions: PropTypes.object,
  createTemplateInProgress: PropTypes.bool,
  createTemplateError: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
  editTemplateInProgress: PropTypes.bool,
  editTemplateError: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
  accountData: PropTypes.object,
  webPush: PropTypes.object,
  onCreateComplete: PropTypes.func,
  getFormData: PropTypes.func,
  isGetFormData: PropTypes.bool,
  templateData: PropTypes.object,
  creativesMode: PropTypes.string,
  params: PropTypes.object,
  globalActions: PropTypes.object,
  location: PropTypes.object,
  metaEntities: PropTypes.object,
  injectedTags: PropTypes.object,
  getDefaultTags: PropTypes.string,
  supportedTags: PropTypes.array,
  forwardedTags: PropTypes.object,
  selectedOfferDetails: PropTypes.array,
  eventContextTags: PropTypes.array,
  waitEventContextTags: PropTypes.object,
  templateActions: PropTypes.object,
  restrictPersonalization: PropTypes.bool,
};

WebPushCreate.defaultProps = {
  isFullMode: true,
  handleClose: () => { },
  webPushActions: {},
  createTemplateInProgress: false,
  editTemplateInProgress: false,
  createTemplateError: '',
  accountData: {},
  webPush: {},
  onCreateComplete: () => { },
  getFormData: null,
  isGetFormData: false,
  templateData: null,
  creativesMode: 'createTemplate',
  params: null,
  globalActions: {},
  location: null,
  metaEntities: null,
  injectedTags: {},
  getDefaultTags: '',
  supportedTags: [],
  forwardedTags: {},
  selectedOfferDetails: [],
  eventContextTags: [],
  waitEventContextTags: {},
  templateActions: {},
  Templates: {},
  restrictPersonalization: false,
};

const mapStateToProps = createStructuredSelector({
  webPush: makeSelectWebPush(),
  createTemplateInProgress: makeSelectCreateTemplateInProgress(),
  createTemplateError: makeSelectCreateError(),
  editTemplateInProgress: makeSelectEditTemplateInProgress(),
  editTemplateError: makeSelectEditError(),
  metaEntities: makeSelectMetaEntities(),
  injectedTags: setInjectedTags(),
  Templates: makeSelectTemplates(),
  accountData: createSelector(
    (state) => state.get('templates'),
    (templatesState) => {
      if (!templatesState) {
        return {};
      }
      const templates = templatesState.toJS();
      return templates?.selectedWebPushAccount || {};
    },
  ),
});

const mapDispatchToProps = (dispatch) => ({
  webPushActions: bindActionCreators(actions, dispatch),
  templateActions: bindActionCreators(templateActions, dispatch),
});

const withWebPushSaga = injectSaga({
  key: 'webPush',
  saga: webPushSagas,
  mode: DAEMON,
});

const withTemplateSaga = injectSaga({
  key: 'templates',
  saga: v2TemplateSaga,
  mode: DAEMON,
});

const withReducer = injectReducer({
  key: 'webPush',
  reducer: webPushReducer,
});

export default withCreatives({
  WrappedComponent: injectIntl(WebPushCreate),
  mapStateToProps,
  mapDispatchToProps,
  userAuth: true,
  sagas: [withWebPushSaga, withTemplateSaga],
  reducers: [withReducer],
});

