<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreBrokerCredentialsRequest;
use App\Services\FlatTrade\FlatTradeAccountSyncService;
use App\Services\FlatTrade\FlatTradeAuthService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class BrokerController extends Controller
{
    public function __construct(
        private FlatTradeAuthService $auth,
        private FlatTradeAccountSyncService $sync,
    ) {}

    public function show(): View
    {
        $user = auth()->user();
        $broker = $user->brokerAccount;

        return view('trading.broker', [
            'data' => app(\App\Services\DashboardService::class)->overview($user),
            'broker' => $broker,
            'canConnect' => $broker && $this->auth->hasCredentials($broker),
            'authUrl' => $broker && $this->auth->hasCredentials($broker)
                ? $this->auth->getAuthorizationUrl($broker)
                : null,
            'isAdminFeed' => $user->isAdmin(),
            'pageTitle' => 'FlatTrade Account',
            'pageSubtitle' => $user->isAdmin()
                ? 'Your API credentials power shared market data (WebSocket) for all users'
                : 'Your API credentials are used only for your trades and account sync',
        ]);
    }

    public function storeCredentials(StoreBrokerCredentialsRequest $request): RedirectResponse
    {
        $user = auth()->user();
        $existing = $user->brokerAccount;
        $apiSecret = $request->input('api_secret');

        if (! filled($apiSecret)) {
            if (! $existing?->api_secret) {
                return back()->withErrors(['api_secret' => 'API Secret is required for first-time setup.']);
            }
            $apiSecret = \Illuminate\Support\Facades\Crypt::decryptString($existing->api_secret);
        }

        $this->auth->saveCredentials($user, $request->validated('api_key'), $apiSecret);

        return redirect()->route('broker')->with('status', 'FlatTrade API credentials saved.');
    }

    public function redirect(): RedirectResponse
    {
        $broker = auth()->user()->brokerAccount;

        if (! $broker || ! $this->auth->hasCredentials($broker)) {
            return redirect()->route('broker')->withErrors([
                'broker' => 'Save your FlatTrade API Key and Secret before connecting.',
            ]);
        }

        return redirect()->away($this->auth->getAuthorizationUrl($broker));
    }

    public function callback(Request $request): RedirectResponse
    {
        $code = $request->query('code');
        if (! $code) {
            return redirect()->route('broker')->withErrors(['broker' => 'Authorization code missing.']);
        }

        try {
            $this->auth->handleCallback(auth()->user(), $code);
        } catch (\Throwable $e) {
            $message = $e->getMessage();
            if (str_contains($message, 'INVALID_IP')) {
                $message = 'FlatTrade rejected the request: server IP is not whitelisted. Add your hosting/VPS static IP in FlatTrade Pi API settings, then click Connect OAuth again.';
            }

            return redirect()->route('broker')->withErrors(['broker' => $message]);
        }

        return redirect()->route('broker')->with('status', 'FlatTrade connected and account data synced.');
    }

    public function disconnect(): RedirectResponse
    {
        $account = auth()->user()->brokerAccount;
        if ($account) {
            $account->update([
                'is_connected' => false,
                'access_token' => null,
                'token_expires_at' => null,
            ]);
        }

        return redirect()->route('broker')->with('status', 'FlatTrade disconnected.');
    }

    public function syncNow(): RedirectResponse
    {
        $user = auth()->user();
        $broker = $user->brokerAccount;

        if (! $broker || ! $this->auth->isTokenValid($broker)) {
            return redirect()->route('broker')->withErrors([
                'broker' => 'Connect FlatTrade first to sync account data.',
            ]);
        }

        $ok = $this->sync->syncUser($user);

        return redirect()->route('broker')->with(
            'status',
            $ok ? 'Account synced: balance, positions, orders and P&L updated.' : 'Sync failed. Check credentials and token.'
        );
    }
}
