<?php

namespace App\Http\Controllers\Dashboard\User;

use App\Models\User;
use App\Models\Trader;
use Illuminate\Http\Request;
use App\Models\CopyTradeRequest;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
use App\Mail\WalletConnected;
use App\Mail\CopyTradeStarted;
use App\Mail\CopyTradeLinkRequestReceived;
use App\Http\Requests\ConnectWalletRequest;
use App\Enum\CopyTradeRequestStatus;
use App\Enum\TraderStatus;
use App\Models\CopyTradeParticipant;
use App\Models\Transaction;
use App\Enum\TransactionType;
use App\Enum\TransactionMethod;
use App\Enum\TransactionDirection;
use App\Enum\TransactionStatus;
use Illuminate\Support\Facades\Cache;

class CopyTradeController extends Controller
{
    public function __construct()
    {
        $this->middleware(['registeredUser', 'kycVerification']);
    }

    /**
     * Display the copy trading landing page.
     */
    public function index(Request $request)
    {
        $user = Auth::user();

        $breadcrumbs = [
            ['label' => config('app.name'), 'url' => '/'],
            ['label' => 'Dashboard', 'url' => route('user.dashboard')],
            ['label' => 'Copy Trade', 'active' => true]
        ];

        $data = [
            'title' => 'Copy Trade',
            'user' => $user,
            'breadcrumbs' => $breadcrumbs,
        ];

        return view('dashboard.user.copy_trade.index', $data);
    }

    /**
     * Display the traders search page.
     */
    public function traders(Request $request)
    {
        $user = Auth::user();

        $traders = Trader::with(['user', 'recentPerformances'])->where('user_id', '!=', $user->id)->where('status', TraderStatus::ACTIVE)
            ->get();


        $breadcrumbs = [
            ['label' => config('app.name'), 'url' => '/'],
            ['label' => 'Dashboard', 'url' => route('user.dashboard')],
            ['label' => 'Copy Trade', 'url' => route('user.copy.trade.index')],
            ['label' => 'Traders', 'active' => true]
        ];

        // Get trader IDs that the user already has requests for
        $userRequestTraderIds = CopyTradeRequest::where('user_id', $user->id)
            ->pluck('trader_id')
            ->toArray();

        $data = [
            'title' => 'Traders',
            'user' => $user,
            'breadcrumbs' => $breadcrumbs,
            'traders' => $traders,
            'statuses' => CopyTradeRequestStatus::cases(),
            'userRequestTraderIds' => $userRequestTraderIds,
        ];

        return view('dashboard.user.copy_trade.traders', $data);
    }

    /**
     * Display the trader details page
     */
    public function traderDetails(string $traderUUID)
    {
        $user = Auth::user();

        $breadcrumbs = [
            ['label' => config('app.name'), 'url' => '/'],
            ['label' => 'Dashboard', 'url' => route('user.dashboard')],
            ['label' => 'Copy Trade', 'url' => route('user.copy.trade.index')],
            ['label' => 'Traders', 'url' => route('user.copy.trade.index')],
            ['label' => 'Trader Details', 'active' => true]
        ];

        $trader = Trader::with('user')
            ->where('uuid', $traderUUID)
            ->firstOrFail();

        $existingRequest = CopyTradeRequest::where('user_id', $user->id)
            ->where('trader_id', $trader->id)
            ->first();

        // Get all user's copy trade requests with traders
        $userRequests = CopyTradeRequest::with('trader.user')
            ->where('trader_id', $trader->id)
            ->where('user_id', $user->id)
            ->latest()
            ->get();

        $data = [
            'title' => 'Trader Details',
            'user' => $user,
            'breadcrumbs' => $breadcrumbs,
            'trader' => $trader,
            'userRequests' => $userRequests,
            'existingRequest' => $existingRequest,
            'statuses' => CopyTradeRequestStatus::cases(),
        ];

        return view('dashboard.user.copy_trade.trader_details', $data);
    }

    /**
     * Send link request to admin for approval
     */
    public function sendLinkRequest(string $traderUUID)
    {
        try {
            $trader = Trader::where('uuid', $traderUUID)->firstOrFail();
            $user = Auth::user();

            // Check if request already exists
            $existingRequest = CopyTradeRequest::where('user_id', $user->id)
                ->where('trader_id', $trader->id)
                ->first();

            if ($existingRequest) {
                DB::transaction(function () use ($user, $trader, $existingRequest) {
                    $existingRequest->update([
                        'trader_id' => $trader->id,
                        'user_id' => $user->id,
                        'status' => CopyTradeRequestStatus::PENDING->value,
                    ]);

                    // Notify admin via email
                    $admins = User::where('role', 'admin')->get();
                    foreach ($admins as $admin) {
                        Mail::to($admin->email)->send(new CopyTradeLinkRequestReceived($existingRequest));
                    }
                });

                return redirect()->back()
                    ->with('success', 'Link request re-sent successfully. Please wait for trader approval.');
            }

            DB::transaction(function () use ($user, $trader) {
                $request = CopyTradeRequest::create([
                    'trader_id' => $trader->id,
                    'user_id' => $user->id,
                    'status' => CopyTradeRequestStatus::PENDING->value,
                ]);

                // Notify admin via email
                $admins = User::where('role', 'admin')->get();
                foreach ($admins as $admin) {
                    Mail::to($admin->email)->send(new CopyTradeLinkRequestReceived($request));
                }
            });

            return redirect()->back()
                ->with('success', 'Link request sent successfully. Please wait for trader approval.');
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return redirect()->back()
                ->with('error', 'Unable to send link request.');
        }
    }

