// Utility to create the Mobile Push payload for rich media, with validation
import { DEEP_LINK } from "../v2Components/CapInAppCTA/constants";
import { EXTERNAL_URL } from "../v2Components/CapMpushCTA/constants";
import {
  IMAGE, VIDEO, GIF, CAROUSEL, BIG_TEXT, BIG_PICTURE,
  MANUAL_CAROUSEL,
  AUTO_CAROUSEL,
  FILMSTRIP_CAROUSEL,
  ANDROID,
  IOS,
  TEXT,
} from "../v2Containers/MobilePushNew/constants";
import messages from '../v2Containers/MobilePushNew/messages';

/**
 * Constructs the payload for Mobile Push, supporting both legacy and rich media as per backend contract.
 * - Trims and validates templateName
 * - Handles legacy and rich media (VIDEO, GIF, CAROUSEL)
 * - Supports platform-specific content (Android/iOS)
 * - Handles CTA and custom fields
 * @param {Object} params - The parameters for creating the payload
 * @param {string} params.templateName - The name of the template
 * @param {Object} params.androidContent - Android-specific content
 * @param {Object} params.iosContent - iOS-specific content
 * @param {Object} params.imageSrc - Image source URLs
 * @param {Object} params.mpushVideoSrcAndPreview - Video source and preview URLs
 * @param {Object} params.accountData - Account data for the payload
 * @param {boolean} params.sameContent - Whether content is shared between platforms
 * @param {Object} params.options - Additional options
 * @param {Object} params.intl - Internationalization object for messages
 */
const createMobilePushPayload = ({
  templateName,
  androidContent,
  iosContent,
  imageSrc = {},
  mpushVideoSrcAndPreview = {},
  accountData,
  sameContent = false,
  options = {},
  intl,
}) => {
  // Platform support checks must be at the top
  const isAndroidSupported = accountData?.configs?.android === '1';
  const isIosSupported = accountData?.configs?.ios === '1';

  const {
    accountId: accountIdFromAccountData, id, licenseCode: licenseCodeFromAccountData, sourceAccountIdentifier, sourceType: sourceTypeFromAccountData, sourceTypeName,
  } = accountData || {};
  // Validate account data
  const accountId = accountIdFromAccountData || id;
  const licenseCode = licenseCodeFromAccountData || sourceAccountIdentifier;
  const sourceType = sourceTypeFromAccountData || sourceTypeName;

  if (!accountId || !licenseCode || !sourceType) {
    throw new Error(intl.formatMessage(messages.accountDataRequiredError));
  }

  // Validate template name
  const trimmedTemplateName = templateName?.trim();
  if (!trimmedTemplateName) {
    throw new Error(intl.formatMessage(messages.templateNameEmptyError));
  }

  // Validate content
  if (isAndroidSupported && (!androidContent?.title || !androidContent?.message)) {
    throw new Error(intl.formatMessage(messages.contentValidationError, { platform: 'Android' }));
  }
  if (isIosSupported && (!iosContent?.title || !iosContent?.message)) {
    throw new Error(intl.formatMessage(messages.contentValidationError, { platform: 'iOS' }));
  }

  // Ensure imageSrc has the required properties
  const safeImageSrc = {
    androidImageSrc: imageSrc?.androidImageSrc || '',
    iosImageSrc: imageSrc?.iosImageSrc || '',
  };

  // Ensure mpushVideoSrcAndPreview has the required properties
  const safeMpushVideoSrcAndPreview = {
    mpushVideoSrc: mpushVideoSrcAndPreview?.mpushVideoSrc || '',
    mpushVideoPreviewImg: mpushVideoSrcAndPreview?.mpushVideoPreviewImg || '',
    duration: mpushVideoSrcAndPreview?.duration || 0,
  };

  // Build the payload
  const payload = {
    name: trimmedTemplateName,
    definition: {
      accountId,
      licenseCode,
      sourceType,
      sameContent,
      mode: options?.mode,
    },
    versions: {
      base: {},
    },
  };

  // Build Android content
  if (isAndroidSupported) {
    payload.versions.base.ANDROID = buildPlatformContent(
      androidContent,
      safeImageSrc.androidImageSrc,
      safeMpushVideoSrcAndPreview,
      ANDROID,
    );
  }

  // Build iOS content
  if (isIosSupported) {
    payload.versions.base.IOS = buildPlatformContent(
      iosContent,
      safeImageSrc.iosImageSrc,
      safeMpushVideoSrcAndPreview,
      IOS,
    );
  }

  return payload;
};

