<?php
/**
 * Firebase Cloud Messaging Service
 * Firebase FCM HTTP v1 API kullanarak bildirim gönderme
 */
class FirebaseService {
    private $db;
    private $config;
    private $accessToken;
    private $tokenExpiry;
    
    public function __construct($database) {
        $this->db = $database;
        $this->loadConfig();
    }
    
    /**
     * Firebase yapılandırmasını yükle
     */
    private function loadConfig() {
        try {
            $stmt = $this->db->prepare("SELECT project_id, service_account_json FROM firebase_config WHERE is_active = 1 LIMIT 1");
            $stmt->execute();
            $configRow = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if (!$configRow) {
                throw new Exception("Firebase yapılandırması bulunamadı. Lütfen Firebase ayarlarını yapılandırın.");
            }
            
            // Service Account JSON'ı parse et
            $serviceAccount = json_decode($configRow['service_account_json'], true);
            if (json_last_error() !== JSON_ERROR_NONE) {
                throw new Exception("Firebase Service Account JSON formatı geçersiz.");
            }
            
            // Config array'ini oluştur
            $this->config = [
                'project_id' => $configRow['project_id'],
                'private_key' => $serviceAccount['private_key'],
                'client_email' => $serviceAccount['client_email'],
                'service_account' => $serviceAccount
            ];
            
        } catch (Exception $e) {
            error_log("Firebase config yükleme hatası: " . $e->getMessage());
            throw $e;
        }
    }
    
    /**
     * Firebase yapılandırmasının geçerli olup olmadığını kontrol et
     */
    public function isConfigured() {
        return !empty($this->config) && 
               !empty($this->config['project_id']) && 
               !empty($this->config['private_key']) && 
               !empty($this->config['client_email']);
    }
    
