<?php

namespace App\Http\Controllers\Api\Admin;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\Transaction;
use App\Mail\Newsletter;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class UserApiController extends Controller
{
    
    // Restrict user withdrawals //$user->restricted = $request->restrict;
    public function restrictWithdrawals(Request $request, $id)
    {
        try {
            $validator = Validator::make($request->all(), [
                'status' => 'required|in:0,1',
            ]);

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

            $user = User::findOrFail($id);
            $user->restricted = $request->status;
            $user->save();
            

            return response()->json([
                'status' => 'success',
                'message' => 'User withdrawal restricted successfully',
                'data' => $user
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to restrict user withdrawal',
                'error' => $e->getMessage()
            ], 500);
        }
    }
    
    
    /**
     * Get all users with pagination and filtering
     */
 public function index(Request $request)
{
    try {
        $query = User::query();

        // =======================
        // SEARCH FUNCTIONALITY
        // =======================
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('name', 'LIKE', "%{$search}%")
                  ->orWhere('email', 'LIKE', "%{$search}%")
                  ->orWhere('username', 'LIKE', "%{$search}%");
            });
        }

        // =======================
        // FILTERS
        // =======================
        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        if ($request->filled('kyc_verified')) {
            $query->whereNotNull('kyc_verified_at');
            if ($request->kyc_verified == 0) {
                $query->whereNull('kyc_verified_at');
            }
        }

        if ($request->filled('date_from')) {
            $query->whereDate('created_at', '>=', $request->date_from);
        }
        if ($request->filled('date_to')) {
            $query->whereDate('created_at', '<=', $request->date_to);
        }

        $perPage = $request->per_page ?? 15;

        // =======================
        // LOAD RELATIONS WITH SUMS AND COUNTS
        // =======================
        $users = $query->withSum('deposits', 'amount')
                       ->withSum('withdrawals', 'amount')
                       ->withSum('botActivations', 'capital')
                       ->withCount('referredUsers') // your referral relationship
                       ->orderBy('created_at', 'desc')
                       ->paginate($perPage);

        // =======================
        // FORMAT SUMS TO 2 DECIMALS
        // =======================
        $users->getCollection()->transform(function ($user) {
            $user->deposits_sum_amount = number_format($user->deposits_sum_amount ?? 0, 2, '.', '');
            $user->withdrawals_sum_amount = number_format($user->withdrawals_sum_amount ?? 0, 2, '.', '');
            $user->bot_activations_sum_capital = number_format($user->bot_activations_sum_capital ?? 0, 2, '.', '');
            return $user;
        });

        return response()->json([
            'status' => 'success',
            'data' => $users
        ]);

    } catch (\Exception $e) {
        return response()->json([
            'status' => 'error',
            'message' => 'Failed to fetch users',
            'error' => $e->getMessage()
        ], 500);
    }
}


    /**
     * Get specific user details
     */
