<?php

namespace App\Console\Commands;

use App\Models\BotRuntimeState;
use App\Models\User;
use App\Services\Bot\EntryEngine;
use App\Services\Bot\PositionSyncService;
use App\Services\MarketData\MarketDataSyncService;
use Illuminate\Console\Command;

class BotScanCommand extends Command
{
    protected $signature = 'bot:scan {--once : Run one scan cycle and exit}';

    protected $description = 'Scan ATM±5 strikes and evaluate entry rules every 180 seconds';

    public function handle(
        MarketDataSyncService $marketSync,
        EntryEngine $entryEngine,
        PositionSyncService $positionSync,
    ): int {
        $this->info('Bot scanner started');

        do {
            BotRuntimeState::heartbeat('bot_scan', 'running');

            try {
                $instruments = $marketSync->syncScanUniverse();
                $spot = $marketSync->fetchNiftySpot();
            } catch (\Throwable $e) {
                $this->error($e->getMessage());
                BotRuntimeState::heartbeat('bot_scan', 'failed', ['error' => $e->getMessage()]);
                sleep(60);
                continue;
            }

            $context = [
                'spot' => $spot,
                'vwap' => $spot - 5,
                'ema20' => $spot - 10,
                'ema50' => $spot - 20,
                'expiry' => now()->next('Thursday'),
            ];

            $users = User::where('role', 'user')
                ->whereHas('botSettings', fn ($q) => $q->where('auto_trade', true)->where('bot_enabled', true))
                ->with(['brokerAccount', 'strategy', 'botSettings'])
                ->get();

            foreach ($users as $user) {
                $positionSync->syncUser($user);
                $entryEngine->scanUser($user, $instruments, $context);
            }

            if ($this->option('once')) {
                break;
            }

            sleep((int) (config('rulebook.global_rules.scan_interval_seconds') ?? 180));
        } while (true);

        return self::SUCCESS;
    }
}