/**
 * Builds platform-specific content for the payload
 * @param {Object} content - Platform content (Android/iOS)
 * @param {string} imageSrc - Image source URL
 * @param {Object} mpushVideoSrcAndPreview - Video source and preview URLs
 * @param {string} platform - Platform (ANDROID/IOS)
 * @returns {Object} Platform-specific content
 */
function buildPlatformContent(content, imageSrc, mpushVideoSrcAndPreview, platform) {
  const {
    title = '',
    message = '',
    expandableDetails = {},
    actionOnClick,
    linkType,
    deepLinkValue,
    externalLinkValue,
    deepLinkKeysValue = [],
  } = content || {};

  const platformContent = {
    title,
    message,
    expandableDetails: { ...expandableDetails },
    custom: buildCustomFields(content),
  };

  // Handle CTA
  if (actionOnClick) {
    let finalDeepLinkValue = deepLinkValue;

    if (linkType === DEEP_LINK && deepLinkKeysValue?.length > 0) {
      // Check if the URL already contains the keys
      const urlHasKeys = deepLinkKeysValue?.some((key) => deepLinkValue?.includes(`${key}=${key}`));

      // Only append keys if they're not already in the URL
      if (!urlHasKeys) {
        finalDeepLinkValue = appendDeepLinkKeysToUrl(deepLinkValue, deepLinkKeysValue);
      }
    }

    platformContent.cta = {
      type: linkType === DEEP_LINK ? DEEP_LINK : EXTERNAL_URL,
      actionLink: linkType === DEEP_LINK ? finalDeepLinkValue : externalLinkValue,
    };
  }

  // Handle media types
  const style = content?.mediaType || expandableDetails?.style;

  // Determine the type field based on media type
  let templateType = TEXT; // Default type for NONE or BIG_TEXT

  // Handle BIG_PICTURE media type
  if (style === BIG_PICTURE || style === IMAGE) {
    platformContent.expandableDetails.style = BIG_PICTURE;
    platformContent.expandableDetails.message = message;
    platformContent.expandableDetails.image = imageSrc;
    templateType = IMAGE;
  } else if (style === VIDEO) { // Handle VIDEO media type
    platformContent.expandableDetails.style = VIDEO;
    platformContent.expandableDetails.message = message;
    platformContent.expandableDetails.media = [{
      url: mpushVideoSrcAndPreview.mpushVideoSrc || (content?.mediaList?.[0]?.url || ''),
      text: content?.mediaList?.[0]?.text || '',
      type: VIDEO,
    }];
    templateType = VIDEO;
  } else if (style === GIF) { // Handle GIF media type
    platformContent.expandableDetails.style = GIF;
    platformContent.expandableDetails.message = message;
    if (content?.mediaList?.[0]) {
      // If mediaList exists, use it and preserve the original type
      const { url = '', text = '', type = GIF } = content.mediaList[0];
      platformContent.expandableDetails.media = [{
        url,
        text,
        type: type.toLowerCase(),
      }];
    } else {
      // If no mediaList but mpushVideoSrc exists
      platformContent.expandableDetails.style = GIF;
      platformContent.expandableDetails.message = message;
      platformContent.expandableDetails.media = [{
        url: mpushVideoSrcAndPreview.mpushVideoSrc,
        text: '',
        type: GIF, // Backend expects GIF type for GIFs
      }];
    }
    templateType = GIF;
  } else if ([CAROUSEL, MANUAL_CAROUSEL, AUTO_CAROUSEL, FILMSTRIP_CAROUSEL].includes(style)) { // Handle CAROUSEL media types
    platformContent.expandableDetails.style = MANUAL_CAROUSEL;
    platformContent.expandableDetails.message = message;
    templateType = CAROUSEL;

    // Handle carouselData
    if (content?.carouselData?.length > 0) {
      platformContent.expandableDetails.carouselData = content.carouselData.map((card) => {
        const {
          mediaType,
          imageUrl,
          videoSrc,
          buttons,
        } = card || {};

        return {
          mediaType: mediaType || IMAGE.toLowerCase(),
          imageUrl: imageUrl || '',
          videoSrc: videoSrc || '',
          buttons: buttons ? buttons.map((button) => {
            const { linkType: buttonLinkType, deepLinkKeys, deepLinkValue: buttonDeepLinkValue } = button || {};
            if (buttonLinkType === DEEP_LINK && deepLinkKeys && buttonDeepLinkValue) {
              const deepLinkKeysArray = Array.isArray(deepLinkKeys) ? deepLinkKeys : [deepLinkKeys];
              const updatedDeepLinkValue = appendDeepLinkKeysToUrl(buttonDeepLinkValue, deepLinkKeysArray);

              return {
                ...button,
                deepLinkValue: updatedDeepLinkValue,
              };
            }
            return button;
          }) : [],
        };
      });
    }

    // Handle mediaList
    if (Array.isArray(content?.mediaList) && content?.mediaList?.length > 0) {
      platformContent.expandableDetails.media = content?.mediaList?.map((media) => {
        const {
          url,
          text,
          type,
        } = media || {};

        return {
          url,
          text: text || '',
          type,
        };
      });
    }
  } else { // Handle BIG_TEXT media type (default)
    platformContent.expandableDetails.style = BIG_TEXT;
    platformContent.expandableDetails.message = message;
    templateType = TEXT;
  }

  // Set the type and deviceType fields
  platformContent.type = templateType;
  platformContent.deviceType = platform;

  // Handle GIF media type

  // iOS-specific handling
  if (platform === IOS) {
    // iOS always needs a ctas array in expandableDetails
    platformContent.expandableDetails.ctas = platformContent.expandableDetails.ctas || [];
  }

  return platformContent;
}