    /**
     * Show wallet connection page
     */
    public function connectWallet()
    {
        $user = Auth::user();

        // Check if user has an approved request
        if (!$user->hasApprovedCopyTradeRequest()) {
            return redirect()->route('user.copy.trade.index')
                ->with('error', 'You need an approved link request before connecting your wallet.');
        }

        $breadcrumbs = [
            ['label' => config('app.name'), 'url' => '/'],
            ['label' => 'Dashboard', 'url' => route('user.dashboard')],
            ['label' => 'Copy Trade', 'url' => route('user.copy.trade.index')],
            ['label' => 'Connect Wallet', 'active' => true]
        ];

        $data = [
            'title' => 'Connect Wallet',
            'user' => $user,
            'breadcrumbs' => $breadcrumbs,
        ];

        return view('dashboard.user.copy_trade.connect-wallet', $data);
    }

    /**
     * Show wallet connection instructions
     */
    public function walletInstructions()
    {
        $user = Auth::user();

        $breadcrumbs = [
            ['label' => config('app.name'), 'url' => '/'],
            ['label' => 'Dashboard', 'url' => route('user.dashboard')],
            ['label' => 'Copy Trade', 'url' => route('user.copy.trade.index')],
            ['label' => 'Wallet Instructions', 'active' => true]
        ];

        $data = [
            'title' => 'Wallet Connection Instructions',
            'user' => $user,
            'breadcrumbs' => $breadcrumbs,
        ];

        return view('dashboard.user.copy_trade.wallet-instructions', $data);
    }

    /**
     * Store wallet address
     */
    public function storeWallet(ConnectWalletRequest $request)
    {
        try {
            $user = Auth::user();

            DB::transaction(function () use ($user, $request) {
                $user->update([
                    'wallet_address' => $request->wallet_address,
                ]);
            });

            // Send confirmation email
            Mail::to($user->email)->send(new WalletConnected($user));

            return redirect()->route('user.copy.trade.automated')
                ->with('success', 'Wallet connected successfully.');
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return redirect()->route('user.copy.trade.wallet.connect')
                ->with('error', 'Unable to connect wallet.');
        }
    }

    /**
     * Disconnect wallet address
     */
    public function disconnectWallet()
    {
        try {
            $user = Auth::user();


            $user->update([
                'wallet_address' => null,
                'wallet_balance' => 0.00,
            ]);


            return redirect()->route('user.copy.trade.subscription')
                ->with('success', 'Wallet disconnected successfully.');
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return redirect()->route('user.copy.trade.subscription')
                ->with('error', 'Unable to disconnect wallet.');
        }
    }

    /**
     * Show automated process page
     */
    public function automatedProcess()
    {
        $user = Auth::user();

        if (!$user->hasConnectedWallet()) {
            return redirect()->route('user.copy.trade.wallet.connect')
                ->with('error', 'Please connect your wallet first.');
        }

        $breadcrumbs = [
            ['label' => config('app.name'), 'url' => '/'],
            ['label' => 'Dashboard', 'url' => route('user.dashboard')],
            ['label' => 'Copy Trade', 'url' => route('user.copy.trade.index')],
            ['label' => 'Automated Process', 'active' => true]
        ];

        $data = [
            'title' => 'Start Automated Process',
            'user' => $user,
            'breadcrumbs' => $breadcrumbs,
        ];

        return view('dashboard.user.copy_trade.automated-process', $data);
    }

    /**
     * Start automated copy trading process
     */
    public function startAutomatedProcess()
    {
        try {
            // Update request status
            $copyTradeRequest = CopyTradeRequest::where('user_id', Auth::user()->id)
                ->where('status', CopyTradeRequestStatus::APPROVED->value)
                ->firstOrFail();


            $copyTradeRequest->update(['is_automated_started' => true]);

            // Send confirmation email
            if ($copyTradeRequest->is_automated_started == false) {
                Mail::to(Auth::user()->email)->send(new CopyTradeStarted(Auth::user()));
            }


            return redirect()->route('user.copy.trade.history', $copyTradeRequest->trader->uuid)
                ->with('success', 'Automated copy trading process has been started.');
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            return redirect()->route('user.copy.trade.automated')
                ->with('error', 'Unable to start automated process.');
        }
    }