    /**
     * JWT token oluştur
     */
    private function createJWT() {
        $header = json_encode(['typ' => 'JWT', 'alg' => 'RS256']);
        $now = time();
        $payload = json_encode([
            'iss' => $this->config['client_email'],
            'scope' => 'https://www.googleapis.com/auth/firebase.messaging',
            'aud' => 'https://oauth2.googleapis.com/token',
            'exp' => $now + 3600,
            'iat' => $now
        ]);
        
        $base64Header = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($header));
        $base64Payload = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($payload));
        
        $signature = '';
        $privateKey = openssl_pkey_get_private($this->config['private_key']);
        openssl_sign($base64Header . "." . $base64Payload, $signature, $privateKey, OPENSSL_ALGO_SHA256);
        openssl_free_key($privateKey);
        
        $base64Signature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($signature));
        
        return $base64Header . "." . $base64Payload . "." . $base64Signature;
    }
    
    /**
     * Access token al
     */
    private function getAccessToken() {
        $jwt = $this->createJWT();
        
        $postData = http_build_query([
            'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
            'assertion' => $jwt
        ]);
        
        $context = stream_context_create([
            'http' => [
                'method' => 'POST',
                'header' => 'Content-Type: application/x-www-form-urlencoded',
                'content' => $postData
            ]
        ]);
        
        $response = file_get_contents('https://oauth2.googleapis.com/token', false, $context);
        $data = json_decode($response, true);
        
        if (!isset($data['access_token'])) {
            throw new Exception("Access token alınamadı: " . $response);
        }
        
        return $data['access_token'];
    }
    
    /**
     * Tüm kullanıcılara bildirim gönder
     */
    public function sendToAll($title, $body, $icon = 'ic_notification', $sound = 'default', $clickAction = null) {
        return $this->sendToTopic('all_users', $title, $body, $icon, $sound, $clickAction);
    }
    
    /**
     * Belirli topic'e bildirim gönder
     */
    public function sendToTopic($topic, $title, $body, $icon = 'ic_notification', $sound = 'default', $clickAction = null) {
        try {
            $accessToken = $this->getAccessToken();
            
            $message = [
                'message' => [
                    'topic' => $topic,
                    'notification' => [
                        'title' => $title,
                        'body' => $body
                    ],
                    'data' => [
                        'icon' => $icon,
                        'sound' => $sound
                    ],
                    'android' => [
                        'notification' => [
                            'icon' => $icon,
                            'sound' => $sound,
                            'click_action' => $clickAction ?: 'FLUTTER_NOTIFICATION_CLICK'
                        ]
                    ]
                ]
            ];
            
            $url = 'https://fcm.googleapis.com/v1/projects/' . $this->config['project_id'] . '/messages:send';
            
            $context = stream_context_create([
                'http' => [
                    'method' => 'POST',
                    'header' => [
                        'Authorization: Bearer ' . $accessToken,
                        'Content-Type: application/json'
                    ],
                    'content' => json_encode($message)
                ]
            ]);
            
            $response = file_get_contents($url, false, $context);
            
            if ($response === false) {
                $error = error_get_last();
                throw new Exception("HTTP isteği başarısız: " . ($error['message'] ?? 'Bilinmeyen hata'));
            }
            
            $responseData = json_decode($response, true);
            
            // HTTP status code kontrolü
            if (isset($http_response_header)) {
                $statusLine = $http_response_header[0];
                preg_match('/HTTP\/\d\.\d\s+(\d+)/', $statusLine, $matches);
                $statusCode = isset($matches[1]) ? (int)$matches[1] : 0;
                
                if ($statusCode >= 400) {
                    $errorMessage = isset($responseData['error']['message']) 
                        ? $responseData['error']['message'] 
                        : "HTTP $statusCode hatası";
                    throw new Exception($errorMessage);
                }
            }
            
            // FCM response kontrolü
            if (isset($responseData['error'])) {
                throw new Exception("FCM hatası: " . $responseData['error']['message']);
            }
            
            return [
                'success' => true,
                'response' => $responseData,
                'message' => 'Bildirim başarıyla gönderildi',
                'message_id' => $responseData['name'] ?? null
            ];
            
        } catch (Exception $e) {
            error_log("Firebase bildirim hatası: " . $e->getMessage());
            return [
                'success' => false,
                'error' => $e->getMessage(),
                'message' => 'Bildirim gönderilemedi'
            ];
        }
    }
    
    /**
     * Belirli token'a bildirim gönder
     */
    public function sendToToken($token, $title, $body, $icon = 'ic_notification', $sound = 'default', $clickAction = null) {
        try {
            $accessToken = $this->getAccessToken();
            
            $message = [
                'message' => [
                    'token' => $token,
                    'notification' => [
                        'title' => $title,
                        'body' => $body
                    ],
                    'data' => [
                        'icon' => $icon,
                        'sound' => $sound
                    ],
                    'android' => [
                        'notification' => [
                            'icon' => $icon,
                            'sound' => $sound,
                            'click_action' => $clickAction ?: 'FLUTTER_NOTIFICATION_CLICK'
                        ]
                    ]
                ]
            ];
            
            $url = 'https://fcm.googleapis.com/v1/projects/' . $this->config['project_id'] . '/messages:send';
            
            $context = stream_context_create([
                'http' => [
                    'method' => 'POST',
                    'header' => [
                        'Authorization: Bearer ' . $accessToken,
                        'Content-Type: application/json'
                    ],
                    'content' => json_encode($message)
                ]
            ]);
            
            $response = file_get_contents($url, false, $context);
            
            if ($response === false) {
                $error = error_get_last();
                throw new Exception("HTTP isteği başarısız: " . ($error['message'] ?? 'Bilinmeyen hata'));
            }
            
            $responseData = json_decode($response, true);
            
            // HTTP status code kontrolü
            if (isset($http_response_header)) {
                $statusLine = $http_response_header[0];
                preg_match('/HTTP\/\d\.\d\s+(\d+)/', $statusLine, $matches);
                $statusCode = isset($matches[1]) ? (int)$matches[1] : 0;
                
                if ($statusCode >= 400) {
                    $errorMessage = isset($responseData['error']['message']) 
                        ? $responseData['error']['message'] 
                        : "HTTP $statusCode hatası";
                    throw new Exception($errorMessage);
                }
            }
            
            // FCM response kontrolü
            if (isset($responseData['error'])) {
                throw new Exception("FCM hatası: " . $responseData['error']['message']);
            }
            
            return [
                'success' => true,
                'response' => $responseData,
                'message' => 'Bildirim başarıyla gönderildi',
                'message_id' => $responseData['name'] ?? null
            ];
            
        } catch (Exception $e) {
            error_log("Firebase bildirim hatası: " . $e->getMessage());
            return [
                'success' => false,
                'error' => $e->getMessage(),
                'message' => 'Bildirim gönderilemedi'
            ];
        }
    }
    
    /**
     * Bildirim geçmişini kaydet
     */
    public function saveNotificationHistory($templateId, $title, $body, $icon, $sound, $clickAction, $targetType, $targetValue, $result, $sentBy) {
        try {
            // Debug log
            error_log("saveNotificationHistory çağrıldı - sentBy: " . var_export($sentBy, true));
            
            // sentBy kontrolü
            if (empty($sentBy)) {
                error_log("UYARI: sentBy değeri boş! Session admin_id kontrol edilmeli.");
                $sentBy = 1; // Varsayılan admin ID
            }
            
            $stmt = $this->db->prepare("
                INSERT INTO sent_notifications 
                (template_id, title, body, icon, sound, click_action, target_type, target_value, status, response_data, sent_count, failed_count, sent_by) 
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            ");
            
            $status = $result['success'] ? 'sent' : 'failed';
            $sentCount = $result['success'] ? 1 : 0;
            $failedCount = $result['success'] ? 0 : 1;
            
            $params = [
                $templateId,
                $title,
                $body,
                $icon,
                $sound,
                $clickAction,
                $targetType,
                $targetValue,
                $status,
                json_encode($result),
                $sentCount,
                $failedCount,
                $sentBy
            ];
            
            error_log("SQL parametreleri: " . json_encode($params));
            
            $stmt->execute($params);
            
            $insertId = $this->db->lastInsertId();
            error_log("Bildirim geçmişi başarıyla kaydedildi. ID: " . $insertId);
            
            return $insertId;
            
        } catch (Exception $e) {
            error_log("Bildirim geçmişi kaydetme hatası: " . $e->getMessage());
            error_log("SQL Hatası: " . print_r($this->db->errorInfo(), true));
            return false;
        }
    }
}
?>
