<?php

use Binafy\LaravelUserMonitoring\Models\VisitMonitoring;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\Request;
use Tests\SetUp\Models\User;
use function Pest\Laravel\{actingAs, get};
use function Pest\Laravel\{assertDatabaseCount, assertDatabaseHas, assertDatabaseMissing};

/*
 * Use `RefreshDatabase` for delete migration data for each test.
 */
uses(RefreshDatabase::class);

test('store login user activity when see a page', function () {
    $user = createUser();

    $response = actingAs($user)->get('/');
    $response->assertContent('milwad');

    // Assertions
    expect($user->name)->toBe(VisitMonitoring::first()->user->name);

    // DB Assertions
    assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 1);
    assertDatabaseHas(config('user-monitoring.visit_monitoring.table'), ['page' => url('/')]);
});

test('store activity without user when see a page', function () {
    $response = get('/');
    $response->assertContent('milwad');

    // Assertions
    expect(VisitMonitoring::first()->user)->toBeNull();

    // DB Assertions
    assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 1);
    assertDatabaseHas(config('user-monitoring.visit_monitoring.table'), ['page' => url('/')]);
});

test('check except pages are not store', function () {
    config()->set('user-monitoring.visit_monitoring.except_pages', ['/']);

    $response = get('/');
    $response->assertContent('milwad');

    // DB Assertions
    assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 0);
    assertDatabaseMissing(config('user-monitoring.visit_monitoring.table'), ['page' => url('/')]);
});

test('check except pages are not store with regex', function () {
    config()->set('user-monitoring.visit_monitoring.except_pages', ['user-monitoring/*']);

    get('user-monitoring/visit');

    // DB Assertions
    assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 0);
    assertDatabaseMissing(config('user-monitoring.visit_monitoring.table'), ['page' => url('user-monitoring/visit')]);
});

test('visit monitoring records didn"t store when turn_on key is off', function () {
    config()->set('user-monitoring.visit_monitoring.turn_on', false);

    $response = get('/');
    $response->assertContent('milwad');

    // DB Assertions
    assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 0);
    assertDatabaseMissing(config('user-monitoring.visit_monitoring.table'), ['page' => url('/')]);
});

// Ajax

test('visit monitoring store ajax requests', function () {
    get('/', ['X-Requested-With' => 'XMLHttpRequest']);

    // DB Assertions
    assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 1);
    assertDatabaseHas(config('user-monitoring.visit_monitoring.table'), ['id' => 1]);
});

test('visit monitoring skip store when ajax mode is off for ajax requests', function () {
    config()->set('user-monitoring.visit_monitoring.ajax_requests', false);

    get('/', ['X-Requested-With' => 'XMLHttpRequest']);

    // DB Assertions
    assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 0);
    assertDatabaseMissing(config('user-monitoring.visit_monitoring.table'), ['page' => 'http:\/\/localhost']);
});

test('visit monitoring skip store when guest mode is off and user not logged in', function () {
    config()->set('user-monitoring.visit_monitoring.guest_mode', false);

    $response = get('/');
    $response->assertContent('milwad');

    // DB Assertions
    assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 0);
    assertDatabaseMissing(config('user-monitoring.visit_monitoring.table'), ['page' => 'http:\/\/localhost']);
});

test('visit monitoring store when guest mode is off and user logged in', function () {
    config()->set('user-monitoring.visit_monitoring.guest_mode', false);

    $user = createUser();
    $response = actingAs($user)->get('/');
    $response->assertContent('milwad');

    // DB Assertions
    assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 1);
});

test('visit monitoring store when guest mode is on and user logged in', function () {
    config()->set('user-monitoring.visit_monitoring.guest_mode', true);

    $user = createUser();
    $response = actingAs($user)->get('/');
    $response->assertContent('milwad');

    // DB Assertions
    assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 1);
});

test('visit monitoring store when guest mode is on and user not logged in', function () {
    config()->set('user-monitoring.visit_monitoring.guest_mode', true);

    $response = get('/');
    $response->assertContent('milwad');

    // DB Assertions
    assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 1);
});

test('visit monitoring is store when config conditions are true', function () {
    config()->set('user-monitoring.visit_monitoring.conditions', [
        function (Request $request) {
            return true;
        },
    ]);

    $response = get('/');
    $response->assertContent('milwad');

    // DB Assertions
    assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 1);
});

test('visit monitoring is not store when config conditions are false', function () {
    config()->set('user-monitoring.visit_monitoring.conditions', [
        function (Request $request) {
            return false;
        },
    ]);

    $response = get('/');
    $response->assertContent('milwad');

    // DB Assertions
    assertDatabaseCount(config('user-monitoring.visit_monitoring.table'), 0);
});

/**
 * Create user and return it.
 */
function createUser(): \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model
{
    return User::query()->create([
        'name' => 'milwad',
        'email' => 'milwad@gmail.com',
        'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
    ]);
}
