<?php
if (!defined('ABSPATH')) exit;

class GSHFJF_JetForm_GoogleSheet
{

    private $spreadsheet;
    private $worksheet;

    /**
     * GET GOOGLE CREDS
     *
     * @since 1.0.0
     */

    private static function creds()
    {
        return is_multisite()
            ? get_site_option('gshfjf_jetform_free_api_creds')
            : get_option('gshfjf_jetform_free_api_creds');
    }

    /**
     * GENERIC HTTP REQUEST
     *
     * @since 1.0.0
     */

    // private function request($method, $url, $body = null)
    // {

    //     $args = [
    //         'method'  => $method,
    //         'headers' => ['Content-Type' => 'application/json']
    //     ];

    //     if ($body) {
    //         $args['body'] = wp_json_encode($body);
    //     }

    //     return wp_remote_request($url, $args);
    // }

    /**
     * EXCHANGE AUTH CODE
     *
     * @since 1.0.0
     */

    public static function preauth($code)
    {
        try {
            $creds = self::creds();
            if (!$creds) return;

            $response = wp_remote_post(
                'https://oauth2.googleapis.com/token',
                [
                    'body' => [
                        'code'          => $code,
                        'client_id'     => $creds['client_id_web'],
                        'client_secret' => $creds['client_secret_web'],
                        'redirect_uri'  => 'https://oauth.gsheetconnector.com/auth-api.php',
                        'grant_type'    => 'authorization_code'
                    ]
                ]
            );
            if (is_wp_error($response)) {
                update_option('gshfjf_jetform_verify', 'invalid-auth');
                return;
            }
            $body = json_decode(wp_remote_retrieve_body($response), true);
            if (!is_array($body)) {
                $body = [];
            }

            // For Logging Error In Debug Log. In Case Auth Fails.
            if (!empty($body['error'])) {
                $status = 'invalid-auth';

                GSHFJF_JetForm_Connector_Utility::gshfjf_debug_log(
                    '[Auth API Error] ' . $body['error'] .
                        (!empty($body['error_description']) ? ' - ' . $body['error_description'] : '')
                );

                $no_token = true;
            }

            $status = 'valid';
            $no_token = false;

            if (empty($body['access_token'])) {
                $no_token = true;
            }

            // TEMP store token
            $access_token = !empty($body['access_token']) ? $body['access_token'] : '';

            // STEP 2 — VERIFY PERMISSIONS
            if (!empty($access_token)) {
                $check = wp_remote_get(
                    'https://www.googleapis.com/oauth2/v2/userinfo',
                    [
                        'headers' => [
                            'Authorization' => 'Bearer ' . $access_token
                        ]
                    ]
                );
                if (is_wp_error($check)) {
                    $status = 'invalid-auth';
                }
                $check_body = json_decode(wp_remote_retrieve_body($check), true);
                if (!is_array($check_body)) {
                    $status = 'invalid-auth';
                }

                // If email missing → permissions issue
                if (empty($check_body['email'])) {
                    $status = 'invalid-auth';
                }

                // STEP 3 — CHECK SCOPES
                if (!empty($body['scope'])) {
                    $scopes = explode(' ', $body['scope']);

                    $has_drive = false;

                    foreach ($scopes as $scope) {
                        if (
                            $scope === 'https://www.googleapis.com/auth/drive' ||
                            $scope === 'https://www.googleapis.com/auth/drive.file' ||
                            $scope === 'https://www.googleapis.com/auth/drive.metadata.readonly'
                        ) {
                            $has_drive = true;
                            break;
                        }
                    }

                    if (
                        !in_array('https://www.googleapis.com/auth/spreadsheets', $scopes) ||
                        !$has_drive
                    ) {
                        $status = 'invalid-auth';
                    }
                }

                // STEP 4 — VERIFY GOOGLE DRIVE ACCESS
                $drive_check = wp_remote_get(
                    'https://www.googleapis.com/drive/v3/files?pageSize=1',
                    [
                        'headers' => [
                            'Authorization' => 'Bearer ' . $access_token
                        ]
                    ]
                );

                $drive_code = wp_remote_retrieve_response_code($drive_check);
                $drive_body = json_decode(wp_remote_retrieve_body($drive_check), true);
                if (!is_array($drive_body)) {
                    $status = 'invalid-auth';
                }
                // If permission missing
                if (
                    is_wp_error($drive_check) ||
                    $drive_code !== 200 ||
                    empty($drive_body) ||
                    isset($drive_body['error'])
                ) {
                    $status = 'invalid-auth';
                }
            }

            $body['expire'] = time() + ($body['expires_in'] ?? 3600);
            update_option('gshfjf_jetform_token', wp_json_encode($body));

            if ($no_token) {
                delete_option('gshfjf_jetform_verify');
            } else {
                update_option('gshfjf_jetform_verify', $status);
            }
        } catch (Exception $e) {
            GSHFJF_JetForm_Connector_Utility::gshfjf_debug_log('[Auth Exception]. ' . $e->getMessage());
            throw new LogicException('Auth error: ' . esc_html($e->getMessage()));
        }
    }

