<?php

namespace Database\Seeders;

use App\Services\BranchContext;
use App\Support\Simulation\SimulationOperationalFinanceExpectations;
use Carbon\Carbon;
use Illuminate\Database\Seeder;
use RuntimeException;

class SimulationSeeder extends Seeder
{
    public function run(BranchContext $context): void
    {
        if (! app()->environment('testing') && ! config('simulation.enabled')) {
            throw new RuntimeException(
                'Simulation seeding is disabled. Set SIMULATION_DATA_ENABLED=true only in an isolated validation environment.'
            );
        }

        $previousTestNow = Carbon::getTestNow();
        Carbon::setTestNow(Carbon::createFromFormat(
            'Y-m-d H:i:s',
            SimulationOperationalFinanceExpectations::AS_OF_DATE.' 12:00:00',
        ));

        try {
            // Keep the ordinary baseline seed authoritative and simulation data opt-in.
            // The whole simulation shares one as-of clock so account/model timestamps
            // cannot accidentally fall after the fixed accounting validation date.
            $this->call(DatabaseSeeder::class);

            $phase = (string) config('simulation.phase', 'full');
            $allowed = ['foundation', 'loan-lifecycle', 'loan-adjustments', 'operational-finance', 'operations-surfaces', 'report-reconciliation', 'full'];
            if (! in_array($phase, $allowed, true)) {
                throw new RuntimeException('Unsupported SIMULATION_PHASE. Use foundation, loan-lifecycle, loan-adjustments, operational-finance, operations-surfaces, report-reconciliation, or full.');
            }

            $context->systemWide(function () use ($phase): void {
                $this->call(Simulation\SimulationFoundationSeeder::class);

                if (in_array($phase, ['loan-lifecycle', 'loan-adjustments', 'operational-finance', 'operations-surfaces', 'report-reconciliation', 'full'], true)) {
                    $this->call(Simulation\SimulationLoanLifecycleSeeder::class);
                }

                if (in_array($phase, ['loan-adjustments', 'operational-finance', 'operations-surfaces', 'report-reconciliation', 'full'], true)) {
                    $this->call(Simulation\SimulationLoanAdjustmentSeeder::class);
                }

                if (in_array($phase, ['operational-finance', 'operations-surfaces', 'report-reconciliation', 'full'], true)) {
                    $this->call(Simulation\SimulationOpeningLedgerSeeder::class);
                    $this->call(Simulation\SimulationOperationalFinanceSeeder::class);
                }

                if (in_array($phase, ['operations-surfaces', 'report-reconciliation', 'full'], true)) {
                    $this->call(Simulation\SimulationOperationsSurfacesSeeder::class);
                }
            });
        } finally {
            Carbon::setTestNow($previousTestNow);
        }
    }
}
