<?php
/**
 * Footer widget configuration, defaults, and sanitization.
 *
 * @package Rsmspark_Content_Widgets
 */

defined( 'ABSPATH' ) || exit;

require_once RSMSPARK_CONTENT_WIDGETS_PATH . 'includes/class-rsmspark-content-widgets-footer-visibility.php';

/**
 * Rsmspark_Content_Widgets_Footer_Config
 */
class Rsmspark_Content_Widgets_Footer_Config {

	/**
	 * @return array<string, mixed>
	 */
	public static function demo_instance() {
		return array(
			'brand'     => array(
				'logo'        => 0,
				'name'        => 'RSMSpark',
				'description' => __( 'Production-grade WordPress plugins built for agencies, restaurants, directories, and serious site builders.', 'rsm-content-widgets' ),
			),
			'social'    => array(
				array(
					'icon'  => 'fa-brands fa-github',
					'url'   => 'https://rsmspark.com',
					'label' => 'GitHub',
				),
				array(
					'icon'  => 'fa-brands fa-x-twitter',
					'url'   => 'https://rsmspark.com',
					'label' => 'X',
				),
			),
			'columns'   => array(
				array(
					'title'       => __( 'Resources', 'rsm-content-widgets' ),
					'column_type' => 'link_list',
					'link_items'  => array(
						array( 'label' => __( 'Plugin Documentation', 'rsm-content-widgets' ), 'url' => '#' ),
						array( 'label' => __( 'Changelog', 'rsm-content-widgets' ), 'url' => '#' ),
						array( 'label' => __( 'Migration Guides', 'rsm-content-widgets' ), 'url' => '#' ),
						array( 'label' => 'RSMSpark', 'url' => 'https://rsmspark.com' ),
					),
				),
				array(
					'title'       => __( 'Support', 'rsm-content-widgets' ),
					'column_type' => 'link_list',
					'link_items'  => array(
						array( 'label' => __( 'Contact & Support', 'rsm-content-widgets' ), 'url' => 'https://rsmspark.com' ),
						array( 'label' => __( 'Priority Pro Support', 'rsm-content-widgets' ), 'url' => 'https://rsmspark.com' ),
						array( 'label' => __( 'Community Forum', 'rsm-content-widgets' ), 'url' => 'https://rsmspark.com' ),
						array( 'label' => __( 'License Management', 'rsm-content-widgets' ), 'url' => 'https://rsmspark.com' ),
					),
				),
				array(
					'title'       => __( 'Legal', 'rsm-content-widgets' ),
					'column_type' => 'text',
					'body'        => __( 'RSM Spark and all suite plugins are licensed GPLv2 or later. Advanced widgets are available as a separate Pro plugin from rsmspark.com.', 'rsm-content-widgets' ),
				),
			),
			'copyright' => __( '© 2026 RSMSpark. All rights reserved.', 'rsm-content-widgets' ),
			'region'    => 'default',
			'show_on'   => array(),
			'hide_on'   => array(),
			'show_on_post_types' => array(),
			'hide_on_post_types' => array(),
			'design'    => array(
				'background_color' => '#0b1220',
				'text_color'       => '#94a3b8',
				'heading_color'    => '#ffffff',
				'link_color'       => '#cbd5e1',
				'link_hover_color' => '#ffffff',
				'padding_y'        => 48,
				'column_gap'       => 32,
				'max_width'        => 0,
				'text_scale'       => 85,
				'placement'        => 'static',
				'reveal_mode'      => 'always',
				'back_to_top'      => false,
				'sticky_compact'   => false,
			),
		);
	}

