<?php

namespace App\Services;

use CodeIgniter\Config\Services;
use CodeIgniter\HTTP\CURLRequest;

/**
 * NotificationService - Handles push notifications using Firebase Cloud Messaging (FCM)
 */
class NotificationService
{
    /**
     * Firebase API Key (Server Key)
     *
     * @var string
     */
    protected $apiKey;
    
    /**
     * FCM API URL
     *
     * @var string
     */
    protected $fcmUrl = 'https://fcm.googleapis.com/fcm/send';
    
    /**
     * HTTP Client
     *
     * @var CURLRequest
     */
    protected $client;
    
    /**
     * Constructor
     */
    public function __construct()
    {
        // Load configuration
        $config = config('Firebase');
        $this->apiKey = $config->serverKey;
        
        // Initialize HTTP client
        $this->client = Services::curlrequest();
    }
    
    /**
     * Send notification to specific user by user ID
     *
     * @param int $userId User ID
     * @param string $title Notification title
     * @param string $body Notification body
     * @param array $data Additional data
     * @param array $options Notification options
     * @return bool Success status
     */
    public function sendToUser($userId, $title, $body, $data = [], $options = [])
    {
        // Get user's device tokens
        $deviceModel = model('App\Models\DeviceModel');
        $devices = $deviceModel->getUserTokens($userId, true);
        
        if (empty($devices)) {
            return false;
        }
        
        // Extract tokens
        $tokens = [];
        foreach ($devices as $device) {
            if (!empty($device['push_token'])) {
                $tokens[] = $device['push_token'];
            }
        }
        
        if (empty($tokens)) {
            return false;
        }
        
      
        
        // Send to multiple registration tokens
        return $this->sendToTokens($tokens, $title, $body, $data, $options);
    }
    
    /**
     * Send notification to multiple users
     *
     * @param array $userIds Array of user IDs
     * @param string $title Notification title
     * @param string $body Notification body
     * @param array $data Additional data
     * @param array $options Notification options
     * @return array Results for each user (user_id => success)
     */
    public function sendToMultipleUsers($userIds, $title, $body, $data = [], $options = [])
    {
        $results = [];
        
        foreach ($userIds as $userId) {
            $results[$userId] = $this->sendToUser($userId, $title, $body, $data, $options);
        }
        
        return $results;
    }
    
    /**
     * Send notification to a topic
     *
     * @param string $topic Topic name
     * @param string $title Notification title
     * @param string $body Notification body
     * @param array $data Additional data
     * @param array $options Notification options
     * @return bool Success status
     */
    public function sendToTopic($topic, $title, $body, $data = [], $options = [])
    {
        // Create payload
        $payload = [
            'to' => '/topics/' . $topic,
            'notification' => [
                'title' => $title,
                'body' => $body,
            ]
        ];
        
        // Add data payload if provided
        if (!empty($data)) {
            $payload['data'] = $data;
        }
        
        // Add options if provided
        if (!empty($options)) {
            if (isset($options['sound'])) {
                $payload['notification']['sound'] = $options['sound'];
            }
            
            if (isset($options['icon'])) {
                $payload['notification']['icon'] = $options['icon'];
            }
            
            if (isset($options['color'])) {
                $payload['notification']['color'] = $options['color'];
            }
            
            if (isset($options['click_action'])) {
                $payload['notification']['click_action'] = $options['click_action'];
            }
            
            if (isset($options['channel_id'])) {
                $payload['notification']['android_channel_id'] = $options['channel_id'];
            }
        }
        
        // Send notification
        return $this->sendFcmRequest($payload);
    }
    
    /**
     * Send notification to specific registration tokens
     *
     * @param array $tokens Array of FCM registration tokens
     * @param string $title Notification title
     * @param string $body Notification body
     * @param array $data Additional data
     * @param array $options Notification options
     * @return bool Success status
     */
    public function sendToTokens($tokens, $title, $body, $data = [], $options = [])
    {
        // Create payload
        $payload = [
            'registration_ids' => $tokens,
            'notification' => [
                'title' => $title,
                'body' => $body,
            ]
        ];
        
        // Add data payload if provided
        if (!empty($data)) {
            $payload['data'] = $data;
        }
        
        // Add options if provided
        if (!empty($options)) {
            if (isset($options['sound'])) {
                $payload['notification']['sound'] = $options['sound'];
            }
            
            if (isset($options['icon'])) {
                $payload['notification']['icon'] = $options['icon'];
            }
            
            if (isset($options['color'])) {
                $payload['notification']['color'] = $options['color'];
            }
            
            if (isset($options['click_action'])) {
                $payload['notification']['click_action'] = $options['click_action'];
            }
            
            if (isset($options['channel_id'])) {
                $payload['notification']['android_channel_id'] = $options['channel_id'];
            }
        }
        
        // Send notification
        return $this->sendFcmRequest($payload);
    }
    
