<?php

namespace Tests\Feature;

use App\Http\Middleware\LogAdminActivity;
use App\Models\Admin;
use App\Models\User;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Schema;
use Tests\TestCase;

class AdminUserWithdrawHoldPermissionTest extends TestCase
{
    protected function setUp(): void
    {
        parent::setUp();

        $this->createTables();
        Config::set('admin_security.edit_password', 'EditSecret123');
    }

    public function test_sub_admin_with_only_scoped_permission_can_open_dedicated_withdraw_hold_page(): void
    {
        $admin = Admin::query()->create([
            'name' => 'Sub Admin',
            'email' => 'subadmin@example.com',
            'password' => Hash::make('CorrectPassword123'),
            'is_super_admin' => false,
            'project_permissions' => ['users_withdraw_hold'],
        ]);

        $user = User::query()->create([
            'name' => 'Member User',
            'email' => 'member@example.com',
            'password' => Hash::make('user-password'),
            'mobile' => '01700000000',
            'referral_code' => 'REF100',
            'withdraw_hold' => 0,
        ]);

        $response = $this->withoutMiddleware([
            LogAdminActivity::class,
        ])->actingAs($admin, 'admin')
            ->get(route('admin.users.withdraw-hold.edit', $user->id));

        $response->assertOk();
        $response->assertSee('Withdraw Hold');
        $response->assertDontSee('Update User');
    }

    public function test_sub_admin_with_only_scoped_permission_can_lookup_user_by_referral_code(): void
    {
        $admin = Admin::query()->create([
            'name' => 'Sub Admin',
            'email' => 'subadminlookup@example.com',
            'password' => Hash::make('CorrectPassword123'),
            'is_super_admin' => false,
            'project_permissions' => ['users_withdraw_hold'],
        ]);

        User::query()->create([
            'name' => 'Lookup User',
            'email' => 'lookup@example.com',
            'password' => Hash::make('user-password'),
            'mobile' => '01700000009',
            'referral_code' => 'LOOKUP100',
            'withdraw_hold' => 0,
        ]);

        $response = $this->withoutMiddleware([
            LogAdminActivity::class,
        ])->actingAs($admin, 'admin')
            ->get(route('admin.users.withdraw-hold.index', ['referral_code' => 'LOOKUP100']));

        $response->assertOk();
        $response->assertSee('Lookup User');
        $response->assertSee('LOOKUP100');
        $response->assertDontSee('Security Password');
    }

    public function test_sub_admin_with_only_scoped_permission_can_update_withdraw_hold_from_dedicated_route_without_password(): void
    {
        $admin = Admin::query()->create([
            'name' => 'Sub Admin',
            'email' => 'subadmin2@example.com',
            'password' => Hash::make('CorrectPassword123'),
            'is_super_admin' => false,
            'project_permissions' => ['users_withdraw_hold'],
        ]);

        $user = User::query()->create([
            'name' => 'Member User',
            'email' => 'member2@example.com',
            'password' => Hash::make('user-password'),
            'mobile' => '01700000001',
            'referral_code' => 'REF200',
            'withdraw_hold' => 0,
        ]);

        $response = $this->withoutMiddleware([
            LogAdminActivity::class,
        ])->actingAs($admin, 'admin')
            ->from(route('admin.users.withdraw-hold.edit', $user->id))
            ->post(route('admin.users.withdraw-hold.update', $user->id), [
                'withdraw_hold' => 1,
                'withdraw_hold_reason' => 'Manual hold for review',
            ]);

        $response->assertRedirect(route('admin.users.withdraw-hold.index', ['referral_code' => 'REF200']));
        $response->assertSessionHas('success');

        $user->refresh();
        $this->assertSame(1, (int) $user->withdraw_hold);
        $this->assertSame('Manual hold for review', $user->withdraw_hold_reason);
        $this->assertSame('Member User', $user->name);
    }

    public function test_sub_admin_with_only_scoped_permission_cannot_open_general_edit_page(): void
    {
        $admin = Admin::query()->create([
            'name' => 'Sub Admin',
            'email' => 'subadmin3@example.com',
            'password' => Hash::make('CorrectPassword123'),
            'is_super_admin' => false,
            'project_permissions' => ['users_withdraw_hold'],
        ]);

        $user = User::query()->create([
            'name' => 'Member User',
            'email' => 'member3@example.com',
            'password' => Hash::make('user-password'),
            'mobile' => '01700000002',
            'referral_code' => 'REF300',
            'withdraw_hold' => 0,
        ]);

        $response = $this->withoutMiddleware([
            LogAdminActivity::class,
        ])->actingAs($admin, 'admin')
            ->get(route('admin.users.edit', $user->id));

        $response->assertForbidden();
    }

    private function createTables(): void
    {
        Schema::dropIfExists('users');
        Schema::dropIfExists('admins');

        Schema::create('admins', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->boolean('is_super_admin')->default(false);
            $table->json('project_permissions')->nullable();
            $table->rememberToken();
            $table->timestamps();
        });

        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->string('mobile')->nullable();
            $table->string('referral_code')->nullable();
            $table->boolean('withdraw_hold')->default(false);
            $table->text('withdraw_hold_reason')->nullable();
            $table->rememberToken();
            $table->timestamps();
        });
    }
}
