<?php

use App\Models\AdminRole;
use App\Models\AdminUser;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(RefreshDatabase::class);

beforeEach(function (): void {
    $this->artisan('lottery:admin-auth-sync')->assertExitCode(0);
});

test('agent role can be deleted when no users assigned', function (): void {
    $siteId = (int) DB::table('admin_sites')->where('is_default', true)->value('id');
    $rootId = (int) DB::table('agent_nodes')->where('admin_site_id', $siteId)->where('depth', 0)->value('id');

    $super = AdminUser::query()->create([
        'username' => 'destroy_role_super',
        'name' => 'Super',
        'email' => null,
        'password' => Hash::make('secret-strong'),
        'status' => 0,
    ]);
    grantSuperAdminRole($super);
    $token = $super->createToken('test', ['*'], now()->addDay())->plainTextToken;

    $branch = app(\App\Services\Agent\AgentNodeService::class)->createChild($super, [
        'parent_id' => $rootId,
        'code' => 'destroy-role-branch',
        'name' => 'Destroy Role Branch',
    ]);

    $role = AdminRole::query()->create([
        'slug' => 'deletable_role',
        'name' => 'Deletable',
        'scope_type' => AdminRole::SCOPE_AGENT,
        'owner_agent_id' => $branch->id,
    ]);
    $role->syncLegacyPermissionSlugs(['prd.agent.role.view']);

    $this->withHeader('Authorization', 'Bearer '.$token)
        ->deleteJson('/api/v1/admin/agent-roles/'.$role->id)
        ->assertOk();

    expect(AdminRole::query()->find($role->id))->toBeNull();
});

test('agent role cannot be deleted while assigned to a user', function (): void {
    $siteId = (int) DB::table('admin_sites')->where('is_default', true)->value('id');
    $rootId = (int) DB::table('agent_nodes')->where('admin_site_id', $siteId)->where('depth', 0)->value('id');

    $super = AdminUser::query()->create([
        'username' => 'destroy_role_blocked_super',
        'name' => 'Super',
        'email' => null,
        'password' => Hash::make('secret-strong'),
        'status' => 0,
    ]);
    grantSuperAdminRole($super);
    $token = $super->createToken('test', ['*'], now()->addDay())->plainTextToken;

    $branch = app(\App\Services\Agent\AgentNodeService::class)->createChild($super, [
        'parent_id' => $rootId,
        'code' => 'destroy-role-blocked',
        'name' => 'Blocked Branch',
    ]);

    $role = AdminRole::query()->create([
        'slug' => 'blocked_role',
        'name' => 'Blocked',
        'scope_type' => AdminRole::SCOPE_AGENT,
        'owner_agent_id' => $branch->id,
    ]);
    $role->syncLegacyPermissionSlugs(['prd.agent.role.view']);

    $user = app(\App\Services\Agent\AgentAdminUserService::class)->createUnderAgent($branch, [
        'username' => 'blocked_user',
        'nickname' => 'Blocked User',
        'password' => 'secret-strong-2',
        'role_ids' => [(int) $role->id],
    ]);

    expect($user->id)->toBeGreaterThan(0);

    $this->withHeader('Authorization', 'Bearer '.$token)
        ->deleteJson('/api/v1/admin/agent-roles/'.$role->id)
        ->assertStatus(422);
});

test('agent admin user can be deleted under agent node', function (): void {
    $siteId = (int) DB::table('admin_sites')->where('is_default', true)->value('id');
    $rootId = (int) DB::table('agent_nodes')->where('admin_site_id', $siteId)->where('depth', 0)->value('id');

    $super = AdminUser::query()->create([
        'username' => 'destroy_user_super',
        'name' => 'Super',
        'email' => null,
        'password' => Hash::make('secret-strong'),
        'status' => 0,
    ]);
    grantSuperAdminRole($super);
    $token = $super->createToken('test', ['*'], now()->addDay())->plainTextToken;

    $branch = app(\App\Services\Agent\AgentNodeService::class)->createChild($super, [
        'parent_id' => $rootId,
        'code' => 'destroy-user-branch',
        'name' => 'Destroy User Branch',
    ]);

    $user = app(\App\Services\Agent\AgentAdminUserService::class)->createUnderAgent($branch, [
        'username' => 'agent_delete_me',
        'nickname' => 'Delete Me',
        'password' => 'secret-strong-3',
        'role_ids' => [],
    ]);

    $this->withHeader('Authorization', 'Bearer '.$token)
        ->deleteJson('/api/v1/admin/agent-admin-users/'.$user->id)
        ->assertOk()
        ->assertJsonPath('data.deleted', true);

    expect(AdminUser::query()->find($user->id))->toBeNull();
    expect(DB::table('admin_user_agents')->where('admin_user_id', $user->id)->exists())->toBeFalse();
});
