<?php

/**
 * Settings normalization and migration.
 *
 * Shared normalization only handles the base keys. Additional normalization is
 * applied separately when those features are available.
 *
 * @package B3WVS\VariationSwatches\Admin\Settings
 */
namespace B3WVS\VariationSwatches\Admin\Settings;

defined( 'ABSPATH' ) || exit;
/**
 * Class Normalizer
 *
 * Handles settings normalization and migration for backwards compatibility.
 */
class Normalizer {
    /**
     * Normalize settings with migrations and defaults.
     *
     * @param array $settings The raw settings from database.
     * @param array $defaults The default settings.
     * @return array
     */
    public function normalize( $settings, $defaults ) {
        if ( !is_array( $settings ) ) {
            $settings = array();
        }
        $merged = array_merge( $defaults, $settings );
        $merged = $this->normalize_layout( $merged );
        $merged = $this->normalize_shape( $merged );
        $merged = $this->normalize_swatch_style( $merged );
        $merged = $this->normalize_padding( $merged, 'layout_padding_', 5 );
        $merged = $this->normalize_padding( $merged, 'external_padding_', 5 );
        $merged = $this->normalize_padding( $merged, 'padding_', null );
        $merged = $this->normalize_swatch_size( $merged );
        $merged = $this->normalize_booleans( $merged );
        return $this->remove_legacy_keys( $merged );
    }

    /**
     * Remove obsolete legacy settings keys from normalized output.
     *
     * @param array $merged The merged settings.
     * @return array
     */
    private function remove_legacy_keys( $merged ) {
        unset($merged['swatch_size']);
        unset($merged['swatchGap']);
        unset($merged['layout_padding']);
        unset($merged['paddingTop']);
        unset($merged['paddingRight']);
        unset($merged['paddingBottom']);
        unset($merged['paddingLeft']);
        return $merged;
    }

    /**
     * Normalize shared layout setting.
     *
     * @param array $merged The merged settings.
     * @return array
     */
    private function normalize_layout( $merged ) {
        $layout = ( isset( $merged['layout'] ) ? sanitize_text_field( $merged['layout'] ) : 'wrap' );
        $merged['layout'] = ( 'wrap' === $layout ? 'wrap' : 'wrap' );
        return $merged;
    }

    /**
     * Normalize shared shape setting.
     *
     * @param array $merged The merged settings.
     * @return array
     */
    private function normalize_shape( $merged ) {
        $shape = ( isset( $merged['shape'] ) ? sanitize_text_field( $merged['shape'] ) : 'square' );
        $merged['shape'] = ( 'square' === $shape ? 'square' : 'square' );
        return $merged;
    }

    /**
     * Normalize shared selector style.
     *
     * @param array $merged The merged settings.
     * @return array
     */
    private function normalize_swatch_style( $merged ) {
        $swatch_style = ( isset( $merged['swatch_style'] ) ? sanitize_text_field( $merged['swatch_style'] ) : 'underline' );
        $merged['swatch_style'] = ( 'underline' === $swatch_style ? 'underline' : 'underline' );
        return $merged;
    }

    /**
     * Normalize padding blocks.
     *
     * @param array    $merged The merged settings.
     * @param string   $prefix Setting prefix.
     * @param int|null $fallback Default value. When null, per-side padding defaults are used.
     * @return array
     */
    private function normalize_padding( $merged, $prefix, $fallback ) {
        foreach ( array(
            'top',
            'right',
            'bottom',
            'left'
        ) as $side ) {
            $key = $prefix . $side;
            $side_default = ( null === $fallback ? ( 'left' === $side || 'right' === $side ? 16 : 8 ) : $fallback );
            $value = ( isset( $merged[$key] ) ? absint( $merged[$key] ) : $side_default );
            if ( $value > 48 ) {
                $value = $side_default;
            }
            $merged[$key] = $value;
        }
        return $merged;
    }

    /**
     * Normalize shared swatch sizes.
     *
     * @param array $merged The merged settings.
     * @return array
     */
    private function normalize_swatch_size( $merged ) {
        $merged['swatch_width'] = ( isset( $merged['swatch_width'] ) ? absint( $merged['swatch_width'] ) : 32 );
        $merged['swatch_height'] = ( isset( $merged['swatch_height'] ) ? absint( $merged['swatch_height'] ) : 32 );
        if ( $merged['swatch_width'] < 24 || $merged['swatch_width'] > 60 ) {
            $merged['swatch_width'] = 32;
        }
        if ( $merged['swatch_height'] < 24 || $merged['swatch_height'] > 60 ) {
            $merged['swatch_height'] = 32;
        }
        return $merged;
    }

    /**
     * Normalize shared booleans.
     *
     * @param array $merged The merged settings.
     * @return array
     */
    private function normalize_booleans( $merged ) {
        $merged['show_labels'] = !empty( $merged['show_labels'] );
        $merged['show_labels_colors'] = !empty( $merged['show_labels_colors'] );
        $merged['enable_tooltips'] = !empty( $merged['enable_tooltips'] );
        $merged['auto_convert_dropdowns'] = !isset( $merged['auto_convert_dropdowns'] ) || !empty( $merged['auto_convert_dropdowns'] );
        $merged['remove_on_uninstall'] = !empty( $merged['remove_on_uninstall'] );
        return $merged;
    }

}
