<?php
/**
 * Google Sheets Authentication Handler
 *
 * Handles OAuth token management and Google Sheets API authentication
 *
 * @package HVAC_Community_Events
 * @subpackage Google_Sheets_Integration
 */

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

class HVAC_Google_Sheets_Auth {
    
    private $client_id;
    private $client_secret;
    private $refresh_token;
    private $redirect_uri;
    private $access_token;
    private $token_expiry;
    private $folder_id;
    private $last_error = null;
    
    // Google API endpoints
    private $auth_url = 'https://accounts.google.com/o/oauth2/v2/auth';
    private $token_url = 'https://oauth2.googleapis.com/token';
    private $sheets_api_url = 'https://sheets.googleapis.com/v4/spreadsheets';
    private $drive_api_url = 'https://www.googleapis.com/drive/v3/files';
    
    public function __construct() {
        // Load configuration if available
        $config_file = plugin_dir_path(__FILE__) . 'google-sheets-config.php';
        if (file_exists($config_file)) {
            require_once $config_file;
            
            $this->client_id = defined('GOOGLE_SHEETS_CLIENT_ID') ? GOOGLE_SHEETS_CLIENT_ID : '';
            $this->client_secret = defined('GOOGLE_SHEETS_CLIENT_SECRET') ? GOOGLE_SHEETS_CLIENT_SECRET : '';
            $this->refresh_token = defined('GOOGLE_SHEETS_REFRESH_TOKEN') ? GOOGLE_SHEETS_REFRESH_TOKEN : '';
            $this->redirect_uri = defined('GOOGLE_SHEETS_REDIRECT_URI') ? GOOGLE_SHEETS_REDIRECT_URI : 'http://localhost:8080/callback';
            $this->folder_id = defined('GOOGLE_SHEETS_FOLDER_ID') ? GOOGLE_SHEETS_FOLDER_ID : '';
        }
        
        // Load stored access token from WordPress options
        $this->load_access_token();
        
        // Register callback handler - use template_redirect to catch it before page rendering
        add_action('template_redirect', array($this, 'handle_oauth_callback'));
    }
    
    /**
     * Generate authorization URL for initial setup
     */
    public function get_authorization_url() {
        $params = array(
            'client_id' => $this->client_id,
            'redirect_uri' => $this->redirect_uri,
            'scope' => 'https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive.file',
            'response_type' => 'code',
            'access_type' => 'offline',
            'prompt' => 'consent',
            'include_granted_scopes' => 'true'
        );
        
        return $this->auth_url . '?' . http_build_query($params);
    }
    
    /**
     * Exchange authorization code for tokens
     */
    public function exchange_code_for_tokens($auth_code) {
        $params = array(
            'client_id' => $this->client_id,
            'client_secret' => $this->client_secret,
            'redirect_uri' => $this->redirect_uri,
            'grant_type' => 'authorization_code',
            'code' => $auth_code
        );
        
        if (class_exists('HVAC_Logger')) {
            HVAC_Logger::info("Token exchange request params: " . json_encode(array(
                'client_id' => substr($this->client_id, 0, 20) . '...',
                'redirect_uri' => $this->redirect_uri,
                'grant_type' => 'authorization_code',
                'code' => substr($auth_code, 0, 20) . '...'
            )), 'GoogleSheets');
        }
        
        $response = wp_remote_post($this->token_url, array(
            'body' => $params,
            'headers' => array(
                'Content-Type' => 'application/x-www-form-urlencoded'
            ),
            'timeout' => 30
        ));
        
        if (is_wp_error($response)) {
            $this->log_error('Failed to exchange code: ' . $response->get_error_message());
            return false;
        }
        
        $response_code = wp_remote_retrieve_response_code($response);
        $body = wp_remote_retrieve_body($response);
        
        if (class_exists('HVAC_Logger')) {
            HVAC_Logger::info("Token exchange response code: " . $response_code, 'GoogleSheets');
            HVAC_Logger::info("Token exchange response body: " . $body, 'GoogleSheets');
        }
        
        $data = json_decode($body, true);
        
        if (isset($data['access_token'])) {
            $this->access_token = $data['access_token'];
            if (isset($data['refresh_token'])) {
                $this->refresh_token = $data['refresh_token'];
            }
            $this->token_expiry = time() + (int)$data['expires_in'];
            
            if (class_exists('HVAC_Logger')) {
                HVAC_Logger::info("Successfully received tokens. Access token: " . substr($this->access_token, 0, 20) . "...", 'GoogleSheets');
                HVAC_Logger::info("Refresh token: " . ($this->refresh_token ? 'RECEIVED' : 'NOT RECEIVED'), 'GoogleSheets');
                HVAC_Logger::info("Token expires at: " . date('Y-m-d H:i:s', $this->token_expiry), 'GoogleSheets');
            }
            
            // Save tokens
            $this->save_tokens();
            
            return true;
        }
        
        $this->log_error('Invalid token response (status ' . $response_code . '): ' . $body);
        return false;
    }
    