	/**
	 * @param mixed $raw Raw instance.
	 * @return array<string, mixed>
	 */
	public static function sanitize_instance( $raw ) {
		if ( is_string( $raw ) && '' !== $raw ) {
			$decoded = json_decode( $raw, true );
			$raw     = is_array( $decoded ) ? $decoded : array();
		}
		if ( ! is_array( $raw ) ) {
			$raw = array();
		}

		$raw = Rsmspark_Content_Widgets_Footer_Visibility::flatten_instance( $raw );

		$demo  = self::demo_instance();
		$brand = wp_parse_args( isset( $raw['brand'] ) && is_array( $raw['brand'] ) ? $raw['brand'] : array(), $demo['brand'] );

		return array(
			'brand'              => array(
				'logo'        => absint( $brand['logo'] ?? 0 ),
				'name'        => sanitize_text_field( (string) ( $brand['name'] ?? '' ) ),
				'description' => sanitize_textarea_field( (string) ( $brand['description'] ?? '' ) ),
			),
			'social'             => self::sanitize_social( $raw['social'] ?? array() ),
			'columns'            => self::sanitize_columns( $raw['columns'] ?? array() ),
			'copyright'          => sanitize_text_field( (string) ( $raw['copyright'] ?? '' ) ),
			'region'             => self::sanitize_region( $raw['region'] ?? '' ),
			'show_on'            => Rsmspark_Content_Widgets_Footer_Visibility::read_page_type_flags( $raw, 'show_on' ),
			'hide_on'            => Rsmspark_Content_Widgets_Footer_Visibility::read_page_type_flags( $raw, 'hide_on' ),
			'show_on_post_types' => Rsmspark_Content_Widgets_Footer_Visibility::sanitize_post_types( $raw['show_on_post_types'] ?? array() ),
			'hide_on_post_types' => Rsmspark_Content_Widgets_Footer_Visibility::sanitize_post_types( $raw['hide_on_post_types'] ?? array() ),
			'design'             => self::sanitize_design( $raw['design'] ?? array(), $demo['design'] ),
		);
	}

	/**
	 * @param mixed $region Raw region slug.
	 * @return string
	 */
	public static function sanitize_region( $region ) {
		$region = sanitize_key( (string) $region );
		return '' !== $region ? $region : 'default';
	}

	/**
	 * @param mixed $items Social rows.
	 * @return array<int, array<string, string>>
	 */
	public static function sanitize_social( $items ) {
		if ( ! is_array( $items ) ) {
			return array();
		}

		$out = array();
		foreach ( $items as $item ) {
			if ( ! is_array( $item ) ) {
				continue;
			}
			$url = self::normalize_url( $item['url'] ?? '' );
			if ( '' === $url ) {
				continue;
			}
			$out[] = array(
				'icon'  => sanitize_text_field( (string) ( $item['icon'] ?? 'fa-solid fa-link' ) ),
				'url'   => $url,
				'label' => sanitize_text_field( (string) ( $item['label'] ?? '' ) ),
			);
		}

		return $out;
	}

	/**
	 * @param mixed $columns Column rows.
	 * @return array<int, array<string, mixed>>
	 */
	public static function sanitize_columns( $columns ) {
		if ( ! is_array( $columns ) ) {
			return array();
		}

		$out = array();
		foreach ( $columns as $column ) {
			if ( ! is_array( $column ) ) {
				continue;
			}

			$raw_type  = $column['column_type'] ?? $column['type'] ?? 'link_list';
			$link_rows = $column['link_items'] ?? $column['links'] ?? array();

			// SiteOrigin can store the link repeater in `type` when it collides with option value `links`.
			if ( is_array( $raw_type ) && empty( $link_rows ) ) {
				$link_rows = $raw_type;
				$raw_type  = 'link_list';
			}

			$type  = self::normalize_column_type( $raw_type );
			$links = self::sanitize_link_rows( $link_rows );
			$body  = ( 'text' === $type ) ? self::extract_column_body( $column ) : '';

			$title = sanitize_text_field( (string) ( $column['title'] ?? '' ) );

			$visibility = self::sanitize_column_visibility( $column );

			if ( 'text' === $type ) {
				if ( '' === $title && '' === $body ) {
					continue;
				}
				$out[] = array_merge(
					array(
						'title' => $title,
						'type'  => 'text',
						'body'  => $body,
					),
					$visibility
				);
				continue;
			}

			if ( '' === $title && empty( $links ) ) {
				continue;
			}

			$out[] = array_merge(
				array(
					'title' => $title,
					'type'  => 'links',
					'links' => $links,
				),
				$visibility
			);
		}

		return $out;
	}

	/**
	 * @param array<string, mixed> $column Raw column row.
	 * @return array{show_on: array<int, string>, hide_on: array<int, string>}
	 */
	public static function sanitize_column_visibility( array $column ) {
		return array(
			'show_on' => Rsmspark_Content_Widgets_Footer_Visibility::sanitize_types( $column['show_on'] ?? array() ),
			'hide_on' => Rsmspark_Content_Widgets_Footer_Visibility::sanitize_types( $column['hide_on'] ?? array() ),
		);
	}

	/**
	 * @param mixed $type Raw column type from forms or legacy data.
	 * @return string links|text
	 */
	public static function normalize_column_type( $type ) {
		if ( is_array( $type ) ) {
			return 'links';
		}

		$type = sanitize_key( (string) $type );
		if ( in_array( $type, array( 'text', 'text_block' ), true ) ) {
			return 'text';
		}

		return 'links';
	}

