<?php
/**
 * Position trait — PHP CSS emit. Bag attr `position = { type, top,
 * right, bottom, left }`. Mirrors JS `buildPositionDecls` byte-for-byte.
 * NOT hover-aware (structural).
 *
 * Emit gate: `type` ∈ {relative, absolute, fixed, sticky}. `auto` (or
 * absent) is the browser default → no CSS.
 *
 * Z-index is NOT emitted here — it has its own trait (`zindex`) with
 * its own flat primitive attribute (`zIndex` × 3 device variants).
 *
 * @package Blocksify
 */

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

class Blocksify_Position_Trait {

	/**
	 * Attribute schema fragment. Mirror of `src/shared/traits/position.js`
	 * `attributes` const. See spacing trait header for rationale + sync rule.
	 */
	public static function attributes() {
		return array(
			'position'        => array( 'type' => array( 'object', 'null' ) ),
			'positionTablet'  => array( 'type' => array( 'object', 'null' ) ),
			'positionMobile'  => array( 'type' => array( 'object', 'null' ) ),
		);
	}

	public static function emit_decls( $attrs, $device, $part_prefix = '' ) {
		$key = Blocksify_Attrs::part_key( $part_prefix, 'position', $device );
		$bag = isset( $attrs[ $key ] ) ? $attrs[ $key ] : null;
		return self::build_decls( $bag );
	}

	protected static function build_decls( $bag ) {
		if ( ! is_array( $bag ) ) {
			return '';
		}
		$type = isset( $bag['type'] ) ? $bag['type'] : null;
		$allowed_types = array( 'relative', 'absolute', 'fixed', 'sticky' );
		if ( ! in_array( $type, $allowed_types, true ) ) {
			return '';
		}
		$decls = 'position:' . $type . ';';
		foreach ( array( 'top', 'right', 'bottom', 'left' ) as $field ) {
			$formatted = self::format_offset(
				isset( $bag[ $field ] ) ? $bag[ $field ] : null
			);
			if ( null !== $formatted ) {
				$decls .= $field . ':' . $formatted . ';';
			}
		}
		return $decls;
	}

	protected static function format_offset( $field ) {
		if ( ! is_array( $field ) ) {
			return null;
		}
		if ( ! isset( $field['value'] ) || ! is_numeric( $field['value'] ) ) {
			return null;
		}
		$unit = isset( $field['unit'] ) && is_string( $field['unit'] ) && $field['unit']
			? $field['unit']
			: 'px';
		return ( (float) $field['value'] ) . $unit;
	}
}