    /**
     * Get valid access token (refresh if needed)
     */
    public function get_access_token() {
        // Check if token is expired or will expire in next 5 minutes
        if ($this->token_expiry && ($this->token_expiry - 300) < time()) {
            $this->refresh_access_token();
        }
        
        return $this->access_token;
    }
    
    /**
     * Refresh access token using refresh token
     */
    private function refresh_access_token() {
        if (empty($this->refresh_token)) {
            $this->log_error('No refresh token available');
            return false;
        }
        
        $params = array(
            'client_id' => $this->client_id,
            'client_secret' => $this->client_secret,
            'refresh_token' => $this->refresh_token,
            'grant_type' => 'refresh_token'
        );
        
        $response = wp_remote_post($this->token_url, array(
            'body' => $params,
            'headers' => array(
                'Content-Type' => 'application/x-www-form-urlencoded'
            )
        ));
        
        if (is_wp_error($response)) {
            $this->log_error('Failed to refresh token: ' . $response->get_error_message());
            return false;
        }
        
        $body = wp_remote_retrieve_body($response);
        $data = json_decode($body, true);
        
        if (isset($data['access_token'])) {
            $this->access_token = $data['access_token'];
            $this->token_expiry = time() + $data['expires_in'];
            
            // Update refresh token if provided
            if (isset($data['refresh_token'])) {
                $this->refresh_token = $data['refresh_token'];
            }
            
            // Save updated tokens
            $this->save_tokens();
            
            return true;
        }
        
        $this->log_error('Failed to refresh token: ' . $body);
        return false;
    }
    
    /**
     * Make authenticated API request to Google Sheets/Drive
     */
    public function make_api_request($method, $endpoint, $data = null, $api_type = 'sheets') {
        $access_token = $this->get_access_token();
        if (!$access_token) {
            throw new Exception('No valid access token available');
        }
        
        $base_url = ($api_type === 'drive') ? $this->drive_api_url : $this->sheets_api_url;
        $url = $base_url . $endpoint;
        
        // Handle valueInputOption as query parameter for Sheets API
        if ($data && isset($data['valueInputOption'])) {
            $url .= '?valueInputOption=' . urlencode($data['valueInputOption']);
            unset($data['valueInputOption']); // Remove from body data
        }
        
        $args = array(
            'method' => $method,
            'headers' => array(
                'Authorization' => 'Bearer ' . $access_token,
                'Content-Type' => 'application/json'
            ),
            'timeout' => 30
        );
        
        if ($data && in_array($method, ['POST', 'PUT', 'PATCH'])) {
            $args['body'] = json_encode($data);
        }
        
        $response = wp_remote_request($url, $args);
        
        if (is_wp_error($response)) {
            throw new Exception('API request failed: ' . $response->get_error_message());
        }
        
        $response_code = wp_remote_retrieve_response_code($response);
        $body = wp_remote_retrieve_body($response);
        
        if ($response_code >= 400) {
            $error_data = json_decode($body, true);
            $error_message = isset($error_data['error']['message']) ? $error_data['error']['message'] : 'Unknown API error';
            throw new Exception("API error {$response_code}: {$error_message}");
        }
        
        return json_decode($body, true);
    }
    
    /**
     * Test API connection
     */
    public function test_connection() {
        try {
            // Try to create a test spreadsheet in the designated folder
            $spreadsheet_data = array(
                'properties' => array(
                    'title' => 'HVAC Test Connection - ' . date('Y-m-d H:i:s')
                )
            );
            
            $response = $this->make_api_request('POST', '', $spreadsheet_data);
            
            if (isset($response['spreadsheetId'])) {
                // Move to designated folder if specified
                if ($this->folder_id) {
                    $this->make_api_request(
                        'PATCH', 
                        '/' . $response['spreadsheetId'] . '?addParents=' . $this->folder_id,
                        null,
                        'drive'
                    );
                }
                
                // Delete test spreadsheet
                $this->make_api_request(
                    'DELETE',
                    '/' . $response['spreadsheetId'],
                    null,
                    'drive'
                );
                
                return array('success' => true, 'message' => 'Connection successful');
            }
            
            return array('success' => false, 'message' => 'Unexpected response format');
            
        } catch (Exception $e) {
            return array('success' => false, 'message' => $e->getMessage());
        }
    }
    
    /**
     * Load access token from WordPress options
     */
    private function load_access_token() {
        $token_data = get_option('hvac_google_sheets_tokens', array());
        
        if (!empty($token_data)) {
            $this->access_token = $token_data['access_token'] ?? '';
            $this->refresh_token = $token_data['refresh_token'] ?? $this->refresh_token;
            $this->token_expiry = $token_data['expires_at'] ?? 0;
        }
    }
    
