<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Wallet;
use App\Models\LedgerTransaction;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use App\Services\RealTimeSyncService;

class FinanceController extends Controller
{
    /**
     * Process a deposit
     */
    public function processDeposit(Request $request): JsonResponse
    {
        try {
            $validated = $request->validate([
                'amount' => 'required|numeric|min:0.01',
                'currency' => 'required|string|max:10',
                'payment_method' => 'required|string|max:50',
                'transaction_hash' => 'nullable|string|max:255',
                'external_reference' => 'nullable|string|max:255',
            ]);

            $user = $request->user();
            $amount = $validated['amount'];
            $currency = $validated['currency'];

            // Create ledger transaction
            $ledgerTransaction = DB::transaction(function () use ($user, $amount, $currency, $validated) {
                // Create the ledger transaction record
                $transaction = LedgerTransaction::create([
                    'user_id' => $user->id,
                    'type' => 'deposit',
                    'description' => 'Deposit of ' . $amount . ' ' . $currency . ' via ' . $validated['payment_method'],
                    'amount' => $amount,
                    'currency' => $currency,
                    'status' => 'completed',
                    'details' => [
                        'payment_method' => $validated['payment_method'],
                        'transaction_hash' => $validated['transaction_hash'] ?? null,
                        'external_reference' => $validated['external_reference'] ?? null,
                    ],
                ]);

                // Find or create user wallet for this currency
                $wallet = Wallet::firstOrCreate(
                    [
                        'user_id' => $user->id,
                        'currency' => $currency,
                    ],
                    [
                        'total_balance' => 0,
                        'available_balance' => 0,
                        'locked_balance' => 0,
                        'settled_balance' => 0,
                    ]
                );

                // Update wallet balances
                $wallet->total_balance += $amount;
                $wallet->available_balance += $amount;
                $wallet->save();

                // Synchronize wallet update
                $syncService = new RealTimeSyncService();
                $syncService->syncWallet($wallet, 'update');

                return $transaction;
            });

            return response()->json([
                'success' => true,
                'data' => $ledgerTransaction,
                'message' => 'Deposit processed successfully'
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Request a withdrawal
     */
    public function requestWithdrawal(Request $request): JsonResponse
    {
        try {
            $validated = $request->validate([
                'amount' => 'required|numeric|min:0.01',
                'currency' => 'required|string|max:10',
                'destination_address' => 'required|string|max:255',
                'payment_method' => 'nullable|string|max:50',
            ]);

            $user = $request->user();
            $amount = $validated['amount'];
            $currency = $validated['currency'];

            // Verify user has sufficient available balance
            $wallet = Wallet::forUserAndCurrency($user->id, $currency)->first();

            if (!$wallet || $wallet->available_balance < $amount) {
                return response()->json([
                    'success' => false,
                    'message' => 'Insufficient available balance'
                ], 400);
            }

            // Create withdrawal request
            $ledgerTransaction = DB::transaction(function () use ($user, $amount, $currency, $validated, $wallet) {
                // Create the ledger transaction record
                $transaction = LedgerTransaction::create([
                    'user_id' => $user->id,
                    'type' => 'withdrawal_request',
                    'description' => 'Withdrawal request of ' . $amount . ' ' . $currency . ' to ' . $validated['destination_address'],
                    'amount' => $amount,
                    'currency' => $currency,
                    'status' => 'pending_approval',
                    'details' => [
                        'destination_address' => $validated['destination_address'],
                        'payment_method' => $validated['payment_method'] ?? null,
                    ],
                ]);

                // Lock the funds (move from available to locked)
                $wallet->locked_balance += $amount;
                $wallet->available_balance -= $amount;
                $wallet->save();

                return $transaction;
            });

            return response()->json([
                'success' => true,
                'data' => $ledgerTransaction,
                'message' => 'Withdrawal request submitted successfully'
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Approve a withdrawal
     */
    public function approveWithdrawal(Request $request, string $transactionId): JsonResponse
    {
        try {
            $user = $request->user();
            
            // Only admins can approve withdrawals
            if (!$user->hasRole('admin')) {
                return response()->json([
                    'success' => false,
                    'message' => 'Unauthorized'
                ], 403);
            }

            $transaction = LedgerTransaction::where('id', $transactionId)
                                          ->where('type', 'withdrawal_request')
                                          ->where('status', 'pending_approval')
                                          ->first();

            if (!$transaction) {
                return response()->json([
                    'success' => false,
                    'message' => 'Transaction not found or not eligible for approval'
                ], 404);
            }

            DB::transaction(function () use ($transaction) {
                // Update transaction status
                $transaction->status = 'approved';
                $transaction->details = array_merge($transaction->details ?? [], [
                    'approved_by' => $request->user()->id,
                    'approved_at' => now(),
                ]);
                $transaction->save();

                // Find and update the corresponding wallet
                $wallet = Wallet::forUserAndCurrency($transaction->user_id, $transaction->currency)->first();
                if ($wallet) {
                    // Funds are already locked, so we just need to update the status
                    // Actual deduction happens upon completion
                }
            });

            return response()->json([
                'success' => true,
                'data' => $transaction->refresh(),
                'message' => 'Withdrawal approved successfully'
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Complete a withdrawal
     */
    public function completeWithdrawal(Request $request, string $transactionId): JsonResponse
    {
        try {
            $user = $request->user();
            
            // Only admins can complete withdrawals
            if (!$user->hasRole('admin')) {
                return response()->json([
                    'success' => false,
                    'message' => 'Unauthorized'
                ], 403);
            }

            $transaction = LedgerTransaction::where('id', $transactionId)
                                          ->where('type', 'withdrawal_request')
                                          ->where('status', 'approved')
                                          ->first();

            if (!$transaction) {
                return response()->json([
                    'success' => false,
                    'message' => 'Transaction not found or not eligible for completion'
                ], 404);
            }

            DB::transaction(function () use ($transaction) {
                // Update transaction status
                $transaction->status = 'completed';
                $transaction->details = array_merge($transaction->details ?? [], [
                    'completed_by' => $request->user()->id,
                    'completed_at' => now(),
                ]);
                $transaction->save();

                // Find and update the corresponding wallet
                $wallet = Wallet::forUserAndCurrency($transaction->user_id, $transaction->currency)->first();
                if ($wallet) {
                    // Deduct from total and locked balance
                    $wallet->total_balance -= $transaction->amount;
                    $wallet->locked_balance -= $transaction->amount;
                    $wallet->save();
                }
            });

            return response()->json([
                'success' => true,
                'data' => $transaction->refresh(),
                'message' => 'Withdrawal completed successfully'
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Get user's wallet balance
     */
    public function getWalletBalance(Request $request, string $currency): JsonResponse
    {
        try {
            $user = $request->user();
            
            $wallet = Wallet::forUserAndCurrency($user->id, $currency)->first();
            
            if (!$wallet) {
                return response()->json([
                    'success' => true,
                    'data' => [
                        'currency' => $currency,
                        'total_balance' => 0,
                        'available_balance' => 0,
                        'locked_balance' => 0,
                        'settled_balance' => 0,
                    ]
                ]);
            }

            return response()->json([
                'success' => true,
                'data' => [
                    'currency' => $currency,
                    'total_balance' => $wallet->total_balance,
                    'available_balance' => $wallet->available_balance,
                    'locked_balance' => $wallet->locked_balance,
                    'settled_balance' => $wallet->settled_balance,
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }

    /**
     * Get user's transaction history
     */
    public function getTransactionHistory(Request $request): JsonResponse
    {
        try {
            $user = $request->user();
            
            $transactions = LedgerTransaction::where('user_id', $user->id)
                                            ->with(['user'])
                                            ->latest()
                                            ->paginate(50);

            return response()->json([
                'success' => true,
                'data' => $transactions
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 400);
        }
    }
}