/**
 * Returns responsive padding styles (top, right, bottom, left) based on the given device.
 * Falls back to desktop values if the current device values are not defined.
 *
 * @param {Object} responsiveAttr - Object containing padding values per device.
 * @param {string} device - The current device ('desktop', 'tablet', or 'mobile').
 * @returns {Object} CSS padding style object.
 */
export const getResponsivePaddingStyle = ( responsiveAttr, device = 'desktop' ) => {

  // If the responsive attribute is not defined or is not an object, return an empty object.
  if ( ! responsiveAttr || 'object' !== typeof responsiveAttr ) {
    return {};
  }

  // Get the fallback values.
  const fallback = responsiveAttr.desktop || {};

  // Get the current values.
  const current = responsiveAttr[device] || {};

  // Get the final values.
  const final = {
    top: '' !== current.top?.trim() ? current.top : fallback.top,
    right: '' !== current.right?.trim() ? current.right : fallback.right,
    bottom: '' !== current.bottom?.trim() ? current.bottom : fallback.bottom,
    left: '' !== current.left?.trim() ? current.left : fallback.left,
    unit: current.unit || fallback.unit || 'px'
  };

  // Return the padding style.
  return {
    paddingTop: final.top + final.unit,
    paddingRight: final.right + final.unit,
    paddingBottom: final.bottom + final.unit,
    paddingLeft: final.left + final.unit
  };
};

/**
 * Returns responsive margin styles (top, right, bottom, left) based on the given device.
 * Falls back to desktop values if the current device values are not defined.
 *
 * @param {Object} responsiveAttr - Object containing margin values per device.
 * @param {string} device - The current device ('desktop', 'tablet', or 'mobile').
 * @returns {Object} CSS margin style object.
 */
export const getResponsiveMarginStyle = ( responsiveAttr, device = 'desktop' ) => {
  if ( ! responsiveAttr || 'object' !== typeof responsiveAttr ) {
    return {};
  }

  // Get the fallback values.
  const fallback = responsiveAttr.desktop || {};

  // Get the current values.
  const current = responsiveAttr[device] || {};

  // Get the final values.
  const final = {
    top: '' !== current.top?.trim() ? current.top : fallback.top,
    right: '' !== current.right?.trim() ? current.right : fallback.right,
    bottom: '' !== current.bottom?.trim() ? current.bottom : fallback.bottom,
    left: '' !== current.left?.trim() ? current.left : fallback.left,
    unit: current.unit || fallback.unit || 'px'
  };

  // Return the margin style.
  return {
    marginTop: final.top + final.unit,
    marginRight: final.right + final.unit,
    marginBottom: final.bottom + final.unit,
    marginLeft: final.left + final.unit
  };
};

/**
 * Returns a responsive max-width style based on section width type and device-specific widths.
 * Returns '100%' for full-width, 'auto' for inline-width, or a specific max-width with units.
 *
 * @param {string} type - Type of width ('full', 'inline', or custom).
 * @param {Object} widths - Object containing width values per device.
 * @param {string} unit - Unit for the width (default is 'px').
 * @param {string} device - The current device ('desktop', 'tablet', or 'mobile').
 * @returns {Object} CSS width style object.
 */
export const getResponsiveWidthStyle = ( type, widths = {}, unit = 'px', device = 'desktop' ) => {

  // If the type is not defined, return the default style.
  if ( '' === type ) {
    return { undefined };
  }

  // If the type is full, return the default style.
  if ( 'full' === type ) {
    return { maxWidth: '100%' };
  }

  // If the type is inline, return the default style.
  if ( 'inline' === type ) {
    return { width: 'auto' };
  }

  // Get the fallback values.
  const fallback = widths.desktop ?? '';

  // Get the current values.
  const width = widths[device] ?? fallback;

  // Return the width style.
  return width ?
    { maxWidth: `${width}${unit}` } :
    {};
};

/**
 * Returns responsive font size with unit based on the given device.
 * Falls back to desktop size if not available for the current device.
 *
 * @param {Object} fontSize - Object containing font size values per device.
 * @param {string} unit - Unit for the font size (default is 'px').
 * @param {string} device - The current device ('desktop', 'tablet', or 'mobile').
 * @returns {string|undefined} Font size with unit or undefined if no value.
 */

export const getResponsiveFontSize = ( fontSize = {}, unit = 'px', device = 'desktop' ) => {

  // Get the fallback values.
  const fallback = fontSize.desktop;

  // Get the current values.
  const value = fontSize[device];

  // If the value is 0, null, undefined, empty string, or less than 0, return the default style.
  // If value is 0, null, undefined, empty string, or less than 0.
  const isInvalid = value === undefined || null === value || '' === value || 0 >= Number( value );

  // Get the valid value.
  const validValue = isInvalid ? fallback : value;

  // Return the font size style.
  return validValue && 0 < Number( validValue ) ?
    { fontSize: `${validValue}${unit}` } :
    { fontSize: 'revert-layer' };
};

/**
 * Returns responsive line height with unit based on the given device.
 * Falls back to desktop size if not available for the current device.
 *
 * @param {Object} lineHeight - Object containing line height values per device.
 * @param {string} unit - Unit for the font size (default is 'px').
 * @param {string} device - The current device ('desktop', 'tablet', or 'mobile').
 * @returns {string|undefined} Font size with unit or undefined if no value.
 */

export const getResponsiveLineHeight = ( lineHeight = {}, unit = 'px', device = 'desktop' ) => {

  // Get the fallback values.
  const fallback = lineHeight.desktop;

  // Get the current values.
  const value = lineHeight[device];

  // If the value is 0, null, undefined, empty string, or less than 0, return the default style.
  // If value is 0, null, undefined, empty string, or less than 0.
  const isInvalid = value === undefined || null === value || '' === value || 0 >= Number( value );

  // Get the valid value.
  const validValue = isInvalid ? fallback : value;

  // Return the line height style.
  return validValue && 0 < Number( validValue ) ?
    { lineHeight: `${validValue}${unit}` } :
    { lineHeight: 'revert-layer' };
};

/**
 * Returns text shadow style based on the given shadow object and active device.
 *
 * @param {Object} shadow - Object containing text shadow values per device.
 * @param {string} activeDevice - The current device ('desktop', 'tablet', or 'mobile').
 * @returns {Object} CSS text shadow style object.
 */
export const getTextShadowStyle = ( shadow, activeDevice = 'desktop' ) => {

  // If the text shadow is not defined, return the default style.
  if ( ! shadow || true !== shadow.enable ) {
    return { textShadow: 'none' };
  }

  // Fallback order for text shadow.
  const fallbackOrder = {
    mobile: [ 'mobile', 'tablet', 'desktop' ],
    tablet: [ 'tablet', 'desktop' ],
    desktop: [ 'desktop' ]
  };

  // Get the value of the text shadow.
  const getValue = ( key ) => {

    // Loop through the fallback order and get the value of the text shadow.
    for ( const device of fallbackOrder[activeDevice]) {
      const val = shadow?.[device]?.[key];
      if ( val !== undefined && null !== val && '' !== String( val ).trim() ) {
        return val;
      }
    }
    return undefined;
  };

  const x = getValue( 'x' ); // X position.
  const y = getValue( 'y' ); // Y position.
  const blur = getValue( 'blur' ); // Blur radius.
  const color = getValue( 'color' ); // Color.

  // If the text shadow is not defined, return the default style.
  if ( x === undefined || y === undefined || blur === undefined || color === undefined ) {
    return { textShadow: 'none' };
  }

  // Return the text shadow style.
  return {
    textShadow: `${x}px ${y}px ${blur}px ${color}`
  };
};