	/**
	 * Read column body copy from SiteOrigin / block / legacy field keys.
	 *
	 * @param array<string, mixed> $column Raw column row.
	 * @return string
	 */
	public static function extract_column_body( array $column ) {
		$candidates = array( 'body', 'text_content', 'content' );
		foreach ( $candidates as $key ) {
			if ( ! empty( $column[ $key ] ) && is_string( $column[ $key ] ) ) {
				return sanitize_textarea_field( $column[ $key ] );
			}
		}

		if ( isset( $column['text'] ) && is_string( $column['text'] ) ) {
			$text = trim( $column['text'] );
			if ( '' !== $text && ! in_array( sanitize_key( $text ), array( 'text', 'text_block', 'links', 'link_list' ), true ) ) {
				return sanitize_textarea_field( $text );
			}
		}

		return '';
	}

	/**
	 * @param mixed $rows Link repeater rows.
	 * @return array<int, array<string, string>>
	 */
	public static function sanitize_link_rows( $rows ) {
		if ( ! is_array( $rows ) ) {
			return array();
		}

		$out = array();
		foreach ( $rows as $link ) {
			$clean = self::sanitize_link_row( $link );
			if ( null !== $clean ) {
				$out[] = $clean;
			}
		}

		return $out;
	}

	/**
	 * @param mixed $link Raw link row.
	 * @return array<string, string>|null
	 */
	public static function sanitize_link_row( $link ) {
		if ( ! is_array( $link ) ) {
			return null;
		}

		$label = sanitize_text_field( (string) ( $link['label'] ?? $link['text'] ?? $link['title'] ?? '' ) );
		$url   = self::normalize_url( $link['url'] ?? $link['link'] ?? '' );

		if ( '' === $label || '' === $url ) {
			return null;
		}

		return array(
			'label' => $label,
			'url'   => $url,
		);
	}

	/**
	 * @param mixed $url Raw URL or SiteOrigin link field value.
	 * @return string
	 */
	public static function normalize_url( $url ) {
		if ( class_exists( 'Rsmspark_Content_Widgets_Render', false ) ) {
			$resolved = Rsmspark_Content_Widgets_Render::link_url( $url );
			if ( '' !== $resolved ) {
				return $resolved;
			}
		}

		if ( is_array( $url ) ) {
			if ( ! empty( $url['url'] ) ) {
				$url = $url['url'];
			} elseif ( ! empty( $url['post'] ) ) {
				$url = 'post:' . (int) $url['post'];
			} else {
				$url = '';
			}
		}

		$url = trim( (string) $url );
		if ( '' === $url ) {
			return '';
		}

		if ( '#' === $url || str_starts_with( $url, '#' ) ) {
			return sanitize_text_field( $url );
		}

		if ( str_starts_with( $url, '/' ) || str_starts_with( $url, '?' ) ) {
			return sanitize_text_field( $url );
		}

		if ( preg_match( '/^post:\s*(\d+)/i', $url, $matches ) ) {
			$permalink = get_permalink( (int) $matches[1] );
			return $permalink ? (string) $permalink : '';
		}

		$clean = esc_url_raw( $url );
		return $clean ? $clean : sanitize_text_field( $url );
	}

	/**
	 * @param mixed                $design   Raw design.
	 * @param array<string, mixed> $defaults Defaults.
	 * @return array<string, mixed>
	 */
	public static function sanitize_design( $design, array $defaults ) {
		$design = wp_parse_args( is_array( $design ) ? $design : array(), $defaults );

		return array(
			'background_color' => sanitize_hex_color( (string) ( $design['background_color'] ?? '' ) ) ?: (string) $defaults['background_color'],
			'text_color'       => sanitize_hex_color( (string) ( $design['text_color'] ?? '' ) ) ?: (string) $defaults['text_color'],
			'heading_color'    => sanitize_hex_color( (string) ( $design['heading_color'] ?? '' ) ) ?: (string) $defaults['heading_color'],
			'link_color'       => sanitize_hex_color( (string) ( $design['link_color'] ?? '' ) ) ?: (string) $defaults['link_color'],
			'link_hover_color' => sanitize_hex_color( (string) ( $design['link_hover_color'] ?? '' ) ) ?: (string) $defaults['link_hover_color'],
			'padding_y'        => max( 0, min( 120, (int) ( $design['padding_y'] ?? $defaults['padding_y'] ) ) ),
			'column_gap'       => max( 0, min( 80, (int) ( $design['column_gap'] ?? $defaults['column_gap'] ) ) ),
			'max_width'        => max( 0, min( 1600, (int) ( $design['max_width'] ?? 0 ) ) ),
			'text_scale'       => self::sanitize_text_scale( $design['text_scale'] ?? null, (int) $defaults['text_scale'] ),
			'placement'        => self::sanitize_placement( $design['placement'] ?? null ),
			'reveal_mode'      => self::sanitize_reveal_mode( $design['reveal_mode'] ?? null ),
			'back_to_top'      => ! empty( $design['back_to_top'] ),
			'sticky_compact'   => ! empty( $design['sticky_compact'] ),
		);
	}