    /**
     * Show history for specific trader
     */
    public function history(string $traderUuid)
    {
        $user = Auth::user();
        $trader = Trader::where('uuid', $traderUuid)->firstOrFail();

        // Ensure user has approved request for this trader
        $request = CopyTradeRequest::where('user_id', $user->id)
            ->where('trader_id', $trader->id)
            ->where('status', CopyTradeRequestStatus::APPROVED->value)
            ->firstOrFail();

        // Get trade history for this specific trader
        $tradeHistory = CopyTradeParticipant::where('user_id', $user->id)
            ->whereHas('copyTrade', function ($q) use ($trader) {
                $q->where('trader_id', $trader->id);
            })
            ->with(['copyTrade'])
            ->orderBy('created_at', 'desc')
            ->paginate(15);

        // Calculate total unrealized profit for this user+trader
        $unrealizedProfit = CopyTradeParticipant::where('user_id', $user->id)
            ->whereHas('copyTrade', function ($q) use ($trader) {
                $q->where('trader_id', $trader->id);
            })
            ->sum('unrealized_profit');


        $breadcrumbs = [
            ['label' => config('app.name'), 'url' => '/'],
            ['label' => 'Dashboard', 'url' => route('user.dashboard')],
            ['label' => 'Copy Trade', 'url' => route('user.copy.trade.index')],
            ['label' => 'Trade History', 'active' => true]
        ];

        $data = [
            'title' => 'Trade History - ' . $trader->user->name,
            'user' => $user,
            'breadcrumbs' => $breadcrumbs,
            'trader' => $trader,
            'request' => $request,
            'tradeHistory' => $tradeHistory,

            'unrealizedProfit' => $unrealizedProfit,
        ];

        return view('dashboard.user.copy_trade.history', $data);
    }

    /**
     * Show user's copy trade subscriptions and activity
     */
    public function subscription()
    {
        $user = Auth::user();

        // Get approved subscriptions (traders user is copying)
        $subscriptions = CopyTradeRequest::with(['trader.user'])
            ->where('user_id', $user->id)
            ->where('status', CopyTradeRequestStatus::APPROVED->value)
            ->get();

        // Get trade history (trades where user participated)
        $tradeHistory = CopyTradeParticipant::with(['copyTrade.trader.user'])
            ->where('user_id', $user->id)
            ->orderBy('created_at', 'desc')
            ->paginate(10);

        $breadcrumbs = [
            ['label' => config('app.name'), 'url' => '/'],
            ['label' => 'Dashboard', 'url' => route('user.dashboard')],
            ['label' => 'Copy Trade', 'url' => route('user.copy.trade.index')],
            ['label' => 'My Subscriptions', 'active' => true]
        ];

        $data = [
            'title' => 'My Subscriptions & Activity',
            'user' => $user,
            'breadcrumbs' => $breadcrumbs,
            'subscriptions' => $subscriptions,
            'tradeHistory' => $tradeHistory,
        ];

        return view('dashboard.user.copy_trade.subscription', $data);
    }

    /**
     * Withdraw unrealized profit from a trader's copy trades
     */
    public function withdrawStore(Request $request, $traderUuid)
    {
        $user = Auth::user();
        $trader = Trader::where('uuid', $traderUuid)->firstOrFail();

        // Ensure user has approved request for this trader
        CopyTradeRequest::where('user_id', $user->id)
            ->where('trader_id', $trader->id)
            ->where('status', CopyTradeRequestStatus::APPROVED->value)
            ->firstOrFail();

        // Get all participants with unrealized profit for this user+trader
        $participants = CopyTradeParticipant::where('user_id', $user->id)
            ->whereHas('copyTrade', function ($q) use ($trader) {
                $q->where('trader_id', $trader->id);
            })
            ->where('unrealized_profit', '>', 0)
            ->get();

        $totalUnrealized = $participants->sum('unrealized_profit');

        if ($totalUnrealized <= 0) {
            return redirect()->back()->with('error', 'No unrealized profit available to withdraw.');
        }

        try {
            DB::beginTransaction();

            // Zero out unrealized profit on all participant records
            foreach ($participants as $participant) {
                $participant->update(['unrealized_profit' => 0]);
            }

            // Credit to wallet balance
            $user->increment('wallet_balance', $totalUnrealized);

            // Record transaction
            $meta['withdraw'] = [
                'trader_id' => $trader->id,
                'trader_name' => $trader->user->name,
                'source' => 'Copy Trade Unrealized Profit'
            ];

            Transaction::create([
                'user_id' => $user->id,
                'type' => TransactionType::WITHDRAW,
                'direction' => TransactionDirection::CREDIT,
                'description' => 'Copy Trade Profit Withdraw - ' . $trader->user->name,
                'amount' => $totalUnrealized,
                'method' => TransactionMethod::CRYPTO,
                'transaction_at' => now(),
                'reference_id' => generateReferenceId(),
                'status' => TransactionStatus::COMPLETED,
                'meta' => $meta
            ]);

            // Clear wallet balance cache
            if ($user->eth_address) {
                Cache::forget('wallet_balance_' . strtolower($user->eth_address));
            }

            DB::commit();

            return redirect()->route('user.copy.trade.history', $trader->uuid)
                ->with('success', 'Profit withdrawn to your wallet successfully.');
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error($e->getMessage());
            return redirect()->back()->with('error', 'Unable to process withdrawal request.');
        }
    }
}
