<?php

namespace Tests\Feature;

use App\Http\Controllers\IncomeHistoryController;
use App\Models\IncomeHistory;
use App\Models\User;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Schema;
use Tests\TestCase;

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

        $this->createTables();
    }

    public function test_default_index_shows_only_authenticated_users_histories(): void
    {
        $viewer = User::factory()->create([
            'referral_code' => 'VIEW-100',
        ]);

        $other = User::factory()->create([
            'referral_code' => 'OTHER-100',
        ]);

        IncomeHistory::query()->create([
            'user_id' => $viewer->id,
            'source' => 'typing_job',
            'amount' => 5.00,
            'description' => 'নিজের typing job আয়।',
            'created_at' => now()->subMinute(),
            'updated_at' => now()->subMinute(),
        ]);

        IncomeHistory::query()->create([
            'user_id' => $other->id,
            'source' => 'referral',
            'amount' => 12.00,
            'description' => 'অভিনন্দন! আপনি ১ তম লেভেলের Viewer (VIEW-100) এর একাউন্ট ভেরিফিকেশন থেকে 12৳ কমিশন পেয়েছেন।',
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        $this->actingAs($viewer);

        $view = (new IncomeHistoryController())->index(
            Request::create('/income-history', 'GET')
        );

        $data = $view->getData();
        $histories = $data['histories'];

        $this->assertSame([5.0], $histories->getCollection()->pluck('amount')->map(fn ($amount) => (float) $amount)->all());
        $this->assertNull($data['searchedUser']);
        $this->assertFalse($data['isRelatedMemberSearch']);
    }

    public function test_referral_code_search_includes_related_member_commission_trail_for_unverified_member(): void
    {
        $viewer = User::factory()->create([
            'referral_code' => 'VIEW-200',
        ]);

        $targetMember = User::factory()->create([
            'name' => 'Target Member',
            'referral_code' => 'USR-301',
            'is_active' => 0,
        ]);

        $uplineOne = User::factory()->create([
            'referral_code' => 'UP-301',
        ]);

        $uplineTwo = User::factory()->create([
            'referral_code' => 'UP-302',
        ]);

        IncomeHistory::query()->create([
            'user_id' => $targetMember->id,
            'source' => 'typing_job',
            'amount' => 4.50,
            'description' => 'নিজস্ব typing job আয়।',
            'created_at' => now()->subMinutes(3),
            'updated_at' => now()->subMinutes(3),
        ]);

        IncomeHistory::query()->create([
            'user_id' => $uplineOne->id,
            'source' => 'referral',
            'amount' => 10.00,
            'description' => 'অভিনন্দন! আপনি ১ তম লেভেলের Target Member (USR-301) এর একাউন্ট ভেরিফিকেশন থেকে 10৳ কমিশন পেয়েছেন।',
            'created_at' => now()->subMinutes(2),
            'updated_at' => now()->subMinutes(2),
        ]);

        IncomeHistory::query()->create([
            'user_id' => $uplineTwo->id,
            'source' => 'referral_reversal',
            'amount' => -10.00,
            'description' => 'রিভার্সাল: Target Member (USR-301) এর একাউন্ট non-verify হওয়ায় 10৳ কমিশন সমন্বয় করা হয়েছে।',
            'created_at' => now()->subMinute(),
            'updated_at' => now()->subMinute(),
        ]);

        IncomeHistory::query()->create([
            'user_id' => $uplineTwo->id,
            'source' => 'referral',
            'amount' => 7.00,
            'description' => 'অভিনন্দন! আপনি ১ তম লেভেলের Other User (OTHER-999) এর একাউন্ট ভেরিফিকেশন থেকে 7৳ কমিশন পেয়েছেন।',
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        $this->actingAs($viewer);

        $view = (new IncomeHistoryController())->index(
            Request::create('/income-history', 'GET', ['referral_code' => 'USR-301'])
        );

        $data = $view->getData();
        $histories = $data['histories'];

        $this->assertCount(3, $histories->getCollection());
        $this->assertEqualsCanonicalizing(
            ['referral_reversal', 'referral', 'typing_job'],
            $histories->getCollection()->pluck('source')->all()
        );
        $this->assertEqualsCanonicalizing(
            [-10.0, 10.0, 4.5],
            $histories->getCollection()->pluck('amount')->map(fn ($amount) => (float) $amount)->all()
        );
        $this->assertTrue($data['isRelatedMemberSearch']);
        $this->assertSame($targetMember->id, $data['searchedUser']->id);
        $this->assertSame('USR-301', $data['searchedUser']->referral_code);
    }

    private function createTables(): void
    {
        Schema::dropIfExists('income_histories');
        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('profile_photo')->nullable();
            $table->string('referred_by')->nullable();
            $table->string('referral_code')->nullable();
            $table->decimal('balance', 12, 2)->default(0);
            $table->decimal('voucher_balance', 12, 2)->default(0);
            $table->boolean('is_active')->default(true);
            $table->dateTime('activated_at')->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();
        });
    }
}