    /**
     * GET ACCESS TOKEN
     *
     * @since 1.0.0
     */

    private function token()
    {
        try {
            $token = json_decode(get_option('gshfjf_jetform_token'), true);
            if (empty($token) || !is_array($token)) {
                return false;
            }

            if (!empty($token['expire']) && time() < $token['expire']) {
                return $token['access_token'] ?? false;
            }

            return $this->refresh($token);
        } catch (Exception $e) {
            GSHFJF_JetForm_Connector_Utility::gshfjf_debug_log("Token write fail! - " . $e->getMessage());
        }
    }

    /**
     * REFRESH TOKEN
     *
     * @since 1.0.0
     */

    private function refresh($token)
    {
        try {
            if (empty($token['refresh_token'])) {
                return false;
            }
            $creds = self::creds();

            $response = wp_remote_post(
                'https://oauth2.googleapis.com/token',
                [
                    'body' => [
                        'client_id'     => $creds['client_id_web'],
                        'client_secret' => $creds['client_secret_web'],
                        'refresh_token' => $token['refresh_token'] ?? '',
                        'grant_type'    => 'refresh_token'
                    ]
                ]
            );
            if (is_wp_error($response)) {
                return false;
            }
            $body = json_decode(wp_remote_retrieve_body($response), true);
            if (!is_array($body)) {
                return false;
            }
            if (empty($body['access_token'])) return false;

            $body['refresh_token'] = $token['refresh_token'] ?? '';
            $body['expire'] = time() + ($body['expires_in'] ?? 3600);

            update_option('gshfjf_jetform_token', wp_json_encode($body));

            return $body['access_token'];
        } catch (Exception $e) {
            GSHFJF_JetForm_Connector_Utility::gshfjf_debug_log("Refresh Token fail! - " . $e->getMessage());
        }
    }

    /**
     * SET SPREADSHEET ID
     *
     * @since 1.0.0
     */

    public function setSpreadsheetId($id)
    {
        $this->spreadsheet = $id;
    }

    /**
     * SET WORKTAB ID
     *
     * @since 1.0.0
     */

    public function setWorkTabId($id)
    {
        $this->worksheet = $id;
    }

    /**
     * APPEND ROW
     *
     * @since 1.0.0
     */

