<?php

namespace App\Http\Controllers\Api\User;

use App\Http\Controllers\Controller;
use App\Http\Controllers\User\DashboardController;
use App\Http\Requests\Api\User\FundCardRequest;
use App\Http\Requests\Api\User\UpdateCardPinRequest;
use App\Models\Card;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Log;
use App\Models\Notification;

class CardApiController extends Controller
{
    protected $dashboardController;

    public function __construct()
    {
        $this->dashboardController = new DashboardController();
    }

    /**
     * Get all user cards
     * @return JsonResponse
     */
    public function index(): JsonResponse
    {
        try {
            $user = auth()->user();

            if (!$user->name || !$user->username || !$user->email || !$user->phone) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Please complete your profile first'
                ], 400);
            }

            $cards = Card::where('user_id', $user->id)
                ->orderBy('id', 'desc')
                ->get();

            return response()->json([
                'status' => 'success',
                'message' => 'Cards retrieved successfully',
                'data' => [
                    'cards' => $cards,
                    'total_cards' => $cards->count(),
                    'active_cards' => $cards->where('status', 'active')->count(),
                    'frozen_cards' => $cards->where('status', 'frozen')->count(),
                ]
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to fetch cards: ' . $e->getMessage());
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to fetch cards',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get single card details
     * @param int $id
     * @return JsonResponse
     */
    public function show($id): JsonResponse
    {
        try {
            $user = auth()->user();
            $card = Card::where('user_id', $user->id)->find($id);

            if (!$card) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Card not found'
                ], 404);
            }

            return response()->json([
                'status' => 'success',
                'message' => 'Card details retrieved successfully',
                'data' => [
                    'card' => $card
                ]
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to fetch card details: ' . $e->getMessage());
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to fetch card details',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Create a new virtual card
     * @return JsonResponse
     */
    public function store(): JsonResponse
    {
        try {
            $user = auth()->user();

            if (!$user) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'User not authenticated'
                ], 401);
            }

            // Check if user profile is complete
            if (!$user->name || !$user->username || !$user->email || !$user->phone) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Please complete your profile first'
                ], 400);
            }

            // Check if user has sufficient balance for card creation fee
            if ($user->balance < 100) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Insufficient funds. You need at least $100 to create a card.'
                ], 400);
            }

            // Check card creation limit (optional - you can set a limit)
            $existingCards = Card::where('user_id', $user->id)->count();
            if ($existingCards >= 20) { // Max 20 cards per user
                return response()->json([
                    'status' => 'error',
                    'message' => 'You have reached the maximum card limit (20 cards)'
                ], 400);
            }

            // Check if user has sudo_id, if not create one
            if (empty($user->sudo_id)) {
                Log::info('User does not have sudo_id, creating customer first', ['user_id' => $user->id]);
                
                // This will create the customer and set the sudo_id
                $customerResult = $this->dashboardController->createCustomer($user->name, $user->username, $user->email, $user->phone);
                
                if (isset($customerResult['data']['_id'])) {
                    $user->sudo_id = $customerResult['data']['_id'];
                    $user->save();
                    Log::info('Sudo customer created successfully', ['user_id' => $user->id, 'sudo_id' => $user->sudo_id]);
                } else {
                    Log::error('Failed to create Sudo customer', ['user_id' => $user->id, 'response' => $customerResult]);
                    return response()->json([
                        'status' => 'error',
                        'message' => 'Failed to create customer profile. Please try again.'
                    ], 500);
                }
            }

            $result = $this->dashboardController->createCard();
            
            if ($result instanceof \Illuminate\Http\JsonResponse) {
                $resultData = $result->getData(true);
                if (isset($resultData['message']) && strpos($resultData['message'], 'Failed') !== false) {
                    return response()->json([
                        'status' => 'error',
                        'message' => $resultData['message']
                    ], 500);
                }
            }

            // Get the latest card created by this user
            $card = Card::where('user_id', $user->id)->latest()->first();

            if (!$card) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Card was not created successfully'
                ], 500);
            }
            
            
            $notification = new Notification();
            $notification->user_id = auth()->user()->id;
            $notification->title = "Card creation";
            $notification->message = "Virtual card created successfully!";
            $notification->status = 0;
            $notification->save();

            return response()->json([
                'status' => 'success',
                'message' => 'Virtual card created successfully',
                'data' => [
                    'card' => $card
                ]
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to create card: ' . $e->getMessage(), [
                'trace' => $e->getTraceAsString(),
                'user_id' => auth()->id()
            ]);
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to create card',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Fund a card
     * @param FundCardRequest $request
     * @param int $id
     * @return JsonResponse
     */
    public function fund(FundCardRequest $request, $id): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'amount' => 'required|numeric|min:1|max:10000'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'status' => 'error',
                    'message' => $validator->errors()->first()
                ], 422);
            }

            $user = auth()->user();
            $card = Card::where('user_id', $user->id)->find($id);

            if (!$card) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Card not found'
                ], 404);
            }

            // Log card status for debugging
            Log::info('Card funding attempt', [
                'card_id' => $card->id,
                'card_status' => $card->status,
                'user_id' => $user->id,
                'amount' => $request->input('amount')
            ]);

            $amount = $request->input('amount');

            // Check if user has sufficient balance
            if ($user->balance < $amount) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Insufficient balance to fund the card'
                ], 400);
            }

            $result = $this->dashboardController->fundCard($request, $id);
            
            // Check if the result is an error response
            if (is_array($result) && isset($result['error'])) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Failed to fund card',
                    'error' => $result['error']
                ], 500);
            }

            // Deduct from user balance only if funding was successful
            $user->balance -= $amount;
            $user->save();
            
            $notification = new Notification();
            $notification->user_id = auth()->user()->id;
            $notification->title = "Card topup";
            $notification->message = "Card funded successfully!";
            $notification->status = 0;
            $notification->save();

            return response()->json([
                'status' => 'success',
                'message' => 'Card funded successfully',
                'data' => [
                    'card' => $card->fresh(),
                    'user_balance' => $user->balance
                ]
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to fund card: ' . $e->getMessage());
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to fund card',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Freeze a card
     * @param int $id
     * @return JsonResponse
     */
    public function freeze($id): JsonResponse
    {
        try {
            $user = auth()->user();
            $card = Card::where('user_id', $user->id)->find($id);

            if (!$card) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Card not found'
                ], 404);
            }

            if ($card->status === 'frozen') {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Card is already frozen'
                ], 400);
            }

            $result = $this->dashboardController->freezeCard($id);
            
            $notification = new Notification();
            $notification->user_id = auth()->user()->id;
            $notification->title = "Freeze card";
            $notification->message = "Card frozen successfully!";
            $notification->status = 0;
            $notification->save();

            return response()->json([
                'status' => 'success',
                'message' => 'Card frozen successfully',
                'data' => [
                    'card' => $card->fresh()
                ]
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to freeze card: ' . $e->getMessage());
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to freeze card',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Activate/Unfreeze a card
     * @param int $id
     * @return JsonResponse
     */
    public function activate($id): JsonResponse
    {
        try {
            $user = auth()->user();
            $card = Card::where('user_id', $user->id)->find($id);

            if (!$card) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Card not found'
                ], 404);
            }

            if ($card->status === 'active') {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Card is already active'
                ], 400);
            }

            $result = $this->dashboardController->activateCard($id);
            
            $notification = new Notification();
            $notification->user_id = auth()->user()->id;
            $notification->title = "Activate card";
            $notification->message = "Card activated successfully!";
            $notification->status = 0;
            $notification->save();

            return response()->json([
                'status' => 'success',
                'message' => 'Card activated successfully',
                'data' => [
                    'card' => $card->fresh()
                ]
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to activate card: ' . $e->getMessage());
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to activate card',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get card transactions/history
     * @param int $id
     * @return JsonResponse
     */
    public function transactions($id): JsonResponse
    {
        try {
            $user = auth()->user();
            $card = Card::where('user_id', $user->id)->find($id);

            if (!$card) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Card not found'
                ], 404);
            }

            // Here you would typically fetch transactions from your transactions table
            // or from the external card provider's API
            // For now, we'll return a placeholder structure
            $transactions = [
                // This is where you'd fetch real transaction data
                // Example structure:
                // [
                //     'id' => 1,
                //     'type' => 'debit',
                //     'amount' => 50.00,
                //     'description' => 'Online Purchase',
                //     'merchant' => 'Amazon',
                //     'status' => 'completed',
                //     'created_at' => '2024-01-15 10:30:00'
                // ]
            ];

            return response()->json([
                'status' => 'success',
                'message' => 'Card transactions retrieved successfully',
                'data' => [
                    'card' => $card,
                    'transactions' => $transactions,
                    'total_transactions' => count($transactions)
                ]
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to fetch card transactions: ' . $e->getMessage());
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to fetch card transactions',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Update card PIN
     * @param UpdateCardPinRequest $request
     * @param int $id
     * @return JsonResponse
     */
    public function updatePin(UpdateCardPinRequest $request, $id): JsonResponse
    {
        try {
            $validator = Validator::make($request->all(), [
                'current_pin' => 'required|string|size:4',
                'new_pin' => 'required|string|size:4|different:current_pin',
                'confirm_pin' => 'required|string|same:new_pin'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'status' => 'error',
                    'message' => $validator->errors()->first()
                ], 422);
            }

            $user = auth()->user();
            $card = Card::where('user_id', $user->id)->find($id);

            if (!$card) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Card not found'
                ], 404);
            }

            $currentPin = $request->input('current_pin');
            $newPin = $request->input('new_pin');

            // Verify current PIN
            if ($card->pin !== $currentPin) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Current PIN is incorrect'
                ], 400);
            }

            // Update PIN
            $card->pin = $newPin;
            $card->save();
            
            $notification = new Notification();
            $notification->user_id = auth()->user()->id;
            $notification->title = "Update card PIN";
            $notification->message = "Card PIN updated successfully!";
            $notification->status = 0;
            $notification->save();

            return response()->json([
                'status' => 'success',
                'message' => 'Card PIN updated successfully'
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to update card PIN: ' . $e->getMessage());
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to update card PIN',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get card balance
     * @param int $id
     * @return JsonResponse
     */
    public function balance($id): JsonResponse
    {
        try {
            $user = auth()->user();
            $card = Card::where('user_id', $user->id)->find($id);

            if (!$card) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Card not found'
                ], 404);
            }

            return response()->json([
                'status' => 'success',
                'message' => 'Card balance retrieved successfully',
                'data' => [
                    'card_id' => $card->id,
                    'balance' => $card->amount,
                    'currency' => 'USD',
                    'last_updated' => $card->updated_at
                ]
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to fetch card balance: ' . $e->getMessage());
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to fetch card balance',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Toggle card status (freeze/activate)
     * @param int $id
     * @return JsonResponse
     */
    public function toggleStatus($id): JsonResponse
    {
        try {
            $user = auth()->user();
            $card = Card::where('user_id', $user->id)->find($id);

            if (!$card) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Card not found'
                ], 404);
            }

            if ($card->status === 'active') {
                $result = $this->dashboardController->freezeCard($id);
                $message = 'Card frozen successfully';
            } else {
                $result = $this->dashboardController->activateCard($id);
                $message = 'Card activated successfully';
            }

            return response()->json([
                'status' => 'success',
                'message' => $message,
                'data' => [
                    'card' => $card->fresh()
                ]
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to toggle card status: ' . $e->getMessage());
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to toggle card status',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Delete/Cancel a card
     * @param int $id
     * @return JsonResponse
     */
    public function destroy($id): JsonResponse
    {
        try {
            $user = auth()->user();
            $card = Card::where('user_id', $user->id)->find($id);

            if (!$card) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Card not found'
                ], 404);
            }

            // Check if card has balance
            if ($card->amount > 0) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Cannot delete a card with remaining balance. Please withdraw all funds first.'
                ], 400);
            }

            // Here you would typically also call the external API to cancel the card
            // For now, we'll just update the status and soft delete
            $card->status = 'cancelled';
            $card->save();
            $card->delete();
            
            $notification = new Notification();
            $notification->user_id = auth()->user()->id;
            $notification->title = "Cancel card";
            $notification->message = "Card cancelled successfully!";
            $notification->status = 0;
            $notification->save();

            return response()->json([
                'status' => 'success',
                'message' => 'Card cancelled successfully'
            ]);
        } catch (\Exception $e) {
            Log::error('Failed to delete card: ' . $e->getMessage());
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to cancel card',
                'error' => $e->getMessage()
            ], 500);
        }
    }
}