    /**
     * Save tokens to WordPress options
     */
    private function save_tokens() {
        $token_data = array(
            'access_token' => $this->access_token,
            'refresh_token' => $this->refresh_token,
            'expires_at' => $this->token_expiry,
            'created_at' => time()
        );
        
        $result = update_option('hvac_google_sheets_tokens', $token_data);
        
        if (class_exists('HVAC_Logger')) {
            HVAC_Logger::info("Saving tokens to database: " . ($result ? 'SUCCESS' : 'FAILED'), 'GoogleSheets');
            HVAC_Logger::info("Token data: " . json_encode(array(
                'access_token' => substr($this->access_token, 0, 20) . '...',
                'refresh_token' => $this->refresh_token ? 'SET' : 'NOT SET',
                'expires_at' => date('Y-m-d H:i:s', $this->token_expiry),
                'created_at' => date('Y-m-d H:i:s', time())
            )), 'GoogleSheets');
        }
    }
    
    /**
     * Clear stored tokens
     */
    public function clear_tokens() {
        delete_option('hvac_google_sheets_tokens');
        $this->access_token = '';
        $this->refresh_token = '';
        $this->token_expiry = 0;
    }
    
    /**
     * Check if we have valid credentials
     */
    public function has_valid_credentials() {
        return !empty($this->client_id) && !empty($this->client_secret);
    }
    
    /**
     * Check if we have an access token
     */
    public function is_authenticated() {
        return !empty($this->access_token) || !empty($this->refresh_token);
    }
    
    /**
     * Get last error message
     */
    public function get_last_error() {
        return $this->last_error;
    }
    
    /**
     * Log error message
     */
    private function log_error($message) {
        $this->last_error = $message;
        if (class_exists('HVAC_Logger')) {
            HVAC_Logger::error("Google Sheets Auth: {$message}", 'GoogleSheets');
        }
        error_log("HVAC Google Sheets Auth Error: {$message}");
    }
    
    /**
     * Get configuration status
     */
    public function get_config_status() {
        return array(
            'has_credentials' => $this->has_valid_credentials(),
            'is_authenticated' => $this->is_authenticated(),
            'client_id' => !empty($this->client_id) ? substr($this->client_id, 0, 10) . '...' : '',
            'has_refresh_token' => !empty($this->refresh_token),
            'token_expires' => $this->token_expiry ? date('Y-m-d H:i:s', $this->token_expiry) : 'Unknown',
            'folder_id' => $this->folder_id
        );
    }
    
    /**
     * Handle OAuth callback from Google
     */
    public function handle_oauth_callback() {
        // Debug: Log all OAuth callback attempts
        if (isset($_GET['code']) && isset($_GET['scope'])) {
            if (class_exists('HVAC_Logger')) {
                HVAC_Logger::info("OAuth callback detected - URI: " . $_SERVER['REQUEST_URI'], 'GoogleSheets');
                HVAC_Logger::info("OAuth callback - code param: " . substr($_GET['code'], 0, 20) . "...", 'GoogleSheets');
            }
            error_log("HVAC Google OAuth callback detected - URI: " . $_SERVER['REQUEST_URI']);
            error_log("HVAC Google OAuth callback - code: " . substr($_GET['code'], 0, 20) . "...");
        }
        
        // Check if this is an OAuth callback request to the Google Sheets page
        if (isset($_GET['code']) && isset($_GET['scope']) && 
            (strpos($_SERVER['REQUEST_URI'], '/google-sheets/') !== false || 
             strpos($_SERVER['REQUEST_URI'], 'google-sheets') !== false)) {
            
            $auth_code = sanitize_text_field($_GET['code']);
            
            if (class_exists('HVAC_Logger')) {
                HVAC_Logger::info("Processing OAuth callback with code: " . substr($auth_code, 0, 20) . "...", 'GoogleSheets');
                HVAC_Logger::info("Current redirect URI: " . $this->redirect_uri, 'GoogleSheets');
            }
            
            // Exchange the authorization code for tokens
            $success = $this->exchange_code_for_tokens($auth_code);
            
            if (class_exists('HVAC_Logger')) {
                HVAC_Logger::info("Token exchange result: " . ($success ? 'SUCCESS' : 'FAILED'), 'GoogleSheets');
                if (!$success) {
                    HVAC_Logger::error("Token exchange error: " . $this->get_last_error(), 'GoogleSheets');
                }
            }
            
            if ($success) {
                // Redirect to Google Sheets admin page with success message (clean URL)
                wp_redirect(add_query_arg(array(
                    'auth_success' => '1'
                ), home_url('/google-sheets/')));
                exit;
            } else {
                // Redirect to Google Sheets admin page with error message
                wp_redirect(add_query_arg(array(
                    'auth_error' => '1',
                    'message' => urlencode($this->get_last_error())
                ), home_url('/google-sheets/')));
                exit;
            }
        }
    }
}