<?php

namespace Tests\Feature;

use App\Models\User;
use App\Services\FixedCommissionDistributor;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Tests\TestCase;

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

        $this->createTables();
        $this->seedCommissionSettings();
    }

    public function test_terminal_collector_receives_remaining_activation_generations(): void
    {
        $collector = User::factory()->create([
            'referral_code' => FixedCommissionDistributor::TERMINAL_COLLECTOR_REFERRAL_CODE,
            'balance' => 0,
        ]);

        $middle = User::factory()->create([
            'referral_code' => 'MID-200',
            'referred_by' => FixedCommissionDistributor::TERMINAL_COLLECTOR_REFERRAL_CODE,
            'balance' => 0,
        ]);

        $user = User::factory()->create([
            'referral_code' => 'USR-300',
            'referred_by' => 'MID-200',
            'balance' => 0,
        ]);

        app(FixedCommissionDistributor::class)->creditActivationCommissions($user);

        $this->assertSame(10.0, (float) $middle->fresh()->balance);
        $this->assertSame(17.0, (float) $collector->fresh()->balance);

        $this->assertDatabaseHas('income_histories', [
            'user_id' => $middle->id,
            'source' => 'referral',
            'amount' => 10,
        ]);

        $this->assertDatabaseHas('income_histories', [
            'user_id' => $collector->id,
            'source' => 'referral',
            'amount' => 9,
        ]);

        $this->assertDatabaseHas('income_histories', [
            'user_id' => $collector->id,
            'source' => 'referral',
            'amount' => 8,
        ]);
    }

    public function test_terminal_collector_reversal_removes_remaining_verification_generations(): void
    {
        $collector = User::factory()->create([
            'referral_code' => FixedCommissionDistributor::TERMINAL_COLLECTOR_REFERRAL_CODE,
            'balance' => 0,
        ]);

        $middle = User::factory()->create([
            'referral_code' => 'MID-201',
            'referred_by' => FixedCommissionDistributor::TERMINAL_COLLECTOR_REFERRAL_CODE,
            'balance' => 0,
        ]);

        $user = User::factory()->create([
            'referral_code' => 'USR-301',
            'referred_by' => 'MID-201',
            'balance' => 0,
        ]);

        $distributor = app(FixedCommissionDistributor::class);
        $distributor->creditVerificationCommissions($user);
        $distributor->reverseVerificationCommissions($user);

        $this->assertSame(0.0, (float) $middle->fresh()->balance);
        $this->assertSame(0.0, (float) $collector->fresh()->balance);

        $this->assertDatabaseHas('income_histories', [
            'user_id' => $middle->id,
            'source' => 'referral_reversal',
            'amount' => -10,
        ]);

        $this->assertDatabaseHas('income_histories', [
            'user_id' => $collector->id,
            'source' => 'referral_reversal',
            'amount' => -9,
        ]);

        $this->assertDatabaseHas('income_histories', [
            'user_id' => $collector->id,
            'source' => 'referral_reversal',
            'amount' => -8,
        ]);
    }

    private function createTables(): void
    {
        Schema::dropIfExists('income_histories');
        Schema::dropIfExists('balance_logs');
        Schema::dropIfExists('fixed_commission_settings');
        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('fixed_commission_settings', function (Blueprint $table) {
            $table->id();
            $table->unsignedInteger('generation')->unique();
            $table->decimal('amount', 12, 2)->default(0);
            $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();
        });
    }

    private function seedCommissionSettings(): void
    {
        foreach ([1 => 10, 2 => 9, 3 => 8] as $generation => $amount) {
            Schema::getConnection()->table('fixed_commission_settings')->insert([
                'generation' => $generation,
                'amount' => $amount,
                'created_at' => now(),
                'updated_at' => now(),
            ]);
        }
    }
}
