<?php
namespace IntentDeep\VirtualFiles\Core;

use WP_Post;

/**
 * Handles WordPress options management for Virtual Files
 */
class Option {
    private const OPTION_NAME = 'intentdeep_vf_settings';
    private const ERROR_PREFIX = 'Virtual Files';

    /**
     * Gets all plugin options
     *
     * @return array|false Plugin options or false if not set
     */
    public static function all() {
        return get_option(self::OPTION_NAME);
    }

    /**
     * Gets a specific option value
     *
     * @param string $key Option key to retrieve
     * @return mixed|null Option value or null if not found
     */
    public static function get(string $key) {
        try {
            $options = static::all();
            
            if (!is_array($options)) {
                return null;
            }

            return $options[$key] ?? null;
        } catch (\Exception $e) {
            intentdeep_vf_log(sprintf("%s Option Error: %s", self::ERROR_PREFIX, $e->getMessage()));
            return null;
        }
    }

    /**
     * Checks if an option exists and is not empty
     *
     * @param string $key Option key to check
     * @return bool True if option exists and has value
     */
    public static function check(string $key): bool {
        try {
            $options = static::all();
            
            if (!is_array($options)) {
                return false;
            }

            return isset($options[$key]) && !empty($options[$key]);
        } catch (\Exception $e) {
            intentdeep_vf_log(sprintf("%s Option Error: %s", self::ERROR_PREFIX, $e->getMessage()));
            return false;
        }
    }

    /**
     * Validates if an option matches a specific value
     *
     * @param string $option Option key to check
     * @param mixed $value Value to compare against
     * @return bool True if option exists and matches value
     */
    public static function valid(string $option, $value): bool {
        try {
            return static::check($option) && static::get($option) == $value;
        } catch (\Exception $e) {
            intentdeep_vf_log(sprintf("%s Option Error: %s", self::ERROR_PREFIX, $e->getMessage()));
            return false;
        }
    }

    /**
     * Gets post meta value for current post
     *
     * @param string $key Meta key to retrieve
     * @return mixed Meta value or empty string if not found
     */
    public static function post_meta(string $key) {
        try {
            global $post;

            if (!$post instanceof WP_Post) {
                throw new \RuntimeException('No post object available');
            }

            return get_post_meta($post->ID, $key, true);
        } catch (\Exception $e) {
            intentdeep_vf_log(sprintf("%s Option Error: %s", self::ERROR_PREFIX, $e->getMessage()));
            return '';
        }
    }

    /**
     * Updates a plugin option
     *
     * @param string $key Option key to update
     * @param mixed $value New value
     * @return bool Success status
     */
    public static function update(string $key, $value): bool {
        try {
            $options = static::all() ?: [];
            
            if (!is_array($options)) {
                $options = [];
            }

            $options[$key] = $value;
            return update_option(self::OPTION_NAME, $options);
        } catch (\Exception $e) {
            intentdeep_vf_log(sprintf("%s Option Error: %s", self::ERROR_PREFIX, $e->getMessage()));
            return false;
        }
    }

    /**
     * Deletes a plugin option
     *
     * @param string $key Option key to delete
     * @return bool Success status
     */
    public static function delete(string $key): bool {
        try {
            $options = static::all();
            
            if (!is_array($options) || !isset($options[$key])) {
                return false;
            }

            unset($options[$key]);
            return update_option(self::OPTION_NAME, $options);
        } catch (\Exception $e) {
            intentdeep_vf_log(sprintf("%s Option Error: %s", self::ERROR_PREFIX, $e->getMessage()));
            return false;
        }
    }

    /**
     * Normalizes option types to ensure they are of the correct data type.
     *
     * @param array $options Array of options to normalize.
     * @return array The normalized array of options.
     */
    public static function normalize_option_types(array $options): array {
        // Ensure boolean types with default values
        $boolean_fields = [
            'routing_enabled' => true,
            'remove_settings_on_uninstall' => false,
            'advanced_editor' => false,
            'cache_enabled' => false,
            'analytics_enabled' => false,
        ];

        // Set default values for boolean fields if they don't exist
        foreach ($boolean_fields as $field => $default) {
            if (!isset($options[$field])) {
                $options[$field] = $default;
            } else {
                $options[$field] = filter_var($options[$field], FILTER_VALIDATE_BOOLEAN);
            }
        }

        // Ensure arrays are properly formatted
        $array_fields = [
            'allowed_extensions' => ['txt', 'md', 'json'],
            'extended_extensions' => ['xml', 'rss', 'csv', 'yml', 'yaml', 'log'],
        ];

        foreach ($array_fields as $field => $default) {
            if (!isset($options[$field])) {
                $options[$field] = $default;
            } else if (!is_array($options[$field])) {
                $options[$field] = $default;
            }
        }

        // Ensure numeric fields
        $numeric_fields = [
            'max_files_pro' => -1,
        ];

        foreach ($numeric_fields as $field => $default) {
            if (!isset($options[$field])) {
                $options[$field] = $default;
            } else {
                $options[$field] = intval($options[$field]);
            }
        }

        return $options;
    }
}