<?php

use App\Models\User;
use App\Models\UserPlan;
use App\Models\Subscription;
use App\Models\Notification;
use App\Services\NotificationService;
use Illuminate\Support\Facades\DB;

require __DIR__.'/vendor/autoload.php';
$app = require_once __DIR__.'/bootstrap/app.php';
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$kernel->bootstrap();

echo "🚀 Starting Notification Targeting Test...\n";

// Helper to access protected methods
function invokeMethod(&$object, $methodName, array $parameters = [])
{
    $reflection = new \ReflectionClass(get_class($object));
    $method = $reflection->getMethod($methodName);
    $method->setAccessible(true);
    return $method->invokeArgs($object, $parameters);
}

try {
    DB::beginTransaction();

    // 1. Setup Test Data
    echo "\n1️⃣  Setting up test user and plans...\n";
    
    // Ensure VIP Buyer plan exists
    $vipPlan = UserPlan::firstOrCreate(
        ['plan_name' => 'VIP Buyer Test'],
        [
            'price' => 10.00,
            'duration_days' => 30,
            'status' => 'active'
        ]
    );

    // Ensure Manual Gateway exists (for Subscription FK)
    \App\Models\PaymentGateway::firstOrCreate(
        ['slug' => 'manual'],
        [
            'name' => 'Manual Payment',
            'is_active' => true,
            'is_test_mode' => true,
            'description' => 'Manual payment for testing'
        ]
    );

    // Create Test User
    $user = User::firstOrCreate(
        ['email' => 'targeting_test@clxpro.com'],
        [
            'name' => 'Targeting Test User',
            'password' => bcrypt('password'),
            'city' => 'TestCity',
            'country' => 'TestCountry'
        ]
    );

    // Create Notification Preference for user
    $user->notificationPreference()->firstOrCreate([
        'user_id' => $user->id
    ], [
        'enabled' => true,
        'types' => ['general' => true]
    ]);

    // Create Subscription
    Subscription::create([
        'user_id' => $user->id,
        'subscription_id' => 'sub_test_' . rand(1000, 9999), 
        'plan_id' => $vipPlan->id,
        'gateway_slug' => 'manual',
        'amount' => 10.00,
        'currency' => 'USD',
        'billing_interval' => 'month',
        'billing_frequency' => 1,
        'status' => 'active',
        'start_date' => now(),
        'end_date' => now()->addDays(30),
        'auto_renew' => false
    ]);

    echo "   ✅ User '{$user->name}' created with 'VIP Buyer Test' plan.\n";

    // 2. Test Targeting Logic
    $service = app(NotificationService::class);

    echo "\n2️⃣  Testing Premium Plan Targeting...\n";
    
    // Mock Notification
    $notification = new Notification();
    $notification->target_value = ['plan_types' => ['VIP Buyer Test']];

    // Call protected method
    $users = invokeMethod($service, 'getPremiumPlanUsers', [$notification]);

    if ($users->contains('id', $user->id)) {
        echo "   ✅ SUCCESS: User Found in Premium Plan Target Group!\n";
    } else {
        echo "   ❌ FAILED: User NOT found in Premium Plan Target Group.\n";
        exit(1);
    }

    echo "\n3️⃣  Testing Location Targeting (Combined)...\n";
    $notification->target_value = [
        'plan_types' => ['VIP Buyer Test'],
        'city' => 'TestCity'
    ];

    $users = invokeMethod($service, 'getPremiumPlanUsers', [$notification]);

    if ($users->contains('id', $user->id)) {
        echo "   ✅ SUCCESS: User Found with Correct Location!\n";
    } else {
        echo "   ❌ FAILED: User NOT found with Correct Location.\n";
    }

    // Negative Test
    $notification->target_value = [
        'plan_types' => ['VIP Buyer Test'],
        'city' => 'WrongCity'
    ];
    $users = invokeMethod($service, 'getPremiumPlanUsers', [$notification]);

    if (!$users->contains('id', $user->id)) {
        echo "   ✅ SUCCESS: User Correctly Excluded for Wrong Location!\n";
    } else {
        echo "   ❌ FAILED: User Should have been excluded.\n";
    }

} catch (\Exception $e) {
    echo "\n❌ ERROR: " . $e->getMessage() . "\n";
    echo $e->getTraceAsString();
} finally {
    DB::rollBack(); // Always rollback to keep DB clean
    echo "\nStart Cleanup... (Rolled back transaction)\n";
}