    /**
     * Subscribe token to topic
     *
     * @param string $token FCM token
     * @param string $topic Topic name
     * @return bool Success status
     */
    public function subscribeTokenToTopic($token, $topic)
    {
        // FCM topic subscription endpoint
        $url = "https://iid.googleapis.com/iid/v1/{$token}/rel/topics/{$topic}";
        
        try {
            $response = $this->client->setHeader('Authorization', 'key=' . $this->apiKey)
                   ->setHeader('Content-Type', 'application/json')
                   ->post($url, ['json' => '']);
            
            // Check response
            return $response->getStatusCode() === 200;
        } catch (\Exception $e) {
            log_message('error', 'Error subscribing token to topic: ' . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Unsubscribe token from topic
     *
     * @param string $token FCM token
     * @param string $topic Topic name
     * @return bool Success status
     */
    public function unsubscribeTokenFromTopic($token, $topic)
    {
        // FCM topic unsubscription endpoint
        $url = "https://iid.googleapis.com/iid/v1:batchRemove";
        
        try {
            $data = [
                'to' => '/topics/' . $topic,
                'registration_tokens' => [$token]
            ];
            
            $response = $this->client->setHeader('Authorization', 'key=' . $this->apiKey)
                                    ->setHeader('Content-Type', 'application/json')
                                    ->post($url, ['json' => $data]);
            
            // Check response
            return $response->getStatusCode() === 200;
        } catch (\Exception $e) {
            log_message('error', 'Error unsubscribing token from topic: ' . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Get active tokens by filters
     *
     * @param array $filters Filter criteria
     * @param int $limit Maximum number of tokens
     * @return array Active tokens
     */
    public function getActiveTokens($filters = [], $limit = 1000)
    {
        $deviceModel = model('App\Models\DeviceModel');
        return $deviceModel->getActiveTokensByFilters($filters, $limit);
    }
    
    /**
     * Send FCM request
     *
     * @param array $payload FCM payload
     * @return bool Success status
     */
protected function sendFcmRequest($payload)
{
    try {
        $logFile = WRITEPATH . 'logs/fcm_requests.log';
        file_put_contents($logFile, date('Y-m-d H:i:s') . " FCM Request Started - Payload: " . json_encode($payload) . "\n", FILE_APPEND);
        
        // Hedef token(lar)ı al
        $tokens = [];
        if (isset($payload['registration_ids'])) {
            $tokens = $payload['registration_ids'];
        } elseif (isset($payload['to']) && strpos($payload['to'], '/topics/') === 0) {
            // Konu gönderimi için şimdilik hata dön
            file_put_contents($logFile, date('Y-m-d H:i:s') . " Topic messaging is not supported in this quick fix\n", FILE_APPEND);
            return false;
        } elseif (isset($payload['to'])) {
            $tokens = [$payload['to']];
        }
        
        if (empty($tokens)) {
            file_put_contents($logFile, date('Y-m-d H:i:s') . " No valid tokens found in payload\n", FILE_APPEND);
            return false;
        }
        
        // Bildirim verilerini al
        $title = isset($payload['notification']['title']) ? $payload['notification']['title'] : '';
        $body = isset($payload['notification']['body']) ? $payload['notification']['body'] : '';
        $data = isset($payload['data']) ? $payload['data'] : [];
        
        // ÖNEMLİ: Data alanındaki tüm değerleri string'e dönüştür
        // HTTP v1 API sadece string değerler kabul eder
        $processedData = [];
        foreach ($data as $key => $value) {
            // Tüm değerleri string'e dönüştür
            $processedData[$key] = (string)$value;
        }
        
        file_put_contents($logFile, date('Y-m-d H:i:s') . " Processed data (all strings): " . json_encode($processedData) . "\n", FILE_APPEND);
        
        // Servis hesabı dosyasının yolu
        $serviceAccountFile = WRITEPATH . 'satisahazirv1-8d7bbdff0ffc.json';
        
        // Eğer servis hesabı dosyası yoksa mesaj ver
        if (!file_exists($serviceAccountFile)) {
            file_put_contents($logFile, date('Y-m-d H:i:s') . " Service account file not found at: $serviceAccountFile\n", FILE_APPEND);
            return false;
        }
        
        // Servis hesabı bilgilerini oku
        $serviceAccount = json_decode(file_get_contents($serviceAccountFile), true);
        
        if (!isset($serviceAccount['private_key']) || !isset($serviceAccount['client_email'])) {
            file_put_contents($logFile, date('Y-m-d H:i:s') . " Invalid service account file\n", FILE_APPEND);
            return false;
        }
        
        // JWT token oluştur
        $now = time();
        $tokenData = [
            'iss' => $serviceAccount['client_email'],
            'sub' => $serviceAccount['client_email'],
            'aud' => 'https://oauth2.googleapis.com/token',
            'iat' => $now,
            'exp' => $now + 3600, // 1 saat
            'scope' => 'https://www.googleapis.com/auth/firebase.messaging'
        ];
        
        // JWT oluşturma fonksiyonu
        $jwtHeader = base64_encode(json_encode(['alg' => 'RS256', 'typ' => 'JWT']));
        $jwtPayload = base64_encode(json_encode($tokenData));
        
        // JWT imzalama
        $signature = '';
        openssl_sign(
            "$jwtHeader.$jwtPayload",
            $signature,
            $serviceAccount['private_key'],
            OPENSSL_ALGO_SHA256
        );
        $jwtSignature = base64_encode($signature);
        
        $jwt = "$jwtHeader.$jwtPayload.$jwtSignature";
        
        // OAuth token al
        $ch = curl_init('https://oauth2.googleapis.com/token');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
            'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
            'assertion' => $jwt
        ]));
        
        $response = curl_exec($ch);
        curl_close($ch);
        
        $authData = json_decode($response, true);
        
        if (!isset($authData['access_token'])) {
            file_put_contents($logFile, date('Y-m-d H:i:s') . " Failed to get OAuth token: " . json_encode($authData) . "\n", FILE_APPEND);
            return false;
        }
        
        $accessToken = $authData['access_token'];
        
        // Başarı sayısı
        $successCount = 0;
        $totalCount = count($tokens);
        
        // Her bir token için bildirim gönder
        foreach ($tokens as $token) {
            // Mesaj gönder
            $projectId = $serviceAccount['project_id'];
            $url = "https://fcm.googleapis.com/v1/projects/$projectId/messages:send";
            
           $message = [
                'message' => [
                    'token' => $token,
                    'notification' => [
                        'title' => $title,
                        'body' => $body
                    ],
                    'data' => $processedData,
                    // Android özel ayarları
                    'android' => [
                        'notification' => [
                            'icon' => 'ic_launcher_round', // Small icon (drawable'da olmalı)
                            'color' => '#AF8C55', // Notification color
                            'channel_id' => 'default_channel', // Notification channel
                            'sound' => 'default',
                            'click_action' => 'FLUTTER_NOTIFICATION_CLICK' // Flutter için
                        ]
                    ],
                    // iOS özel ayarları  
                    'apns' => [
                        'payload' => [
                            'aps' => [
                                'sound' => 'default',
                                'badge' => 1
                            ]
                        ],
                        'fcm_options' => [
                            'image' => 'https://satisahazir.com/app-icon.png' // iOS için large icon
                        ]
                    ]
                ]
            ];
            
            // Eski ayarları kaldır (artık gerek yok)
            // if (isset($payload['notification']['sound'])) {
            //     $message['message']['notification']['sound'] = $payload['notification']['sound'];
            // }
            // 
            // if (isset($payload['notification']['icon'])) {
            //     $message['message']['notification']['icon'] = $payload['notification']['icon'];
            // }
            // 
            // if (isset($payload['notification']['color'])) {
            //     $message['message']['android']['notification']['color'] = $payload['notification']['color'];
            // }
            // 
            // if (isset($payload['notification']['click_action'])) {
            //     $message['message']['notification']['click_action'] = $payload['notification']['click_action'];
            // }
            // 
            // if (isset($payload['notification']['android_channel_id'])) {
            //     $message['message']['android']['notification']['channel_id'] = $payload['notification']['android_channel_id'];
            // }
            
            // Tam mesajı logla
            file_put_contents($logFile, date('Y-m-d H:i:s') . " Sending message to FCM: " . json_encode($message) . "\n", FILE_APPEND);
            
            $ch = curl_init($url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($message));
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'Authorization: Bearer ' . $accessToken,
                'Content-Type: application/json'
            ]);
            
            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            
            file_put_contents($logFile, date('Y-m-d H:i:s') . " FCM HTTP v1 Response for token $token (Code: $httpCode): $response\n", FILE_APPEND);
            
            if ($httpCode >= 200 && $httpCode < 300) {
                $successCount++;
            } else {
                // Hata mesajını ayrıştır
                $responseData = json_decode($response, true);
                if (isset($responseData['error']['message'])) {
                    file_put_contents($logFile, date('Y-m-d H:i:s') . " FCM Error: " . $responseData['error']['message'] . "\n", FILE_APPEND);
                    
                    // Data format hatası için daha fazla debug
                    if (strpos($responseData['error']['message'], 'message.data') !== false) {
                        file_put_contents($logFile, date('Y-m-d H:i:s') . " Data Format Error - Raw data: " . json_encode($data) . "\n", FILE_APPEND);
                        file_put_contents($logFile, date('Y-m-d H:i:s') . " Data Format Error - Processed data: " . json_encode($processedData) . "\n", FILE_APPEND);
                    }
                }
            }
        }
        
        // Sonuç değerlendir
        $success = $successCount > 0;
        file_put_contents($logFile, date('Y-m-d H:i:s') . " FCM Request Summary: $successCount of $totalCount tokens successful\n", FILE_APPEND);
        
        return $success;
    } catch (\Exception $e) {
        $logFile = WRITEPATH . 'logs/fcm_requests.log';
        file_put_contents($logFile, date('Y-m-d H:i:s') . " Error sending FCM request: " . $e->getMessage() . "\n" . $e->getTraceAsString() . "\n", FILE_APPEND);
        return false;
    }
}
        
     
     
     

}