    public function add_row_feed($spreadsheet_id, $sheet_title, $data)
    {
        try {
            $token = $this->token();

            if (!$token) {
                GSHFJF_JetForm_Connector_Utility::gshfjf_debug_log('add_row_feed: Token not found');
                return null;
            }

            $header_response = wp_remote_get(
                "https://sheets.googleapis.com/v4/spreadsheets/{$spreadsheet_id}/values/" . urlencode($sheet_title . '!1:1'),
                [
                    'headers' => [
                        'Authorization' => 'Bearer ' . $token
                    ]
                ]
            );

            if (is_wp_error($header_response)) {
                GSHFJF_JetForm_Connector_Utility::gshfjf_debug_log(
                    'add_row_feed: Failed to fetch headers - ' . $header_response->get_error_message()
                );
                return null;
            }

            $header_body = json_decode(wp_remote_retrieve_body($header_response), true);

            if (empty($header_body['values'][0])) {
                GSHFJF_JetForm_Connector_Utility::gshfjf_debug_log(
                    'add_row_feed: No headers found in sheet - ' . $sheet_title
                );
                return null;
            }

            $headers = $header_body['values'][0];
            $normalize = function ($str) {
                return strtolower(preg_replace('/[^a-z0-9]/', '', strtolower($str)));
            };

            $normalized_data = [];
            foreach ($data as $key => $val) {
                $normalized_data[$normalize($key)] = is_array($val)
                    ? implode(', ', $val)
                    : $val;
            }

            $row = [];
            foreach ($headers as $header) {
                $row[] = $normalized_data[$normalize($header)] ?? '';
            }

            $response = wp_remote_post(
                "https://sheets.googleapis.com/v4/spreadsheets/{$spreadsheet_id}/values/" . urlencode($sheet_title) . ":append?valueInputOption=USER_ENTERED&insertDataOption=INSERT_ROWS",
                [
                    'headers' => [
                        'Authorization' => 'Bearer ' . $token,
                        'Content-Type'  => 'application/json'
                    ],
                    'body' => wp_json_encode([
                        'values' => [$row]
                    ])
                ]
            );

            if (is_wp_error($response)) {
                GSHFJF_JetForm_Connector_Utility::gshfjf_debug_log(
                    'add_row_feed: Append failed - ' . $response->get_error_message()
                );
                return null;
            }

            $code = wp_remote_retrieve_response_code($response);

            if ($code !== 200) {
                GSHFJF_JetForm_Connector_Utility::gshfjf_debug_log(
                    'add_row_feed: API error ' . $code . ' - ' . wp_remote_retrieve_body($response)
                );
                return null;
            }

            $append_body = json_decode(wp_remote_retrieve_body($response), true);
            $updated_range = $append_body['updates']['updatedRange'] ?? '';

            preg_match('/!(?:[A-Z]+)(\d+)/', $updated_range, $matches);
            $inserted_row = isset($matches[1]) ? (int) $matches[1] : 0;

            if ($inserted_row > 0 && $this->worksheet !== null) {
                wp_remote_post(
                    "https://sheets.googleapis.com/v4/spreadsheets/{$spreadsheet_id}:batchUpdate",
                    [
                        'headers' => [
                            'Authorization' => 'Bearer ' . $token,
                            'Content-Type'  => 'application/json'
                        ],
                        'body' => wp_json_encode([
                            'requests' => [
                                [
                                    'repeatCell' => [
                                        'range' => [
                                            'sheetId'          => (int) $this->worksheet,
                                            'startRowIndex'    => $inserted_row - 1,
                                            'endRowIndex'      => $inserted_row,
                                            'startColumnIndex' => 0,
                                            'endColumnIndex'   => 1000
                                        ],
                                        'cell'   => ['userEnteredFormat' => new stdClass()],
                                        'fields' => 'userEnteredFormat'
                                    ]
                                ]
                            ]
                        ])
                    ]
                );
            }

            return true;
        } catch (Exception $e) {
            GSHFJF_JetForm_Connector_Utility::gshfjf_debug_log(
                '[GSheet] add_row_feed exception: ' . $e->getMessage()
            );
            return null;
        }
    }

    /**
     * GET USER EMAIL
     *
     * @since 1.0.0
     */

    public function gsheet_print_google_account_email()
    {
        try {
            $token = $this->token();
            if (!$token) return '';

            $response = wp_remote_get(
                'https://www.googleapis.com/oauth2/v2/userinfo',
                [
                    'headers' => [
                        'Authorization' => 'Bearer ' . $token
                    ]
                ]
            );

            $body = json_decode(wp_remote_retrieve_body($response), true);

            if (!empty($body['email'])) {
                update_option('gshfjf_jetform_email_account', $body['email']);
                return $body['email'];
            }

            return '';
        } catch (Exception $e) {
            GSHFJF_JetForm_Connector_Utility::gshfjf_debug_log(
                __METHOD__ . " Error in fetching user info: \n " . $e->getMessage()
            );
            return false;
        }
    }
}
