<?php

namespace Fab\Feature;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Feature base class
 * - Feature class used to define a feature of the plugin.
 * - Feature class mainly used to group plugin settings together.
 *
 * @package    Fab
 * @subpackage Fab\Includes
 */
class Feature extends \Fab\Controller\Controller {

    // Load plugin traits.
    use \Fab\Plugin\Helper\Singleton;

    /**
     * Feature key
     *
     * @var     string
     */
    protected $key;

    /**
     * Feature name
     *
     * @var     string
     */
    protected $name;

    /**
     * Feature description
     *
     * @var     string
     */
    protected $description;

    /**
     * Feature options
     *
     * @var     object
     */
    protected $options;

    /**
     * Feature params
     *
     * @var     object
     */
    protected $params;

    /**
     * Feature construect
     *
     * @return void
     * @var    object   $plugin     Feature configuration
     * @pattern prototype
     */
    public function __construct() {
        $this->options = (object) array();
        $this->params  = (object) array();
    }

    /**
     * Load options value from database
     *
     * @return void
     */
    public function load_options() {
        $has_options = false;
        foreach ( $this->options as $section => &$section_data ) {
            foreach ( $section_data['children'] as $key => &$value ) {
                // Unset the option if premium is set and it value not equal to current plan.
                if ( isset( $value['premium'] ) && \FAB()->Helper->isPremiumPlan() !== $value['premium'] ) {
                    unset( $section_data['children'][ $key ] );
                    continue;
                }
                // Make sure there are options to save.
                $has_options = true;
                // Load option value from database.
                $option_key     = sprintf( 'fab_%s', $key );
                $option_value   = get_option( $option_key );
                $value['value'] = $option_value ? $option_value : $value['value'];
            }

            // Remove section if no valid options remain.
            if ( empty( $section_data['children'] ) || ! isset( $has_options ) ) {
                unset( $this->options[ $section ] );
            }
        }

        // If there are no options to save, set the options to an empty array.
        $this->options = $has_options ? $this->options : array();
    }

    /**
     * Update plugin settings options value in database
     *
     * @param array $params $_POST data.
     * @return void
     */
    public function update_settings( $params ) {
        $this->init_options();
        $data = $params[ sprintf( 'fab_%s', $this->key ) ];
        $data = \FAB()->Helper->sanitizeTextField( $data );

        // Update the data.
        foreach ( $data as $section => $section_data ) {
            foreach ( $section_data['children'] as $key => $value ) {
                $option_config = $this->options[ $section ]['children'][ $key ];
                $option_key    = sprintf( 'fab_%s', $key );
                $option_value  = $data[ $section ]['children'][ $key ]['value'];

                // Transform the value.
                if ( isset( $option_config['transform'] ) ) {
                    $option_value = $option_config['transform'][ $option_value ];
                }

                // Update the option.
                update_option( $option_key, $option_value );
            }
        }
    }

    /**
     * @return string
     */
    public function getKey() {
        return $this->key;
    }

    /**
     * @param string $key
     */
    public function setKey( $key ) {
        $this->key = $key;
    }

    /**
     * @return string
     */
    public function getName() {
        return $this->name;
    }

    /**
     * @param string $name
     */
    public function setName( $name ) {
        $this->name = $name;
    }

    /**
     * @return string
     */
    public function getDescription() {
        return $this->description;
    }

    /**
     * @param string $description
     */
    public function setDescription( $description ) {
        $this->description = $description;
    }

    /**
     * @return object
     */
    public function getOptions() {
        return $this->options;
    }

    /**
     * @param object $options
     */
    public function setOptions( $options ): void {
        $this->options = $options;
    }

    /**
     * @return object
     */
    public function getParams() {
        return $this->params;
    }

    /**
     * @param object $params
     */
    public function setParams( $params ): void {
        $this->params = $params;
    }

    /** Grab All Assigned Variables */
    public function getVars() {
        return get_object_vars( $this );
    }
}