/**
 * Builds custom fields array from content
 * @param {Object} content - Platform content (Android/iOS)
 * @returns {Array} Array of custom fields
 */
function buildCustomFields(content) {
  let customFields = [];
  const { custom = {} } = content || {};
  // If content.custom is already an array, use it as base
  if (Array.isArray(custom)) {
    customFields = [...custom];
  } else if (custom && typeof custom === 'object') {
    // If it's an object, map to array, excluding deepLinkKeys
    customFields = Object.entries(custom)
      .filter(([key]) => key !== 'deepLinkKeysValue' && key !== 'deepLinkValue' && key !== 'linkType')
      .map(([key, value]) => ({ key, value }));
  }
  return customFields;
}

/**
 * Appends deep link keys to URL
 * @param {string} url - Base URL
 * @param {Array} keys - Deep link keys
 * @returns {string} URL with appended keys
 */
export function appendDeepLinkKeysToUrl(url, keys) {
  if (!url || !keys || !Array.isArray(keys) || keys?.length === 0) return url;

  const separator = url.includes('?') ? '&' : '?';
  const validKeys = keys.filter((key) => typeof key === 'string' && key?.length > 0);
  if (validKeys?.length === 0) return url;

  const keyParams = validKeys.map((key) => `${key}=${key}`).join('&');

  return `${url}${separator}${keyParams}`;
}

export default createMobilePushPayload;
