<?php
/**
 * FluentC API Key Validator.
 *
 * This class handles the validation of FluentC API keys to prevent errors
 * when the key is invalid or the service is unreachable.
 *
 * @package FluentCPlugin
 * @author  FluentC <wp@fluentc.io>
 */

namespace FluentC\Services;

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

/**
 * API Key Validator class
 *
 * @since 2.4.1
 */
class API_Key_Validator {
    /**
     * FluentC connection class
     *
     * @var Connect
     */
    protected $fluentc_connect;

    /**
     * FluentC cache class
     *
     * @var Cache
     */
    protected $fluentc_cache;

    /**
     * Constructor.
     *
     * @since 2.5
     */
    public function __construct() {
        $this->fluentc_connect = new Connect();
        $this->fluentc_cache = new Cache();
    }

    /**
     * Validates an API key by making a test request to the FluentC API
     *
     * @param string $api_key The API key to validate
     * @return array Result with status and message
     */
    public function validate_api_key($api_key) {
        // Return early if API key is empty
        if (empty($api_key)) {
            return [
                'success' => false,
                'message' => 'API key cannot be empty.',
                'valid' => false
            ];
        }

        // Check if validation result is cached
        $cached = $this->fluentc_cache->get('api_key_validation_' . md5($api_key), 'settings');
        if ($cached !== false) {
            return $cached;
        }

        // Try to fetch widget options to validate the key
        try {
            $widget_options = $this->fluentc_connect->fetch_widget_options($api_key);

            // Check if we got a valid response
            if (!$widget_options || !is_object($widget_options) || !isset($widget_options->data) || !isset($widget_options->data->fetchSiteOptions)) {
                $result = [
                    'success' => false,
                    'message' => 'Invalid API key or FluentC service returned an unexpected response.',
                    'valid' => false,
                    'response' => $widget_options
                ];
            } else {
                // API key is valid
                $result = [
                    'success' => true,
                    'message' => 'API key validated successfully.',
                    'valid' => true,
                    // Store minimal needed info to avoid large cache entries
                    'languages' => isset($widget_options->data->fetchSiteOptions->languages) ? 
                                  $widget_options->data->fetchSiteOptions->languages : [],
                    'source_language' => isset($widget_options->data->fetchSiteOptions->sourceLanguage) ? 
                                        $widget_options->data->fetchSiteOptions->sourceLanguage : '',
                    'appearance' => isset($widget_options->data->fetchSiteOptions->appearance) ? 
                                   $widget_options->data->fetchSiteOptions->appearance : 'float'
                ];
            }
        } catch (\Exception $e) {
            // Log the exception
            error_log('FluentC API Key Validation Error: ' . $e->getMessage());
            
            $result = [
                'success' => false,
                'message' => 'Error validating API key: ' . $e->getMessage(),
                'valid' => false,
                'error' => $e->getMessage()
            ];
        }

        // Cache the result for 1 hour (can be adjusted as needed)
        $this->fluentc_cache->set('api_key_validation_' . md5($api_key), $result, 'settings', HOUR_IN_SECONDS);

        return $result;
    }

    /**
     * Check if an API key is valid
     *
     * @param string $api_key The API key to check
     * @return bool True if the API key is valid
     */
    public function is_valid_api_key($api_key = null) {
        // If no API key is provided, get it from options
        if ($api_key === null) {
            $api_key = get_option('fluentc_api_key', '');
        }

        if (empty($api_key)) {
            return false;
        }

        $validation = $this->validate_api_key($api_key);
        return $validation['valid'] === true;
    }

    /**
     * Get available languages for a validated API key
     *
     * @param string $api_key The API key 
     * @return array Available languages or empty array if validation fails
     */
    public function get_available_languages($api_key = null) {
        // If no API key is provided, get it from options
        if ($api_key === null) {
            $api_key = get_option('fluentc_api_key', '');
        }

        if (empty($api_key)) {
            return [];
        }

        $validation = $this->validate_api_key($api_key);
        return isset($validation['languages']) ? $validation['languages'] : [];
    }

    /**
     * Get source language for a validated API key
     *
     * @param string $api_key The API key
     * @return string Source language or empty string if validation fails
     */
    public function get_source_language($api_key = null) {
        // If no API key is provided, get it from options
        if ($api_key === null) {
            $api_key = get_option('fluentc_api_key', '');
        }

        if (empty($api_key)) {
            return '';
        }

        $validation = $this->validate_api_key($api_key);
        return isset($validation['source_language']) ? $validation['source_language'] : '';
    }

    /**
     * Clears the API key validation cache
     *
     * @param string $api_key The API key
     * @return bool Success status
     */
    public function clear_validation_cache($api_key = null) {
        // If no API key is provided, get it from options
        if ($api_key === null) {
            $api_key = get_option('fluentc_api_key', '');
        }

        if (empty($api_key)) {
            return false;
        }

        return $this->fluentc_cache->delete('api_key_validation_' . md5($api_key), 'settings');
    }

    /**
     * Save API key with validation
     *
     * @param string $api_key The API key to save
     * @return array Result with status and message
     */
    public function save_api_key_with_validation($api_key) {
        // Validate the API key first
        $validation = $this->validate_api_key($api_key);
        
        if ($validation['valid']) {
            // Only save if validation passed
            update_option('fluentc_api_key', $api_key);
            update_option('fluentc_api_key_validated', true);
            update_option('fluentc_api_key_validation_time', current_time('timestamp'));
            
            // Set a flag to flush rewrite rules
            update_option('fluentc_need_flush_rewrite', true);
            
            return [
                'success' => true,
                'message' => 'API key validated and saved successfully.',
                'validation' => $validation
            ];
        } else {
            // Save the invalid key but mark it as invalid
            update_option('fluentc_api_key', $api_key);
            update_option('fluentc_api_key_validated', false);
            update_option('fluentc_api_key_validation_message', $validation['message']);
            
            return [
                'success' => false,
                'message' => 'API key saved but failed validation: ' . $validation['message'],
                'validation' => $validation
            ];
        }
    }

    /**
     * Check if a validated API key exists
     *
     * @return bool True if a validated API key exists
     */
    public function has_valid_api_key() {
        $api_key = get_option('fluentc_api_key', '');
        $api_key_validated = get_option('fluentc_api_key_validated', false);
        
        if (empty($api_key)) {
            return false;
        }

        // If the key has been validated before, we can trust that check
        if ($api_key_validated) {
            return true;
        }

        // Otherwise validate it now
        return $this->is_valid_api_key($api_key);
    }
}