public function show(Request $request, $id)
{
    try {
        $perPage = 10; // default pagination

        $user = User::withCount('referredUsers')->findOrFail($id);

        // =======================
        // USER INFO - ALL COLUMNS
        // =======================
        $userStats = $user->toArray();

        // Add balances per currency
        $userStats['balances'] = [
            'usd' => number_format($user->balance ?? 0, 2, '.', ''),
            'ngn' => number_format($user->ngn_balance ?? 0, 2, '.', ''),
            'kes' => number_format($user->kes_balance ?? 0, 2, '.', ''),
        ];

        // =======================
        // FINANCIAL SUMS PER CURRENCY
        // =======================
        $financialSums = [
            'deposits' => [
                'usd' => number_format($user->deposits()->where('type', 'usd')->sum('amount'), 2, '.', ''),
                'ngn' => number_format($user->deposits()->where('type', 'ngn')->sum('amount'), 2, '.', ''),
                'kes' => number_format($user->deposits()->where('type', 'kes')->sum('amount'), 2, '.', ''),
            ],
            'withdrawals' => [
                'usd' => number_format($user->withdrawals()->where('currency', 'usd')->sum('amount'), 2, '.', ''),
                'ngn' => number_format($user->withdrawals()->where('currency', 'ngn')->sum('amount'), 2, '.', ''),
                'kes' => number_format($user->withdrawals()->where('currency', 'kes')->sum('amount'), 2, '.', ''),
            ],
            'bot_capital' => number_format($user->botActivations()->sum('capital'), 2, '.', ''),
        ];

        // =======================
        // PAGINATED LISTS
        // =======================
        $recent = [
            'deposits' => $user->deposits()->orderByDesc('created_at')->paginate($perPage),
            'withdrawals' => $user->withdrawals()->orderByDesc('created_at')->paginate($perPage),
            'transactions' => $user->transactions()->orderByDesc('created_at')->paginate($perPage),
            'bot_activations' => $user->botActivations()->orderByDesc('created_at')->paginate($perPage),
        ];

        // Format the paginated results
        $recent = collect($recent)->map(function($page, $key) {
            return $page->through(function($item) use ($key) {
                return match($key) {
                    'deposits' => [
                        'id' => $item->id,
                        'amount' => number_format($item->amount, 2, '.', ''),
                        'type' => $item->type,
                        'status' => $item->status,
                        'created_at' => $item->created_at->toDateTimeString(),
                    ],
                    'withdrawals' => [
                        'id' => $item->id,
                        'amount' => number_format($item->amount, 2, '.', ''),
                        'currency' => $item->currency,
                        'status' => $item->status,
                        'created_at' => $item->created_at->toDateTimeString(),
                    ],
                    'transactions' => [
                        'id' => $item->id,
                        'amount' => number_format($item->amount, 2, '.', ''),
                        'type' => $item->type,
                        'status' => $item->status,
                        'created_at' => $item->created_at->toDateTimeString(),
                    ],
                    'bot_activations' => [
                        'id' => $item->id,
                        'capital' => number_format($item->capital, 2, '.', ''),
                        'status' => $item->status,
                        'plan_id' => $item->plan_id,
                        'created_at' => $item->created_at->toDateTimeString(),
                    ],
                };
            });
        });

        // =======================
        // REFERRALS
        // =======================
        $referrals = $user->referredUsers()->paginate($perPage);

        // =======================
        // SUCCESS RESPONSE
        // =======================
        return response()->json([
            'status' => 'success',
            'data' => [
                'user' => $userStats,
                'financial' => $financialSums,
                'referrals' => $referrals,
                'all' => $recent,
            ]
        ]);

    } catch (\Exception $e) {
        return response()->json([
            'status' => 'error',
            'message' => 'User not found',
            'error' => $e->getMessage()
        ], 404);
    }
}



    /**
     * Update user status
     */
    public function updateStatus(Request $request, $id)
    {
        try {
            $validator = Validator::make($request->all(), [
                'status' => 'required|in:0,1',
                'reason' => 'nullable|string|max:255'
            ]);

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

            $user = User::findOrFail($id);
            $user->update([
                'status' => $request->status,
                'status_reason' => $request->reason
            ]);

            return response()->json([
                'status' => 'success',
                'message' => 'User status updated successfully',
                'data' => $user
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to update user status',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Update user details
     */
    public function update(Request $request, $id)
    {
        try {
            $user = User::findOrFail($id);

            $validator = Validator::make($request->all(), [
                'name' => 'required|string|max:255',
                'email' => 'required|email|unique:users,email,' . $id,
                // 'username' => 'required|string|unique:users,username,' . $id,
                'phone' => 'nullable|string|max:20',
                'country' => 'nullable|string|max:100',
                'city' => 'nullable|string|max:100',
                'address' => 'nullable|string|max:500',
                'postal_code' => 'nullable|string|max:20',
                'kyc_verified' => 'boolean',
                'email_verified' => 'boolean',
            ]);

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

            $data = $validator->validated();
            
            // Handle email verification
            if (isset($data['email_verified'])) {
                $data['email_verified_at'] = $data['email_verified'] ? now() : null;
                unset($data['email_verified']);
            }

            $user->update($data);

            return response()->json([
                'status' => 'success',
                'message' => 'User updated successfully',
                'data' => $user
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to update user',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Credit or debit user balance (matches original logic)
     */
    public function creditDebit(Request $request, $id)
    {
        try {
            $validator = Validator::make($request->all(), [
                'amount' => 'required|numeric|min:0.01',
                'currency' => 'required|string|in:usd,ngn,kes',
                'type' => 'required|in:credit,debit',
                'description' => 'required|string|max:500',
                'platform' => 'nullable|string'
            ]);
    
            if ($validator->fails()) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Validation failed',
                    'errors' => $validator->errors()
                ], 422);
            }
    
            DB::beginTransaction();
    
            $user = User::findOrFail($id);
    
            $amount = (float) $request->amount;
            $type = $request->type;
            $description = $request->description;
            $currency = $request->currency;
    
            // Determine wallet field based on platform and currency
            if ($request->platform === 'cbcnet') {
                $balanceField = 'cbc_balance';
            } else {
                switch ($currency) {
                    case 'ngn':
                        $balanceField = 'ngn_balance';
                        break;
                    case 'kes':
                        $balanceField = 'kes_balance';
                        break;
                    case 'usd':
                    default:
                        $balanceField = 'balance';
                        break;
                }
            }
    
            $currentBalance = (float) $user->$balanceField;
    
            // Check balance if debit
            if ($type === 'debit' && $currentBalance < $amount) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Insufficient balance'
                ], 400);
            }
    
            // Calculate and update balance
            $new_balance = $type === 'credit'
                ? $currentBalance + $amount
                : $currentBalance - $amount;
    
            $user->$balanceField = $new_balance;
            $user->save();
    
            // Record transaction
            if (function_exists('recordNewTransaction')) {
                // Note: If recordNewTransaction accepts a currency parameter, you may want to include it here
                recordNewTransaction($amount, $user->id, $type, $description);
            }
    
            DB::commit();
    
            $message = $user->username . ($type === 'credit'
                ? ' has been credited'
                : ' has been debited');
    
            return response()->json([
                'status' => 'success',
                'message' => $message,
                'data' => [
                    'user' => $user->fresh(),
                    'new_balance' => $new_balance,
                    'currency' => $currency
                ]
            ]);
    
        } catch (\Exception $e) {
            DB::rollBack();
    
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to process balance update',
                'error' => $e->getMessage()
            ], 500);
        }
    }    
    
    /**
     * Send email to user
     */
    public function sendEmail(Request $request, $id)
    {
        try {
            $validator = Validator::make($request->all(), [
                'subject' => 'required|string|max:255',
                'message' => 'required|string'
            ]);

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

            $user = User::findOrFail($id);
            
            // Send email using Newsletter mailable
            Mail::to($user->email)->send(new Newsletter($request->subject, $request->message));

            return response()->json([
                'status' => 'success',
                'message' => 'Email sent successfully to ' . $user->email
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to send email',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Change user password
     */
    public function changePassword(Request $request, $id)
    {
        try {
            $validator = Validator::make($request->all(), [
                'password' => 'required|string|min:6|confirmed'
            ]);

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

            $user = User::findOrFail($id);
            $user->update([
                'password' => Hash::make($request->password)
            ]);

            return response()->json([
                'status' => 'success',
                'message' => 'Password changed successfully'
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to change password',
                'error' => $e->getMessage()
            ], 500);
        }
    }
    
    
    /**
     * Change user pin
     */
    public function changePIN(Request $request, $id)
    {
        try {
            $validator = Validator::make($request->all(), [
                'pin' => 'required|min:4'
            ]);

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

            $user = User::findOrFail($id);
            $user->update([
                'pin' => $request->pin
            ]);

            return response()->json([
                'status' => 'success',
                'message' => 'Pin changed successfully'
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to change password',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Login as user (admin impersonation)
     */
    public function loginAsUser(Request $request, $id)
    {
        try {
            $user = User::findOrFail($id);
            
            if ($user->status != 1) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Cannot login as inactive user'
                ], 400);
            }

            // Generate token for the user
            $token = $user->createToken('admin-impersonation')->plainTextToken;

            return response()->json([
                'status' => 'success',
                'message' => 'Logged in as user successfully',
                'data' => [
                    'user' => $user,
                    'token' => $token,
                    'impersonated_by' => Auth::id()
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to login as user',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Delete user
     */
    public function destroy($id)
    {
        try {
            $user = User::findOrFail($id);
            
            // Check if user has active transactions or balances
            if ($user->deposit_wallet > 0 || $user->interest_wallet > 0 || $user->bonus_wallet > 0) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'Cannot delete user with active balances'
                ], 400);
            }

            $user->delete();

            return response()->json([
                'status' => 'success',
                'message' => 'User deleted successfully'
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to delete user',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Make user staff
     */
    public function makeStaff(Request $request)
    {
        $userId = $request->route('id');
        $user = User::find($userId);
    
        if (!$user) {
            return response()->json([
                'status' => 'error',
                'message' => 'User not found',
            ], 404);
        }
    
        // Toggle role (0 = normal user, 2 = staff)
        if ($user->role == 0) {
            $user->role = 2;
            $message = 'User upgraded to staff successfully';
        } else {
            $user->role = 0;
            $message = 'User reverted to normal user successfully';
        }
    
        $user->save();
    
        return response()->json([
            'status' => 'success',
            'message' => $message,
            'data' => [
                'user_id' => $user->id,
                'new_role' => $user->role
            ]
        ], 200);
    }


    /**
     * Bulk actions on users (matching original functionality)
     */
    public function bulkAction(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'selected_action' => 'required|in:suspend,activate,loser_mode_on,loser_mode_off,email,delete',
                'selected_ids' => 'required|string'
            ]);

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

            $action = $request->selected_action;
            $user_ids = explode(',', $request->selected_ids);
            
            // Operation message to return in response
            $operation = ucfirst(str_replace('_', ' ', $action));

            switch ($action) {
                case 'suspend':
                    User::whereIn('id', $user_ids)->update(['status' => 0]);
                    break;
                case 'activate':
                    User::whereIn('id', $user_ids)->update(['status' => 1]);
                    break;
                case 'loser_mode_on':
                    User::whereIn('id', $user_ids)->update(['loser_mode' => 1]);
                    break;
                case 'loser_mode_off':
                    User::whereIn('id', $user_ids)->update(['loser_mode' => 0]);
                    break;
                case 'delete':
                    User::whereIn('id', $user_ids)->delete();
                    break;
                case 'email':
                    // Store user IDs for email functionality
                    return response()->json([
                        'status' => 'success',
                        'message' => 'Users selected for email',
                        'user_ids' => $user_ids
                    ]);
                default:
                    return response()->json([
                        'status' => 'error',
                        'message' => 'Invalid operation'
                    ], 422);
            }

            return response()->json([
                'status' => 'success',
                'message' => "{$operation} performed successfully"
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to perform bulk action',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Send bulk email to users (matching original functionality)
     */
    public function bulkEmail(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'subject' => 'required|string|max:255',
                'message' => 'required|string',
                'user_ids' => 'required|array',
                'user_ids.*' => 'exists:users,id'
            ]);

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

            $users = User::whereIn('id', $request->user_ids)->get();

            if ($users->isEmpty()) {
                return response()->json([
                    'status' => 'error',
                    'message' => 'No users found for email'
                ], 404);
            }

            // Queue emails with intervals (matching original logic)
            $delayMinutes = 0;
            $sentCount = 0;

            foreach ($users as $user) {
                try {
                    // Calculate delay with variation (between 9-11 minutes)
                    $delayMinutes += 10 + rand(-1, 1);
                    $delaySeconds = $delayMinutes * 60;

                    // Queue the email with delay
                    Mail::to($user->email)
                        ->later(now()->addSeconds($delaySeconds), 
                               new Newsletter($request->subject, $request->message, $user));
                    $sentCount++;
                } catch (\Exception $e) {
                    \Log::error("Failed to queue email for {$user->email}: " . $e->getMessage());
                }
            }

            // Calculate approximate completion time
            $completionTime = now()->addMinutes($delayMinutes)->format('h:i A');

            return response()->json([
                'status' => 'success',
                'message' => "Emails have been queued for {$sentCount} users. All emails should be sent by approximately {$completionTime}"
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 'error',
                'message' => 'Failed to send bulk email',
                'error' => $e->getMessage()
            ], 500);
        }
    }
}