	/**
	 * @param mixed $placement Raw placement mode.
	 * @return string static|sticky_bar
	 */
	public static function sanitize_placement( $placement ) {
		$placement = sanitize_key( (string) $placement );
		return in_array( $placement, array( 'static', 'sticky_bar' ), true ) ? $placement : 'static';
	}

	/**
	 * @param mixed $mode Raw reveal mode.
	 * @return string always|scroll_up|scroll_down
	 */
	public static function sanitize_reveal_mode( $mode ) {
		$mode = sanitize_key( (string) $mode );
		return in_array( $mode, array( 'always', 'scroll_up', 'scroll_down' ), true ) ? $mode : 'always';
	}

	/**
	 * @param mixed $scale Raw scale percentage.
	 * @param int   $default Default when empty.
	 * @return int
	 */
	public static function sanitize_text_scale( $scale, $default = 85 ) {
		if ( null === $scale || '' === $scale ) {
			return max( 50, min( 135, (int) $default ) );
		}

		return max( 50, min( 135, (int) round( (float) $scale ) ) );
	}

	/**
	 * Scaled body copy size in rem.
	 *
	 * @param int $scale Percentage (50–135).
	 * @return string
	 */
	public static function body_font_size_css( $scale ) {
		$scale   = self::sanitize_text_scale( $scale );
		$body_rem = 0.75 * ( $scale / 100 );

		return round( $body_rem, 4 ) . 'rem';
	}

	/**
	 * Column heading size in rem; always slightly larger than body copy.
	 *
	 * @param int $scale Percentage (50–135).
	 * @return string
	 */
	public static function heading_font_size_css( $scale ) {
		$scale       = self::sanitize_text_scale( $scale );
		$body_rem    = 0.75 * ( $scale / 100 );
		$heading_rem = max( 0.8125, round( $body_rem * 1.1, 4 ) );

		return $heading_rem . 'rem';
	}

	/**
	 * Social icon size in rem; scales with body copy but keeps a sensible floor.
	 *
	 * @param int $scale Percentage (50–135).
	 * @return string
	 */
	public static function social_font_size_css( $scale ) {
		$scale      = self::sanitize_text_scale( $scale );
		$body_rem   = 0.75 * ( $scale / 100 );
		$social_rem = max( 0.5, round( $body_rem * 1.15, 4 ) );

		return $social_rem . 'rem';
	}

	/**
	 * Flatten SiteOrigin section instance into unified shape.
	 *
	 * @param array<string, mixed> $instance SO instance.
	 * @return array<string, mixed>
	 */
	public static function from_siteorigin_instance( array $instance ) {
		$brand  = isset( $instance['brand'] ) && is_array( $instance['brand'] ) ? $instance['brand'] : array();
		$design = isset( $instance['design'] ) && is_array( $instance['design'] ) ? $instance['design'] : array();
		$flat   = Rsmspark_Content_Widgets_Footer_Visibility::flatten_instance( $instance );

		return self::sanitize_instance(
			array_merge(
				$flat,
				array(
					'brand'     => $brand,
					'social'    => $instance['social'] ?? array(),
					'columns'   => $instance['columns'] ?? array(),
					'copyright' => $instance['copyright'] ?? '',
					'design'    => $design,
				)
			)
		);
	}

