<?php

namespace App\Service;

use App\Models\User;
use Kreait\Firebase\Messaging;
use Kreait\Firebase\Messaging\CloudMessage;
use Kreait\Firebase\Messaging\Notification;

class PushNotification
{
    protected $messaging;

    public function __construct(?Messaging $messaging = null)
    {
        $this->messaging = $messaging;
    }

    public function sendNotification(User $user, string $type, array $data = [], string $status = 'success')
    {
        // Check if Firebase Messaging is available
        if (!$this->messaging) {
            \Log::warning('Firebase Messaging is not initialized. Push notification skipped.', [
                'user_id' => $user->id,
                'type' => $type,
            ]);
            return false;
        }

        if (!$user->hasDeviceTokens()) {
            \Log::info('User has no device tokens for notification');
            return false;
        }

        // Prepare notification data
        $notificationData = [
            'type' => $type,
            'status' => $status,
            'user_id' => $user->id,
            'name' => $user->name,
            'timestamp' => now()
        ];

        // Merge with additional data
        $notificationData = array_merge($notificationData, $data);

        // Get title and body based on notification type
        $title = $body = null;

        switch ($type) {
            case 'registration':
                $title = __('eventmie-pro::em.register_success');
                $body = __('eventmie-pro::em.welcome_message', ['name' => $user->name]);
                break;

            case 'login':
                $title = __('eventmie-pro::em.login_success');
                $body = __('eventmie-pro::em.login_message', ['name' => $user->name]);
                break;

            case 'booking':
                $title = $status === 'success' 
                    ? __('eventmie-pro::em.booking_success')
                    : __('eventmie-pro::em.booking_failed');

                $body = $status === 'success' 
                    ? __('eventmie-pro::em.booking_success_body_multiple', [
                        'event' => $data['event_title'] ?? '',
                        
                    ])
                    : __('eventmie-pro::em.booking_failed_body');
                break;

            default:
                $title = $data['title'] ?? __('eventmie-pro::em.default_title');
                $body = $data['body'] ?? __('eventmie-pro::em.default_body');
        }

        try {
            $message = null;

            // Add FCM token if available
            if (!empty($user->fcm_token)) {
                $message = CloudMessage::new()
                    ->toToken($user->fcm_token)
                    ->withNotification(Notification::create($title, $body))
                    ->withData($notificationData);
            }

            // Add APN token if available (only if FCM token is not set, to avoid overwriting)
            if (!$message && !empty($user->apn_token)) {
                $message = CloudMessage::new()
                    ->toToken($user->apn_token)
                    ->withNotification(Notification::create($title, $body))
                    ->withData($notificationData);
            }

            // If no valid token is available, log and return
            if (!$message) {
                \Log::info('No valid FCM or APN token found for user', ['user_id' => $user->id]);
                return false;
            }

            // Send the message
            $response = $this->messaging->send($message);
            
            // Log success
            \Log::info('Push notification sent successfully', [
                'user_id' => $user->id,
                'type' => $type,
                'title' => $title,
                'data' => $notificationData
            ]);

            return true;
        } catch (\Exception $e) {
            \Log::error('Failed to send push notification', [
                'user_id' => $user->id,
                'type' => $type,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
            return false;
        }
    }
}
