<?php
/**
 * Config Controller V1
 *
 * @package ZenoChatbot\Http\Controller\Api\V1
 */

namespace ZenoChatbot\Http\Controller\Api\V1;

use ZenoChatbot\Framework\Foundation\Application;
use ZenoChatbot\Helper\Settings;
use ZenoChatbot\Services\LLMService\LLMService;

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Configuration API controller
 */
class ConfigController {

    /**
     * Application instance
     *
     * @var Application
     */
    protected $app;

    /**
     * LLM service
     *
     * @var LLMService
     */
    private $llmService;

    /**
     * Constructor
     *
     * @param Application $app
     * @param LLMService $llmService
     */
    public function __construct(Application $app, LLMService $llmService) {
        $this->app = $app;
        $this->llmService = $llmService;
    }

    /**
     * Get configuration
     *
     * @param \WP_REST_Request $request
     * @return array
     */
    public function get(\WP_REST_Request $request) {
        try {
            // Using Settings Helper for dynamic settings
            $config = [
                'llm_provider' => Settings::get('llm.provider', 'openai'),
                'widget_enabled' => Settings::get('widget.enabled', true),
                'chat_widget_position' => Settings::get('widget.position', 'bottom-right'),
                'store_chat_history' => Settings::get('chat.store_history', false),
                'indexed_post_types' => Settings::get('content.indexed_post_types', ['post', 'page']),
                'max_context_length' => Settings::get('llm.max_context_length', 4000),

                'providers' => [
                    'openai' => [
                        'enabled' => Settings::get('llm.providers.openai.enabled', false),
                        'model' => Settings::get('llm.providers.openai.model', 'gpt-3.5-turbo'),
                        'api_key' => Settings::get('llm.providers.openai.api_key', ''),
                    ],
                    'claude' => [
                        'enabled' => Settings::get('llm.providers.claude.enabled', false),
                        'model' => Settings::get('llm.providers.claude.model', 'claude-3-sonnet'),
                        'api_key' => Settings::get('llm.providers.claude.api_key', ''),
                    ],
                    'gemini' => [
                        'enabled' => Settings::get('llm.providers.gemini.enabled', false),
                        'model' => Settings::get('llm.providers.gemini.model', 'gemini-pro'),
                        'api_key' => Settings::get('llm.providers.gemini.api_key', ''),
                    ],
                ]
            ];

            // Don't expose actual API keys, just show if they're configured
            return [
                'success' => true,
                'data' => $config
            ];

        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Failed to retrieve configuration',
                'error' => $e->getMessage(),
                'status' => 500
            ];
        }
    }

    /**
     * Update configuration
     *
     * @param \WP_REST_Request $request
     * @return array
     */
    public function update(\WP_REST_Request $request) {
        $data = $request->get_json_params();

        if (empty($data)) {
            return [
                'success' => false,
                'message' => 'No configuration data provided',
                'status' => 400
            ];
        }

        try {
            // Validate and sanitize each field
            $validated_data = $this->validateConfigData($data);

            if (!$validated_data['valid']) {
                return [
                    'success' => false,
                    'message' => 'Validation failed',
                    'errors' => $validated_data['errors'],
                    'status' => 400
                ];
            }

            // Update configuration using Settings Helper
            foreach ($validated_data['data'] as $key => $value) {
                if (strpos($key, 'api_key_') === 0) {
                    // Extract provider from key (api_key_openai -> openai)
                    $provider = substr($key, 8);
                    Settings::update("llm.providers.{$provider}.api_key", $value);
                } else {
                    // Map old keys to new Settings structure
                    $settingsKey = static::mapConfigKeyToSettings($key);
                    if ($settingsKey) {
                        Settings::update($settingsKey, $value);
                    }
                }
            }

            return [
                'success' => true,
                'message' => 'Configuration updated successfully'
            ];

        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Failed to update configuration',
                'error' => $e->getMessage(),
                'status' => 500
            ];
        }
    }

    /**
     * Test LLM connection
     *
     * @param \WP_REST_Request $request
     * @return array
     */
    public function testConnection(\WP_REST_Request $request) {
        try {
            $result = $this->llmService->testConnection();

            return [
                'success' => $result['success'],
                'message' => $result['message'],
                'provider' => $result['provider'] ?? null
            ];

        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Connection test failed',
                'error' => $e->getMessage(),
                'status' => 500
            ];
        }
    }

    /**
     * Reset plugin configuration
     *
     * @param \WP_REST_Request $request
     * @return array
     */
    public function reset(\WP_REST_Request $request) {
        $confirm = sanitize_text_field((string) $request->get_param('confirm'));

        if ($confirm !== 'yes') {
            return [
                'success' => false,
                'message' => 'Reset confirmation required',
                'status' => 400
            ];
        }

        try {
            // Reset all configuration - commented out for now
            // Config::reset();

            return [
                'success' => true,
                'message' => 'Plugin configuration reset successfully (static mode)'
            ];

        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => 'Failed to reset configuration',
                'error' => $e->getMessage(),
                'status' => 500
            ];
        }
    }

    /**
     * Validate configuration data
     *
     * @param array $data
     * @return array
     */
    private function validateConfigData($data) {
        $validated = [];
        $errors = [];

        // Validate LLM provider
        if (isset($data['llm_provider'])) {
            $provider = Security::sanitizeText($data['llm_provider']);
            if (in_array($provider, ['openai', 'claude', 'gemini'])) {
                $validated['llm_provider'] = $provider;
            } else {
                $errors['llm_provider'] = 'Invalid LLM provider';
            }
        }

        // Validate provider-specific API keys
        $providers = ['openai', 'claude', 'gemini'];
        foreach ($providers as $provider) {
            $key_field = "api_key_{$provider}";
            if (isset($data[$key_field])) {
                $api_key = Security::sanitizeText($data[$key_field]);
                if (Validator::isValidApiKeyFormat($api_key)) {
                    $validated[$key_field] = $api_key;
                } else {
                    $errors[$key_field] = "Invalid {$provider} API key format";
                }
            }
        }

        // Validate boolean fields
        $boolean_fields = ['widget_enabled', 'store_chat_history'];
        foreach ($boolean_fields as $field) {
            if (isset($data[$field])) {
                $validated[$field] = (bool) $data[$field];
            }
        }

        // Validate widget position
        if (isset($data['chat_widget_position'])) {
            $position = Security::sanitizeText($data['chat_widget_position']);
            if (in_array($position, ['bottom-right', 'bottom-left'])) {
                $validated['chat_widget_position'] = $position;
            } else {
                $errors['chat_widget_position'] = 'Invalid widget position';
            }
        }

        // Validate post types
        if (isset($data['indexed_post_types']) && is_array($data['indexed_post_types'])) {
            $post_types = array_map([Security::class, 'sanitizeText'], $data['indexed_post_types']);
            $validated['indexed_post_types'] = $post_types;
        }

        // Validate max context length
        if (isset($data['max_context_length'])) {
            $length = (int) $data['max_context_length'];
            if ($length >= 1000 && $length <= 8000) {
                $validated['max_context_length'] = $length;
            } else {
                $errors['max_context_length'] = 'Context length must be between 1000 and 8000';
            }
        }

        return [
            'valid' => empty($errors),
            'data' => $validated,
            'errors' => $errors
        ];
    }

    /**
     * Map old config keys to new Settings structure
     *
     * @param string $key
     * @return string|null
     */
    protected static function mapConfigKeyToSettings(string $key): ?string
    {
        $mapping = [
            'llm_provider' => 'llm.provider',
            'widget_enabled' => 'widget.enabled',
            'chat_widget_position' => 'widget.position',
            'store_chat_history' => 'chat.store_history',
            'indexed_post_types' => 'content.indexed_post_types',
            'max_context_length' => 'llm.max_context_length',
        ];

        return $mapping[$key] ?? null;
    }
}