	/**
	 * @param array<string, mixed> $instance Sanitized instance.
	 * @return array<string, mixed>
	 */
	public static function prepare_view_model( array $instance ) {
		$instance = self::sanitize_instance( $instance );
		$design   = $instance['design'];
		$logo_url = '';

		if ( ! empty( $instance['brand']['logo'] ) ) {
			$logo_url = wp_get_attachment_image_url( (int) $instance['brand']['logo'], 'medium' );
		}

		$text_scale = self::sanitize_text_scale( $design['text_scale'] ?? 85 );

		$vars = array(
			'--rf-bg'                 => $design['background_color'],
			'--rf-text'               => $design['text_color'],
			'--rf-heading'            => $design['heading_color'],
			'--rf-link'               => $design['link_color'],
			'--rf-link-hover'         => $design['link_hover_color'],
			'--rf-pad-y'              => (int) $design['padding_y'] . 'px',
			'--rf-column-gap'         => (int) $design['column_gap'] . 'px',
			'--rf-content-width'      => '90%',
			'--rf-body-font-size'     => self::body_font_size_css( $text_scale ),
			'--rf-heading-font-size'  => self::heading_font_size_css( $text_scale ),
			'--rf-social-font-size'   => self::social_font_size_css( $text_scale ),
		);

		if ( ! empty( $design['max_width'] ) ) {
			$vars['--rf-max-width'] = (int) $design['max_width'] . 'px';
		}

		$style_parts = array();
		foreach ( $vars as $key => $value ) {
			$style_parts[] = $key . ':' . $value;
		}

		$columns      = Rsmspark_Content_Widgets_Footer_Visibility::filter_columns( $instance['columns'] );
		$column_count = 1 + count( $columns );
		$column_count = max( 1, min( 6, $column_count ) );

		$placement   = self::sanitize_placement( $design['placement'] ?? 'static' );
		$reveal_mode = self::sanitize_reveal_mode( $design['reveal_mode'] ?? 'always' );
		$back_to_top = ! empty( $design['back_to_top'] );
		$is_sticky   = ( 'sticky_bar' === $placement );

		$classes = array( 'rsmspark-footer' );
		if ( $is_sticky ) {
			$classes[] = 'rsmspark-footer--sticky-bar';
			if ( ! empty( $design['sticky_compact'] ) ) {
				$classes[] = 'rsmspark-footer--sticky-compact';
			}
		}
		if ( $back_to_top ) {
			$classes[] = 'rsmspark-footer--has-back-to-top';
		}

		return array(
			'brand'         => $instance['brand'],
			'brand_logo_url'=> $logo_url ? (string) $logo_url : '',
			'social'        => $instance['social'],
			'columns'       => $columns,
			'copyright'     => $instance['copyright'],
			'region'        => $instance['region'],
			'inline_style'  => implode( ';', $style_parts ),
			'column_count'  => $column_count,
			'has_brand'     => '' !== $instance['brand']['name'] || '' !== $instance['brand']['description'] || '' !== $logo_url || ! empty( $instance['social'] ),
			'has_columns'   => ! empty( $columns ),
			'has_copyright' => '' !== $instance['copyright'],
			'placement'     => $placement,
			'reveal_mode'   => $reveal_mode,
			'back_to_top'   => $back_to_top,
			'is_sticky'     => $is_sticky,
			'footer_class'  => implode( ' ', $classes ),
		);
	}

	const EXPORT_PLUGIN = 'rsmspark-content-widgets';

	const EXPORT_WIDGET = 'footer';

	/**
	 * Add attachment URL hints for cross-site imports (not stored in block attrs).
	 *
	 * @param array<string, mixed> $config Sanitized config.
	 * @return array<string, mixed>
	 */
	public static function enrich_export_media( array $config ) {
		if ( ! empty( $config['brand']['logo'] ) ) {
			$url = wp_get_attachment_image_url( (int) $config['brand']['logo'], 'medium' );
			if ( $url ) {
				$config['brand_logo_url'] = (string) $url;
			}
		}

		return $config;
	}

	/**
	 * @param array<string, mixed> $config Footer config or SO instance.
	 * @param string               $label  Export label.
	 * @return array<string, mixed>
	 */
	public static function build_export_payload( array $config, $label = '' ) {
		$config = self::from_siteorigin_instance( $config );
		$config = self::sanitize_instance( $config );
		$config = self::enrich_export_media( $config );

		if ( '' === trim( $label ) ) {
			$label = (string) ( $config['brand']['name'] ?? '' );
		}
		if ( '' === trim( $label ) ) {
			$label = __( 'Footer', 'rsm-content-widgets' );
		}

		return array(
			'plugin'      => self::EXPORT_PLUGIN,
			'widget'      => self::EXPORT_WIDGET,
			'version'     => RSMSPARK_CONTENT_WIDGETS_VERSION,
			'exported_at' => gmdate( DATE_ATOM ),
			'label'       => sanitize_text_field( $label ),
			'config'      => $config,
		);
	}

