<?php

declare(strict_types=1);

require DENTAL_ROOT . '/app/bootstrap.php';
require_login();
require_permission('smtp.manage',['super_admin','clinic_admin']);
require DENTAL_ROOT . '/app/layout.php';

function gmail_oauth_http_form(string $url, array $fields, int $timeout = 30): array
{
    if (!extension_loaded('curl')) {
        throw new RuntimeException('PHP cURL must be enabled before Gmail OAuth can be connected.');
    }
    $ch = curl_init($url);
    if ($ch === false) {
        throw new RuntimeException('Unable to initialize Google OAuth request.');
    }
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query($fields, '', '&'),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => max(10, min(120, $timeout)),
        CURLOPT_CONNECTTIMEOUT => 30,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_SSL_VERIFYHOST => 2,
        CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'],
    ]);
    $raw = curl_exec($ch);
    $errno = curl_errno($ch);
    $error = curl_error($ch);
    $status = (int) curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    curl_close($ch);
    if ($raw === false || $errno !== 0) {
        throw new RuntimeException('Google OAuth HTTPS request failed: ' . ($error ?: 'cURL error ' . $errno));
    }
    $decoded = json_decode((string) $raw, true);
    if (!is_array($decoded)) {
        throw new RuntimeException('Google OAuth returned a non-JSON response with HTTP ' . $status . '.');
    }
    if ($status < 200 || $status >= 300) {
        $message = (string) ($decoded['error_description'] ?? $decoded['error'] ?? 'Google OAuth request failed.');
        throw new RuntimeException('Google OAuth error HTTP ' . $status . ': ' . $message);
    }
    return $decoded;
}

$config = dental_config();
$mail = (array)($config['mail'] ?? []);
$gmail = array_merge([
    'client_id' => '',
    'client_secret' => '',
    'refresh_token' => '',
    'sender_email' => (string)($mail['from_email'] ?? ''),
    'timeout' => 30,
], (array)($mail['gmail_api'] ?? []));
$clientId = trim((string)$gmail['client_id']);
$clientSecret = (string)$gmail['client_secret'];
$redirectUri = app_absolute_url('gmail-oauth');
$scope = 'https://www.googleapis.com/auth/gmail.send';

try {
    if (isset($_GET['error'])) {
        throw new RuntimeException('Google rejected the Gmail connection: ' . (string)$_GET['error']);
    }
    if (isset($_GET['code'])) {
        $knownState = (string)($_SESSION['gmail_oauth_state'] ?? '');
        $returnedState = (string)($_GET['state'] ?? '');
        if ($knownState === '' || $returnedState === '' || !hash_equals($knownState, $returnedState)) {
            throw new RuntimeException('Invalid or expired Gmail OAuth state. Start the Gmail connection again.');
        }
        if ($clientId === '' || $clientSecret === '') {
            throw new RuntimeException('Save the Google OAuth Client ID and Client Secret before completing Gmail connection.');
        }
        $token = gmail_oauth_http_form('https://oauth2.googleapis.com/token', [
            'client_id' => $clientId,
            'client_secret' => $clientSecret,
            'code' => (string)$_GET['code'],
            'grant_type' => 'authorization_code',
            'redirect_uri' => $redirectUri,
        ], (int)$gmail['timeout']);
        $refreshToken = (string)($token['refresh_token'] ?? '');
        if ($refreshToken === '') {
            throw new RuntimeException('Google did not return a refresh token. Remove the app access from the Google account, then reconnect with consent again.');
        }
        unset($_SESSION['gmail_oauth_state']);
        dental_update_generated_config(static function(array $config) use ($refreshToken, $gmail): array {
            $mail = (array)($config['mail'] ?? []);
            $existing = (array)($mail['gmail_api'] ?? []);
            $sender = trim((string)($existing['sender_email'] ?? $gmail['sender_email'] ?? $mail['from_email'] ?? ''));
            $mail['driver'] = 'gmail_api';
            $mail['gmail_api'] = array_merge($existing, [
                'refresh_token' => $refreshToken,
                'sender_email' => $sender,
                'timeout' => max(10, min(120, (int)($existing['timeout'] ?? 30))),
            ]);
            if ($sender !== '') {
                $mail['from_email'] = $sender;
            }
            $config['mail'] = $mail;
            return $config;
        });
        audit('gmail_api_oauth_connected', 'settings', null, ['sender_email' => (string)($gmail['sender_email'] ?? '')]);
        flash('success','Gmail is connected. Gmail API is now selected as the email driver. Run Full Delivery Test to send a real test message.');
        header('Location: email_settings.php');
        exit;
    }
} catch (Throwable $exception) {
    flash('error', $exception->getMessage());
    header('Location: email_settings.php');
    exit;
}

$state = bin2hex(random_bytes(24));
$_SESSION['gmail_oauth_state'] = $state;
$authUrl = 'https://accounts.google.com/o/oauth2/v2/auth?' . http_build_query([
    'client_id' => $clientId,
    'redirect_uri' => $redirectUri,
    'response_type' => 'code',
    'scope' => $scope,
    'access_type' => 'offline',
    'prompt' => 'consent',
    'state' => $state,
], '', '&', PHP_QUERY_RFC3986);

render_header('Connect Gmail');
?>
<section class="card smtp-heading"><div><span class="eyebrow">Gmail API</span><h2>Connect Gmail</h2><p>This connects Gmail through Google OAuth and sends mail through HTTPS. It does not use SMTP ports 465 or 587.</p></div><a class="btn ghost" href="email_settings.php">Back to Email Settings</a></section>
<section class="card form-grid">
    <h2 class="wide">Connection checklist</h2>
    <div class="alert info wide"><strong>Authorized redirect URI for Google Cloud</strong><br><code><?=e($redirectUri)?></code></div>
    <div class="health-list wide">
        <div><span>OAuth Client ID saved</span><strong class="<?= $clientId !== '' ? 'ok' : 'bad' ?>"><?= $clientId !== '' ? 'Ready' : 'Missing' ?></strong></div>
        <div><span>OAuth Client Secret saved</span><strong class="<?= $clientSecret !== '' ? 'ok' : 'bad' ?>"><?= $clientSecret !== '' ? 'Ready' : 'Missing' ?></strong></div>
        <div><span>Gmail send scope</span><strong class="ok">gmail.send</strong></div>
        <div><span>Transport path</span><strong class="ok">HTTPS 443</strong></div>
    </div>
    <?php if($clientId !== '' && $clientSecret !== ''): ?>
        <div class="wide status-actions"><a class="btn primary" href="<?=e($authUrl)?>">Authorize Gmail Account</a><a class="btn ghost" href="email_settings.php">Cancel</a></div>
    <?php else: ?>
        <div class="alert warning wide">Save the Google OAuth Client ID and Client Secret on Email Settings first, then return here.</div>
        <div class="wide status-actions"><a class="btn primary" href="email_settings.php">Open Email Settings</a></div>
    <?php endif; ?>
</section>
<?php render_footer();
