<?php
/**
 * Number Control
 *
 * Number input with min/max/step support
 *
 * @package GuardDog
 * @since 1.8.45
 */

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

class Guard_Dog_Number_Control extends Guard_Dog_Customizer_Control {

    /**
     * Render the control
     *
     * @param mixed $value Current value
     */
    public function render($value) {
        $this->render_wrapper_start();

        $min = $this->get_arg('min', null);
        $max = $this->get_arg('max', null);
        $step = $this->get_arg('step', 1);

        ?>
        <input type="number"
               id="<?php echo esc_attr($this->id); ?>"
               name="<?php echo esc_attr($this->id); ?>"
               class="small-text"
               value="<?php echo esc_attr($value); ?>"
               <?php if ($min !== null): ?>min="<?php echo esc_attr($min); ?>"<?php endif; ?>
               <?php if ($max !== null): ?>max="<?php echo esc_attr($max); ?>"<?php endif; ?>
               step="<?php echo esc_attr($step); ?>"
               <?php echo $this->get_input_attrs_html(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
        />
        <?php

        $this->render_wrapper_end();
    }

    /**
     * Sanitize the control value
     *
     * @param mixed $value Value to sanitize
     * @return int|float Sanitized number
     */
    public function sanitize($value) {
        // Handle empty value
        if ($value === '' || $value === null) {
            return $this->get_default();
        }

        // Convert to number
        $step = $this->get_arg('step', 1);

        if ($step < 1 && strpos((string)$step, '.') !== false) {
            // Float
            $value = floatval($value);
        } else {
            // Integer
            $value = intval($value);
        }

        // Apply min/max constraints
        $min = $this->get_arg('min', null);
        $max = $this->get_arg('max', null);

        if ($min !== null && $value < $min) {
            $value = $min;
        }

        if ($max !== null && $value > $max) {
            $value = $max;
        }

        return $value;
    }

    /**
     * Validate the control value
     *
     * @param mixed $value Value to validate
     * @return bool True if valid number
     */
    public function validate($value) {
        if (!is_numeric($value)) {
            return false;
        }

        $min = $this->get_arg('min', null);
        $max = $this->get_arg('max', null);

        if ($min !== null && $value < $min) {
            return false;
        }

        if ($max !== null && $value > $max) {
            return false;
        }

        return true;
    }

    /**
     * Get default arguments
     *
     * @return array
     */
    protected function get_default_args() {
        return array_merge(parent::get_default_args(), [
            'min' => null,
            'max' => null,
            'step' => 1,
        ]);
    }
}
