<?php

require_once __DIR__ . '/fcm_config.php';

function mch_send_fcm_notification($token, $title, $body, array $data = array(), $dataOnly = false)
{
    if (!FCM_ENABLED || empty($token)) {
        return array('success' => false, 'message' => 'FCM disabled or token empty');
    }

    if (!empty(FCM_SERVER_KEY)) {
        return mch_send_fcm_legacy($token, $title, $body, $data, $dataOnly);
    }

    if (is_file(FCM_SERVICE_ACCOUNT_FILE)) {
        return mch_send_fcm_v1($token, $title, $body, $data, $dataOnly);
    }

    return array('success' => false, 'message' => 'FCM not configured');
}

function mch_send_fcm_legacy($token, $title, $body, array $data = array(), $dataOnly = false)
{
    $payload = array(
        'to' => $token,
        'priority' => 'high',
        'data' => array_merge(array(
            'title' => $title,
            'body' => $body,
        ), $data),
    );

    if (!$dataOnly) {
        $payload['notification'] = array(
            'title' => $title,
            'body' => $body,
            'sound' => 'default',
        );
    }

    $headers = array(
        'Authorization: key=' . FCM_SERVER_KEY,
        'Content-Type: application/json',
    );

    return mch_fcm_curl('https://fcm.googleapis.com/fcm/send', json_encode($payload), $headers);
}

function mch_send_fcm_v1($token, $title, $body, array $data = array(), $dataOnly = false)
{
    $accessToken = mch_get_fcm_access_token();
    if (empty($accessToken)) {
        return array('success' => false, 'message' => 'Unable to obtain FCM access token');
    }

    $message = array(
        'token' => $token,
        'data' => array_map('strval', array_merge(array(
            'title' => $title,
            'body' => $body,
        ), $data)),
        'android' => array(
            'priority' => 'HIGH',
        ),
    );

    if (!$dataOnly) {
        $message['notification'] = array(
            'title' => $title,
            'body' => $body,
        );
    }

    $payload = array(
        'message' => $message,
    );

    $url = 'https://fcm.googleapis.com/v1/projects/' . FCM_PROJECT_ID . '/messages:send';
    $headers = array(
        'Authorization: Bearer ' . $accessToken,
        'Content-Type: application/json',
    );

    return mch_fcm_curl($url, json_encode($payload), $headers);
}

function mch_get_fcm_access_token()
{
    static $cachedToken = null;
    static $cachedExpiry = 0;

    if ($cachedToken && time() < ($cachedExpiry - 60)) {
        return $cachedToken;
    }

    $serviceAccount = json_decode(file_get_contents(FCM_SERVICE_ACCOUNT_FILE), true);
    if (empty($serviceAccount['client_email']) || empty($serviceAccount['private_key'])) {
        return null;
    }

    $now = time();
    $jwtHeader = mch_base64url_encode(json_encode(array('alg' => 'RS256', 'typ' => 'JWT')));
    $jwtClaim = mch_base64url_encode(json_encode(array(
        'iss' => $serviceAccount['client_email'],
        'scope' => 'https://www.googleapis.com/auth/firebase.messaging',
        'aud' => 'https://oauth2.googleapis.com/token',
        'iat' => $now,
        'exp' => $now + 3600,
    )));

    $unsignedToken = $jwtHeader . '.' . $jwtClaim;
    openssl_sign($unsignedToken, $signature, $serviceAccount['private_key'], 'sha256WithRSAEncryption');
    $signedJwt = $unsignedToken . '.' . mch_base64url_encode($signature);

    $ch = curl_init('https://oauth2.googleapis.com/token');
    curl_setopt_array($ch, array(
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query(array(
            'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
            'assertion' => $signedJwt,
        )),
    ));
    $response = curl_exec($ch);
    curl_close($ch);

    $decoded = json_decode($response, true);
    if (empty($decoded['access_token'])) {
        return null;
    }

    $cachedToken = $decoded['access_token'];
    $cachedExpiry = $now + (int)($decoded['expires_in'] ?? 3600);
    return $cachedToken;
}

function mch_base64url_encode($data)
{
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

function mch_fcm_curl($url, $payload, array $headers)
{
    $ch = curl_init($url);
    curl_setopt_array($ch, array(
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => $headers,
        CURLOPT_POSTFIELDS => $payload,
        CURLOPT_CONNECTTIMEOUT => 10,
        CURLOPT_TIMEOUT => 20,
    ));

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $error = curl_error($ch);
    curl_close($ch);

    if ($response === false) {
        return array('success' => false, 'message' => $error);
    }

    $decoded = json_decode($response, true);
    $success = ($httpCode >= 200 && $httpCode < 300);

    if (!$success && is_array($decoded) && isset($decoded['error'])) {
        return array('success' => false, 'message' => json_encode($decoded['error']));
    }

    return array(
        'success' => $success,
        'message' => $success ? 'Notification sent' : $response,
        'response' => $decoded,
    );
}

function mch_get_device_fcm_token($con, $imeino)
{
    $query = "SELECT fcmtoken FROM tblbranchdevicemapping WHERE deviceid = $1 AND statuscode = '1' LIMIT 1";
    $result = pg_query_params($con, $query, array($imeino));
    if ($result && pg_num_rows($result) > 0) {
        $row = pg_fetch_assoc($result);
        return $row['fcmtoken'] ?? '';
    }
    return '';
}
