<?php

use App\Enums\InvestmentStatus;
use App\Enums\InvestmentTransactionType;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Ledger interno por inversión + acreditaciones mensuales globales aplicadas al % vigente.
     */
    public function up(): void
    {
        $activeValue = InvestmentStatus::Active->value;

        Schema::table('investments', function (Blueprint $table): void {
            $table->decimal('capital_balance', 14, 2)->nullable()->after('amount');
            $table->unsignedSmallInteger('months_credited')->default(0)->after('duration_months');
        });

        Schema::create('platform_month_accruals', function (Blueprint $table): void {
            $table->id();
            $table->string('reference_month', 7);
            $table->decimal('applied_percent', 8, 4);
            $table->unsignedInteger('investments_credited')->default(0);
            $table->foreignId('processed_by')->nullable()->constrained('users')->nullOnDelete();
            $table->timestamp('processed_at')->useCurrent();
            $table->timestamps();

            $table->unique('reference_month');
        });

        Schema::create('investment_transactions', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('investment_id')->constrained()->cascadeOnDelete();
            $table->string('type', 24);
            $table->decimal('amount', 14, 2);
            $table->decimal('balance_after', 14, 2);
            $table->foreignId('platform_month_accrual_id')->nullable()->constrained('platform_month_accruals')->nullOnDelete();
            $table->unsignedSmallInteger('investment_month_index')->nullable();
            $table->decimal('applied_percent', 8, 4)->nullable();
            $table->timestamps();

            $table->index(['investment_id', 'type']);
        });

        DB::table('investments')
            ->where('status', $activeValue)
            ->update([
                'capital_balance' => DB::raw('amount'),
            ]);

        DB::table('investments')
            ->where('status', '!=', $activeValue)
            ->update([
                'capital_balance' => null,
            ]);

        $activeIds = DB::table('investments')
            ->where('status', $activeValue)
            ->pluck('id');

        foreach ($activeIds as $investmentId) {
            $exists = DB::table('investment_transactions')
                ->where('investment_id', $investmentId)
                ->exists();

            if ($exists) {
                continue;
            }

            $row = DB::table('investments')->where('id', $investmentId)->first();
            if ($row === null) {
                continue;
            }

            $balance = (string) $row->capital_balance;

            DB::table('investment_transactions')->insert([
                'investment_id' => $investmentId,
                'type' => InvestmentTransactionType::Deposit->value,
                'amount' => $row->amount,
                'balance_after' => $balance,
                'platform_month_accrual_id' => null,
                'investment_month_index' => null,
                'applied_percent' => null,
                'created_at' => now(),
                'updated_at' => now(),
            ]);
        }
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('investment_transactions');
        Schema::dropIfExists('platform_month_accruals');

        Schema::table('investments', function (Blueprint $table): void {
            $table->dropColumn(['capital_balance', 'months_credited']);
        });
    }
};
