<?php

namespace App\Commands;

use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\CLI\CLI;
use Modules\Notification\Models\NotificationModel;
use Modules\Notification\Models\UserNotificationModel;
use CodeIgniter\Database\Exceptions\DataException;
use Modules\Passanger\Models\UserDeviceModel;
use Modules\Ticket\Models\TicketModel;
use App\Libraries\UserPushNotification;

class SendScheduledNotifications extends BaseCommand
{
    protected $group       = 'Notifications';
    protected $name        = 'notifications:send';
    protected $description = 'Send scheduled notifications every minute';

    // public function run(array $params)
    // {
    //     $notificationModel = new NotificationModel();

    //     // Find scheduled notifications whose time has arrived
    //     $notifications = $notificationModel->where('status', 'scheduled')
    //         ->where('notification_date <=', date('Y-m-d H:i:s'))
    //         ->findAll();
    //     if (empty($notifications)) {
    //         CLI::write('No notifications to send at this time.', 'yellow');
    //         return;
    //     }

    //     foreach ($notifications as $notification) {
    //             $targetUserIds = [];

    //     if ($notification->target_group === 'all_users') {
    //         // Get all active user device entries
    //         $devices = $userDeviceModel->where('status', 'active')->findAll();

    //         foreach ($devices as $device) {
    //             $targetUserIds[] = $device->user_id;
    //         }
    //         try {
    //             print_r($notification);
    //             exit;
    //             // Call your existing API endpoint
    //             $ch = curl_init();
    //             curl_setopt($ch, CURLOPT_URL, "https://data.busvalley.com/busvalley_new/modules/api/v1/passangers/send-notification");
    //             curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    //             curl_setopt($ch, CURLOPT_POST, true);
    //             curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
    //             curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    //                 'user_id' => $notification['user_id'],
    //                 'title'   => $notification['subject'],  
    //                 'body'    => $notification['message'],   
    //             ]));

    //             $response = curl_exec($ch);
    //             print_r($response);
    //             exit;

    //             curl_close($ch);

    //             // Update notification status → sent
    //              $notificationModel->update($notification['id'], [
    //                 'status' => 'sent',
    //                 'updated_at' => date('Y-m-d H:i:s')
    //             ]);

    //             CLI::write("Notification {$notification['id']} sent successfully.", 'green');
    //         } catch (\Exception $e) {
    //             CLI::error("Error sending notification {$notification['id']}: " . $e->getMessage());
    //         }
    //     }
    // }
    public function run(array $params)
    {
        $notificationModel = new NotificationModel();
        $userDeviceModel   = new UserDeviceModel();
        $userNotificationModel = new UserNotificationModel();
        $ticketModel       = new TicketModel();
        $pushNotifier      = new UserPushNotification();

        // 1. Fetch scheduled notifications whose time has arrived
        $notifications = $notificationModel->where('status', 'scheduled')
            ->where('notification_date <=', date('Y-m-d H:i:s'))
            ->findAll();

        if (empty($notifications)) {
            CLI::write('No notifications to send at this time.', 'yellow');
            return;
        }

        foreach ($notifications as $notification) {

            $targetUserIds = [];

            // 2. Determine target users
            if ($notification['target_group'] === 'all_users') {
                // Get all active user device entries
                $devices = $userDeviceModel->where('status', 1)->findAll();
                foreach ($devices as $device) {
                    $targetUserIds[] = $device->user_id; // array syntax
                }
                // Remove duplicate user IDs
                $targetUserIds = array_unique($targetUserIds);
            } elseif ($notification['target_group'] === 'specific_trip' && ! empty($notification['trip_id'])) {
                // Same eligibility as admin immediate send: paid, not cancelled, passenger user id
                $tickets = $ticketModel->select('passanger_id')
                    ->where('trip_id', $notification['trip_id'])
                    ->where('cancel_status', 0)
                    ->where('payment_status', 'paid')
                    ->where('passanger_id >', 0)
                    ->groupBy('passanger_id')
                    ->findAll();
                foreach ($tickets as $ticket) {
                    $targetUserIds[] = (int) $ticket->passanger_id;
                }
                $targetUserIds = array_unique($targetUserIds);
            }

            $targetUserIds = array_values(array_unique(array_filter(array_map('intval', $targetUserIds))));
            $targetUserIds = array_values(array_filter($targetUserIds, static fn ($id) => $id > 0));

            if ($targetUserIds === []) {
                CLI::write("Notification {$notification['id']} skipped: no eligible recipients.", 'yellow');

                continue;
            }

            // 3. Send push (FCM) when enabled — same stack as Passanger::sendNotification / admin immediate send
            foreach ($targetUserIds as $userId) {
                if (! empty($notification['is_push_notification'])) {
                    try {
                        $pushNotifier->sendToUser((int) $userId, (string) $notification['subject'], (string) $notification['message']);
                    } catch (\Throwable $e) {
                        CLI::error("Push error notification {$notification['id']} user {$userId}: " . $e->getMessage());
                    }
                }

                $currentTime = date('Y-m-d H:i:s');

                try {
                    $existingDelivery = $userNotificationModel->where('notification_id', $notification['id'])
                        ->where('user_id', $userId)
                        ->first();

                    if ($existingDelivery) {
                        $userNotificationModel->update($existingDelivery->id, [
                            'sent_at' => $currentTime,
                            'is_read' => 0,
                            'read_at' => null,
                        ]);
                    } else {
                        $userNotificationModel->insert([
                            'notification_id' => $notification['id'],
                            'user_id' => $userId,
                            'sent_at' => $currentTime,
                            'is_read' => 0,
                            'read_at' => null,
                        ]);
                    }
                } catch (DataException $e) {
                    CLI::error("Failed to record notification {$notification['id']} for user {$userId}: " . $e->getMessage());
                } catch (\Throwable $e) {
                    CLI::error("Unexpected error while recording notification {$notification['id']} for user {$userId}: " . $e->getMessage());
                }
            }

            $updateData = [];
            $repeatOption = $notification['repeat_option'] ?? 'none';

            switch ($repeatOption) {
                case 'daily':
                    $updateData['notification_date'] = date('Y-m-d H:i:s', strtotime($notification['notification_date'] . ' +1 day'));

                    break;
                case 'weekly':
                    $updateData['notification_date'] = date('Y-m-d H:i:s', strtotime($notification['notification_date'] . ' +1 week'));

                    break;
                case 'monthly':
                    $updateData['notification_date'] = date('Y-m-d H:i:s', strtotime($notification['notification_date'] . ' +1 month'));

                    break;
                case 'none':
                default:
                    $updateData['status'] = 'sent';

                    break;
            }

            if ($updateData !== []) {
                $notificationModel->update($notification['id'], $updateData);
            }
        }


        CLI::write('All due notifications processed.', 'blue');
    }

}
