<?php

namespace Tests\Feature;

use App\Http\Controllers\Admin\SmartLeadershipAdminController;
use App\Models\SmartLeadershipReward;
use App\Models\User;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Schema;
use Tests\TestCase;

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

        $this->createTables();
    }

    public function test_user_can_claim_smart_leadership_reward_once_per_earned_cycle(): void
    {
        $user = User::factory()->create([
            'balance' => 0,
            'referral_code' => 'SMART-1001',
        ]);

        User::factory()->count(12)->create([
            'referred_by' => 'SMART-1001',
            'is_active' => 1,
        ]);

        $firstResponse = $this->actingAs($user)
            ->from('/smart-leadership')
            ->post(route('user.smart.leadership.claim'));

        $firstResponse->assertRedirect('/smart-leadership');
        $firstResponse->assertSessionHas('success');

        $this->assertDatabaseHas('smart_leadership_rewards', [
            'user_id' => $user->id,
            'level' => 1,
            'amount' => 120,
        ]);

        $this->assertDatabaseHas('balance_logs', [
            'user_id' => $user->id,
            'amount' => 120,
        ]);

        $this->assertDatabaseHas('income_histories', [
            'user_id' => $user->id,
            'source' => 'smart_leadership',
            'amount' => 120,
        ]);

        $this->assertSame(120.0, (float) $user->fresh()->balance);

        $secondResponse = $this->actingAs($user)
            ->from('/smart-leadership')
            ->post(route('user.smart.leadership.claim'));

        $secondResponse->assertRedirect('/smart-leadership');
        $secondResponse->assertSessionHas('error');
        $this->assertSame(1, SmartLeadershipReward::where('user_id', $user->id)->count());
        $this->assertSame(120.0, (float) $user->fresh()->balance);
    }

    public function test_admin_summary_and_details_use_smart_leadership_rewards_data(): void
    {
        $user = User::factory()->create([
            'referral_code' => 'SMART-2001',
            'mobile' => '01700000000',
        ]);

        SmartLeadershipReward::create([
            'user_id' => $user->id,
            'level' => 2,
            'amount' => 240,
        ]);

        $controller = new SmartLeadershipAdminController();

        $indexView = $controller->index(Request::create('/admin/smart-leadership', 'GET'));
        $indexData = $indexView->getData();

        $this->assertSame('admin.smart-leadership.index', $indexView->getName());
        $this->assertSame(1, (int) $indexData['summary']->total_claims);
        $this->assertSame(240.0, (float) $indexData['summary']->total_amount);
        $this->assertCount(1, $indexData['rewards']->items());
        $this->assertSame($user->id, $indexData['rewards']->items()[0]->user_id);

        $showView = $controller->show(Request::create('/admin/smart-leadership/' . $user->id, 'GET'), $user);
        $showData = $showView->getData();

        $this->assertSame('admin.smart-leadership.show', $showView->getName());
        $this->assertSame(1, (int) $showData['totals']->times);
        $this->assertSame(240.0, (float) $showData['totals']->total_amount);
        $this->assertCount(1, $showData['claims']->items());
        $this->assertSame(2, $showData['claims']->items()[0]->level);
        $this->assertSame(240.0, (float) $showData['claims']->items()[0]->amount);
    }

    private function createTables(): void
    {
        Schema::dropIfExists('income_histories');
        Schema::dropIfExists('balance_logs');
        Schema::dropIfExists('smart_leadership_rewards');
        Schema::dropIfExists('users');

        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->string('mobile')->nullable();
            $table->string('referred_by')->nullable();
            $table->string('referral_code')->nullable();
            $table->decimal('balance', 12, 2)->default(0);
            $table->boolean('is_active')->default(true);
            $table->dateTime('activated_at')->nullable();
            $table->timestamps();
        });

        Schema::create('smart_leadership_rewards', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id');
            $table->unsignedInteger('level');
            $table->decimal('amount', 12, 2)->default(0);
            $table->dateTime('claimed_at')->nullable();
            $table->timestamps();
        });

        Schema::create('balance_logs', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id');
            $table->decimal('amount', 12, 2)->default(0);
            $table->string('type')->nullable();
            $table->timestamps();
        });

        Schema::create('income_histories', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id');
            $table->string('source');
            $table->decimal('amount', 12, 2)->default(0);
            $table->text('description')->nullable();
            $table->timestamps();
        });
    }
}
