<?php
/**
 * Social login button style: width defaults to auto for icon-only; for label+icon, full unless module "inline row" (auto) or shortcode width.
 *
 * @package WP_PowerSuite\OAuth\UI
 */

namespace WP_PowerSuite\OAuth\UI;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

final class ButtonStyleHelper {

	public const STYLES = [ 'default', 'outline', 'minimal' ];

	public const WIDTHS = [ 'full', 'auto', 'custom' ];

	public const ALIGNS = [ 'left', 'center', 'right' ];

	/** label = text + icon; icon = icon only. */
	public const DISPLAYS = [ 'label', 'icon' ];

	public static function sanitize( string $style ): string {
		$s = sanitize_key( $style );
		return in_array( $s, self::STYLES, true ) ? $s : 'default';
	}

	public static function sanitizeWidth( string $w ): string {
		$w = sanitize_key( $w );
		return in_array( $w, self::WIDTHS, true ) ? $w : 'full';
	}

	public static function sanitizeAlign( string $a ): string {
		$a = sanitize_key( $a );
		return in_array( $a, self::ALIGNS, true ) ? $a : 'center';
	}

	public static function sanitizeDisplay( string $d ): string {
		$d = sanitize_key( $d );
		return in_array( $d, self::DISPLAYS, true ) ? $d : 'label';
	}

	/**
	 * “Inline row” for label+icon: use auto width so multiple providers sit in one row.
	 */
	public static function sanitizeLabelInline( $v ): bool {
		if ( is_bool( $v ) ) {
			return $v;
		}
		$s = is_string( $v ) ? strtolower( trim( $v ) ) : '';
		if ( in_array( $s, [ '1', 'true', 'yes', 'on' ], true ) ) {
			return true;
		}
		if ( in_array( $s, [ '0', 'false', 'no', 'off' ], true ) ) {
			return false;
		}
		return (bool) $v;
	}

	/**
	 * Allow values like 240px, 12rem, 100%, 18.5em.
	 */
	public static function sanitizeWidthCustom( string $v ): string {
		$v = trim( $v );
		if ( $v === '' ) {
			return '280px';
		}
		if ( ! preg_match( '/^\d+(\.\d+)?(px|em|rem|%)$/', $v ) ) {
			return '280px';
		}
		return $v;
	}

	/**
	 * @param array<string, mixed> $a Render options; empty style uses module’s saved style.
	 * @return array<string, mixed>
	 */
	public static function merge( array $a, string $module_default_style ): array {
		$in = isset( $a['style'] ) ? trim( (string) $a['style'] ) : '';
		if ( $in === '' ) {
			$a['style'] = self::sanitize( $module_default_style );
		} else {
			$a['style'] = self::sanitize( $in );
		}
		return $a;
	}

	/**
	 * Fills width, width_custom, align, display, type, show_text. If width is unset: icon mode → auto; label + module inline option → auto; else full. Shortcodes may override width.
	 *
	 * @param array<string, mixed> $a
	 * @param array<string, mixed> $raw_settings Module getSettings() output.
	 * @return array<string, mixed>
	 */
	public static function applyFromModuleSettings( array $a, array $raw_settings ): array {
		$style_def = (string) ( $raw_settings['button_style'] ?? 'default' );
		$a         = self::merge( $a, $style_def );

		$width_set = isset( $a['width'] ) && trim( (string) $a['width'] ) !== '';

		$wc = isset( $a['width_custom'] ) ? (string) $a['width_custom'] : '';
		if ( $wc === '' ) {
			$a['width_custom'] = '280px';
		} else {
			$a['width_custom'] = self::sanitizeWidthCustom( $wc );
		}

		$al = isset( $a['align'] ) ? trim( (string) $a['align'] ) : '';
		$a['align'] = self::sanitizeAlign( $al );

		$type_in = (string) ( $a['type'] ?? '' );
		$disp_in = isset( $a['display'] ) ? trim( (string) $a['display'] ) : '';
		$disp    = ( $disp_in === '' ) ? self::sanitizeDisplay( (string) ( $raw_settings['button_display'] ?? 'label' ) ) : self::sanitizeDisplay( $disp_in );
		if ( 'icon' === $type_in ) {
			$disp = 'icon';
		}

		$label_inline = self::sanitizeLabelInline( $raw_settings['button_label_inline'] ?? false );

		if ( 'icon' === $disp ) {
			$a['type']      = 'icon';
			$a['show_text'] = false;
		} else {
			if ( ! isset( $a['type'] ) || (string) $a['type'] === '' ) {
				$a['type'] = 'button';
			}
			if ( ! isset( $a['show_text'] ) ) {
				$a['show_text'] = true;
			}
		}

		if ( ! $width_set ) {
			if ( (string) ( $a['type'] ?? '' ) === 'icon' ) {
				$a['width'] = 'auto';
			} else {
				$a['width'] = $label_inline ? 'auto' : 'full';
			}
		} else {
			$a['width'] = self::sanitizeWidth( trim( (string) $a['width'] ) );
		}

		// Re-sync display to icon for final state.
		if ( (string) ( $a['type'] ?? '' ) === 'icon' ) {
			$a['show_text'] = false;
		}

		return $a;
	}
}
