<?php

namespace HulkPlugins\ElementorPro\Forms\AdvancedFields\Models;

use HulkPlugins\ElementorPro\Forms\AdvancedFields\Traits\SingletonTrait;
use function HulkPlugins\ElementorPro\Forms\AdvancedFields\hulk_affef_fs;
use const HulkPlugins\ElementorPro\Forms\AdvancedFields\PLUGIN_DIR_PATH;
use const HulkPlugins\ElementorPro\Forms\AdvancedFields\PREFIX;
if ( !defined( 'ABSPATH' ) ) {
    exit;
    // Exit if accessed directly.
}
class SettingsModel {
    use SingletonTrait;
    private array $attributes;

    private string $optionName = PREFIX . 'settings';

    private array $supportedFields = [];

    private array $fieldsInfo = [];

    private array $defaultOptions = [
        'fields' => [],
    ];

    public function getSupportedFields() : array {
        if ( empty( $this->supportedFields ) ) {
            $_fields = (require PLUGIN_DIR_PATH . 'includes/fields.php');
            $this->supportedFields = $_fields;
        }
        return $this->supportedFields;
    }

    /**
     * Get supported fields slug
     * @return array
     */
    public function getDefaultFields() : array {
        $data = [];
        foreach ( $this->getSupportedFields() as $field ) {
            $data[$field['slug']] = true;
        }
        return $data;
    }

    /**
     * Deletes the settings from the database.
     *
     * @return bool
     */
    public function deleteSettings() : bool {
        return delete_option( $this->optionName );
    }

    /**
     * Sanitize fields
     *
     * @param array $data
     *
     * @return array
     */
    public function sanitizeFields( array $data ) : array {
        $sanitized_data = [];
        foreach ( $data as $key => $value ) {
            $sanitized_data[sanitize_text_field( $key )] = filter_var( $value, FILTER_VALIDATE_BOOLEAN );
        }
        return $sanitized_data;
    }

    /**
     * Sanitizes settings
     *
     * @param array $input
     *
     * @return array Sanitized associative array
     */
    public function sanitizeSettings( array $input ) : array {
        $sanitized = [];
        foreach ( $input as $key => $value ) {
            $key = sanitize_text_field( $key );
            // Skip non exist option
            if ( !array_key_exists( $key, $this->defaultOptions ) ) {
                continue;
            }
            if ( $key === 'fields' ) {
                $sanitized[$key] = $this->sanitizeFields( ( is_array( $value ) ? $value : [] ) );
            } else {
                $sanitized[$key] = sanitize_text_field( $value );
            }
        }
        return $sanitized;
    }

    /**
     * Updates the settings in the database.
     *
     * @param array $settings Associative array with the settings to update.
     *
     * @return bool True if the settings were updated, false otherwise.
     */
    public function updateSettings( array $settings ) : bool {
        $updated = update_option( $this->optionName, $this->sanitizeSettings( $settings ) );
        if ( $updated ) {
            $this->attributes = [];
        }
        return $updated;
    }

    /**
     * Get all settings
     * @return array
     */
    public function getSettings() : array {
        if ( empty( $this->attributes ) ) {
            $options = get_option( $this->optionName, $this->defaultOptions );
            $attributes = array_merge( $this->defaultOptions, ( is_array( $options ) ? $options : [] ) );
            $attributes['fields'] = array_merge( $this->getDefaultFields(), $attributes['fields'] );
            $this->attributes = array_map( static function ( $item ) {
                if ( is_string( $item ) ) {
                    return trim( $item );
                }
                return $item;
            }, $attributes );
        }
        return $this->attributes;
    }

    /**
     * Find field by slug
     * @param string $slug
     *
     * @return array
     */
    public function findFieldBySlug( string $slug ) : ?array {
        $settingsSupportedFields = $this->getSupportedFields();
        foreach ( $settingsSupportedFields as $field ) {
            if ( $field['slug'] === $slug ) {
                return (array) $field;
            }
        }
        return null;
    }

    /**
     * Get fields info
     * @return array
     */
    public function getFieldsInfo() : array {
        if ( empty( $this->fieldsInfo ) ) {
            $settings = $this->getSettings();
            foreach ( $settings['fields'] as $key => $isEnabled ) {
                $find = $this->findFieldBySlug( $key );
                if ( isset( $find['slug'] ) ) {
                    $this->fieldsInfo[] = array_merge( $find, [
                        'isEnabled' => $isEnabled,
                    ] );
                }
            }
        }
        return $this->fieldsInfo;
    }

}
