<?php

namespace App\Services\FlatTrade;

use App\Models\Instrument;
use App\Models\MarketTick;
use App\Models\User;
use App\Services\Bot\PositionMonitorService;
use Illuminate\Console\Command;

class FlatTradeWebSocketService
{
    public function __construct(
        private PositionMonitorService $positionMonitor,
        private BrokerAccountResolver $resolver,
        private FlatTradeAuthService $auth,
    ) {}

    public function run(Command $command): void
    {
        $account = $this->resolver->marketFeedAccount();

        if (! $account) {
            $command->error('Admin market feed credentials not connected. Save admin API creds and complete OAuth.');
            while (true) {
                \App\Models\BotRuntimeState::heartbeat('websocket', 'waiting_admin_creds');
                sleep(30);
            }
        }

        $command->info("WebSocket using admin market feed: {$account->client_id}");
        $command->warn('Live WebSocket stream runs on VPS. Polling fallback active until WS session is attached.');

        while (true) {
            \App\Models\BotRuntimeState::heartbeat('websocket', 'running', [
                'feed_client' => $account->client_id,
                'mode' => 'admin_feed',
            ]);
            sleep(30);
        }
    }

    public function dispatchQuoteTick(string $token, float $ltp): void
    {
        $instrument = Instrument::where('token', $token)->first();
        if (! $instrument) {
            return;
        }

        MarketTick::create([
            'instrument_id' => $instrument->id,
            'ltp' => $ltp,
            'open' => $ltp,
            'high' => $ltp,
            'low' => $ltp,
            'close' => $ltp,
            'volume' => 0,
            'oi' => 0,
            'tick_at' => now(),
        ]);

        $users = User::whereHas('positions', function ($q) use ($instrument) {
            $q->where('is_open', true)->where('instrument_id', $instrument->id);
        })->get();

        foreach ($users as $user) {
            $this->positionMonitor->onTick($user, $token, $ltp);
        }
    }

    public function dispatchOrderUpdate(User $user, array $payload): void
    {
        if (($payload['reporttype'] ?? '') === 'Fill' || ($payload['status'] ?? '') === 'COMPLETE') {
            app(FlatTradeAccountSyncService::class)->syncUser($user);
            $this->positionMonitor->onOrderFill($user);
        }
    }

    public function marketFeedAccount(): ?\App\Models\BrokerAccount
    {
        return $this->resolver->marketFeedAccount();
    }
}