	/**
	 * @param array<string, mixed> $payload Decoded export payload.
	 * @return array<string, mixed>|null
	 */
	public static function extract_config_from_payload( array $payload ) {
		$plugin = (string) ( $payload['plugin'] ?? '' );

		if (
			self::EXPORT_PLUGIN === $plugin
			&& self::EXPORT_WIDGET === sanitize_key( (string) ( $payload['widget'] ?? '' ) )
			&& is_array( $payload['config'] ?? null )
		) {
			return $payload['config'];
		}

		if (
			self::EXPORT_PLUGIN === $plugin
			&& self::EXPORT_WIDGET === sanitize_key( (string) ( $payload['block'] ?? '' ) )
			&& is_array( $payload['attributes'] ?? null )
		) {
			return $payload['attributes'];
		}

		return null;
	}

	/**
	 * @param mixed $payload Decoded JSON or array.
	 * @return array{config: array<string, mixed>, label: string}|null
	 */
	public static function parse_import_payload( $payload ) {
		if ( is_string( $payload ) ) {
			$payload = json_decode( $payload, true );
		}

		if ( ! is_array( $payload ) ) {
			return null;
		}

		$config = self::extract_config_from_payload( $payload );
		if ( null === $config ) {
			return null;
		}

		return array(
			'label'  => sanitize_text_field( (string) ( $payload['label'] ?? '' ) ),
			'config' => self::sanitize_instance( $config ),
		);
	}

	/**
	 * Merge imported config onto current footer config.
	 *
	 * @param array<string, mixed> $config  Import config.
	 * @param array<string, mixed> $current Current config.
	 * @return array<string, mixed>
	 */
	public static function merge_config( array $config, array $current = array() ) {
		$config  = self::sanitize_instance( $config );
		$current = self::sanitize_instance( $current );
		$merged  = $current;

		foreach ( array( 'copyright', 'region', 'show_on', 'hide_on', 'show_on_post_types', 'hide_on_post_types' ) as $key ) {
			if ( array_key_exists( $key, $config ) ) {
				$merged[ $key ] = $config[ $key ];
			}
		}

		if ( isset( $config['brand'] ) && is_array( $config['brand'] ) ) {
			$merged['brand'] = array_merge( $current['brand'], $config['brand'] );
			if ( empty( $config['brand']['logo'] ) && ! empty( $current['brand']['logo'] ) ) {
				$merged['brand']['logo'] = $current['brand']['logo'];
			}
		}

		if ( isset( $config['design'] ) && is_array( $config['design'] ) ) {
			$merged['design'] = array_merge( $current['design'], $config['design'] );
		}

		if ( array_key_exists( 'social', $config ) ) {
			$merged['social'] = $config['social'];
		}

		if ( array_key_exists( 'columns', $config ) ) {
			$merged['columns'] = $config['columns'];
		}

		return self::sanitize_instance( $merged );
	}

	/**
	 * Convert unified config into a SiteOrigin widget instance shape.
	 *
	 * @param array<string, mixed> $config Sanitized config.
	 * @return array<string, mixed>
	 */
	public static function to_siteorigin_instance( array $config ) {
		$config = self::sanitize_instance( $config );

		$instance = array(
			'region'             => $config['region'],
			'copyright'          => $config['copyright'],
			'social'             => $config['social'],
			'columns'            => $config['columns'],
			'show_on_post_types' => $config['show_on_post_types'],
			'hide_on_post_types' => $config['hide_on_post_types'],
			'brand'              => $config['brand'],
			'design'             => $config['design'],
		);

		foreach ( array_keys( Rsmspark_Content_Widgets_Footer_Visibility::page_type_options() ) as $slug ) {
			$instance[ Rsmspark_Content_Widgets_Footer_Visibility::checkbox_field_name( 'show_on', $slug ) ] = in_array( $slug, $config['show_on'], true );
			$instance[ Rsmspark_Content_Widgets_Footer_Visibility::checkbox_field_name( 'hide_on', $slug ) ] = in_array( $slug, $config['hide_on'], true );
		}

		return $instance;
	}

	/**
	 * Apply imported config onto a SiteOrigin footer instance.
	 *
	 * @param array<string, mixed> $instance Current SO instance.
	 * @param array<string, mixed> $config   Import config.
	 * @return array<string, mixed>
	 */
	public static function merge_siteorigin_instance( array $instance, array $config ) {
		$current = self::from_siteorigin_instance( $instance );
		$merged  = self::merge_config( $config, $current );

		return self::to_siteorigin_instance( $merged );
	}
}
