<?php

namespace App\Nexus\Console\Commands;

use App\Models\Bid;
use App\Nexus\Engine\BidEvaluator;
use App\Nexus\Engine\NexusConfig;
use App\Nexus\Engine\TradeExecutor;
use App\Nexus\Models\NexusSession;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

/**
 * Evaluates all pending manual bids that have reached the 1-hour evaluation window.
 * Runs every 2 minutes via Laravel scheduler.
 *
 * Bids are evaluated 1 hour after placement (bid_time + 1hr).
 * Does NOT require an active session -- a bid placed at 17:30 during Session 3
 * evaluates at 18:30 even though Session 3 closed at 18:00.
 * Uses the most recent session for criteria profile (weights, win cap, loss requirement).
 */
class NexusProcessBids extends Command
{
    protected $signature = 'nexus:process-bids';
    protected $description = 'NEXUS: Evaluate pending manual bids that have reached 1hr evaluation window';

    public function handle(): void
    {
        if (!NexusConfig::isNexusActive()) return;
        if (NexusConfig::isEmergencyPaused()) return;

        // Get the most recent session for its criteria profile.
        // Active preferred, but processing/completed also valid
        // (bids can mature after their session closes).
        $session = NexusSession::whereIn('status', [
            NexusSession::STATUS_ACTIVE,
            NexusSession::STATUS_PROCESSING,
            NexusSession::STATUS_COMPLETED,
        ])->orderBy('id', 'desc')->first();

        if (!$session) return; // No sessions have ever run

        $pendingBids = Bid::where('type', 'manual_bid')
            ->where('status', 0)
            ->where('bid_time', '<=', Carbon::now()->subHours(1))
            ->orderBy('bid_time', 'asc')
            ->get();

        if ($pendingBids->isEmpty()) return;

        $evaluator = new BidEvaluator(new TradeExecutor());

        $won = 0;
        $lost = 0;
        $errors = 0;

        foreach ($pendingBids as $bid) {
            try {
                $result = $evaluator->evaluate($bid, $session);

                if ($result->isApproved() || $result->isGuaranteed()) {
                    $won++;
                } else {
                    $lost++;
                }
            } catch (\Throwable $e) {
                $errors++;
                Log::error('[NEXUS] process-bids failed for bid #' . $bid->id, [
                    'bid_id'  => $bid->id,
                    'user_id' => $bid->user_id,
                    'error'   => $e->getMessage(),
                ]);
            }
        }

        $total = $won + $lost;
        if ($total > 0 || $errors > 0) {
            $this->info("Bids evaluated: {$total} | Won: {$won} | Lost: {$lost} | Errors: {$errors}");
            Log::info('[NEXUS] process-bids complete', [
                'evaluated'  => $total,
                'won'        => $won,
                'lost'       => $lost,
                'errors'     => $errors,
                'session_id' => $session->id,
            ]);
        }
    }
}
