<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\Country;
use App\Models\Language;
use App\Models\Ban;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\ValidationException;

class UserController extends Controller
{
    /**
     * Display a listing of users
     */
    public function index(Request $request)
    {
        $query = User::with(['language', 'country', 'currentCountry']);

        // 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('phone', 'like', "%{$search}%");
            });
        }

        // Filter by role
        if ($request->filled('role')) {
            $query->where('role', $request->role);
        }

        // Filter by verification status
        if ($request->filled('verified')) {
            if ($request->verified === '1') {
                $query->whereNotNull('email_verified_at');
            } else {
                $query->whereNull('email_verified_at');
            }
        }

        // Filter by guest status
        if ($request->filled('guest')) {
            $query->where('is_guest', $request->guest === '1');
        }

        // Filter by banned status
        if ($request->filled('banned')) {
            if ($request->banned === '1') {
                $query->whereNotNull('banned_at');
            } else {
                $query->whereNull('banned_at');
            }
        }

        // Filter by country
        if ($request->filled('country_id')) {
            $query->where('country_id', $request->country_id);
        }

        // Filter by language
        if ($request->filled('language_id')) {
            $query->where('language_id', $request->language_id);
        }

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

        // Sort
        $sortBy = $request->get('sort', 'created_at');
        $sortOrder = $request->get('order', 'desc');
        $query->orderBy($sortBy, $sortOrder);

        // Get paginated results
        $users = $query->paginate(20)->withQueryString();

        // Get filter options
        $countries = Country::active()->ordered()->get();
        $languages = Language::active()->ordered()->get();

        return view('admin.users.index', compact(
            'users',
            'countries',
            'languages'
        ));
    }

    /**
     * Store a newly created user
     */
    public function store(Request $request)
    {
        // Enhanced validation with detailed error logging
        try {
            $validatedData = $request->validate([
                'name' => 'required|string|max:255',
                'email' => 'required|email|unique:users,email',
                'phone' => 'nullable|string|max:20',
                'country_code' => 'nullable|string|max:5',
                'password' => 'required|string|min:8|confirmed',
                'role' => 'required|in:admin,store_owner,user',
                'language_id' => 'nullable|exists:languages,id',
                'country_id' => 'nullable|exists:countries,id',
                'current_country_id' => 'nullable|exists:countries,id',
                'is_guest' => 'nullable|boolean',
                'email_verified' => 'nullable|boolean',
            ]);
        } catch (ValidationException $e) {
            Log::error('User creation validation failed', [
                'errors' => $e->errors(),
                'request_data' => $request->except(['password', 'password_confirmation']),
                'user_id' => auth()->id(),
                'ip' => $request->ip(),
            ]);

            // Format validation errors for toast
            $errorMessages = [];
            foreach ($e->errors() as $field => $messages) {
                foreach ($messages as $message) {
                    $errorMessages[] = $message;
                }
            }

            flash_error(implode(' • ', $errorMessages), admin_trans('validation_errors'));
            return back()->withInput();
        }

        Log::info('Starting user creation process', [
            'request_data' => $request->except(['password', 'password_confirmation']),
            'admin_user_id' => auth()->id(),
            'ip' => $request->ip(),
        ]);

        DB::beginTransaction();
        try {
            // Always get country calling code from selected country (override user input)
            $countryCode = null;
            if ($validatedData['country_id']) {
                $country = Country::find($validatedData['country_id']);
                if ($country && $country->calling_code) {
                    $countryCode = $country->calling_code;
                }
            }

            // Fallback to user input only if no country selected and user provided a valid code
            if (!$countryCode && $validatedData['country_code']) {
                $countryCode = $validatedData['country_code'];
            }

            // Prepare user data
            $userData = [
                'name' => $validatedData['name'],
                'email' => $validatedData['email'],
                'phone' => $validatedData['phone'],
                'country_code' => $countryCode,
                'password' => Hash::make($validatedData['password']), // Explicitly hash password
                'role' => $validatedData['role'],
                'language_id' => $validatedData['language_id'],
                'country_id' => $validatedData['country_id'],
                'current_country_id' => $validatedData['current_country_id'] ?? $validatedData['country_id'],
                'is_guest' => $request->boolean('is_guest', false),
                'email_verified_at' => $request->boolean('email_verified') ? now() : null,
            ];

            // Generate E164 number if phone and country code exist
            if (!empty($countryCode) && !empty($validatedData['phone'])) {
                $userData['e164_number'] = $countryCode . $validatedData['phone'];
            }

            Log::info('Creating user with data', [
                'user_data' => collect($userData)->except(['password'])->toArray(),
            ]);

            // Create user
            $user = User::create($userData);

            if (!$user) {
                throw new \Exception('Failed to create user - User::create returned null');
            }

            Log::info('User created successfully', [
                'user_id' => $user->id,
                'user_email' => $user->email,
                'admin_user_id' => auth()->id(),
            ]);

            DB::commit();
            
            if (function_exists('flash_success')) {
                flash_success(admin_trans('user_created_successfully'));
            } else {
                session()->flash('success', admin_trans('user_created_successfully'));
            }
            
            return redirect()->route('admin.users.index');

        } catch (\Exception $e) {
            DB::rollBack();
            
            Log::error('User creation failed', [
                'error_message' => $e->getMessage(),
                'error_file' => $e->getFile(),
                'error_line' => $e->getLine(),
                'stack_trace' => $e->getTraceAsString(),
                'request_data' => $request->except(['password', 'password_confirmation']),
                'admin_user_id' => auth()->id(),
                'ip' => $request->ip(),
            ]);

            if (function_exists('flash_error')) {
                flash_error(admin_trans('error_creating_user') . ': ' . $e->getMessage());
            } else {
                session()->flash('error', admin_trans('error_creating_user') . ': ' . $e->getMessage());
            }
            
            return back()->withInput()->withErrors(['general' => $e->getMessage()]);
        }
    }

    /**
     * Show the form for editing the specified user
     */
    public function edit(User $user)
    {
        try {
            $user->load(['language', 'country', 'currentCountry', 'devices', 'providers']);

            // Get ban info if user is banned
            $banInfo = null;
            if ($user->is_banned) {
                $banInfo = Ban::where([
                    'bannable_type' => User::class,
                    'bannable_id' => $user->id,
                ])->active()->latest()->first();
            }

            $data = [
                'id' => $user->id,
                'name' => $user->name,
                'email' => $user->email,
                'phone' => $user->phone,
                'country_code' => $user->country_code,
                'e164_number' => $user->e164_number,
                'role' => $user->role,
                'language_id' => $user->language_id,
                'country_id' => $user->country_id,
                'current_country_id' => $user->current_country_id,
                'is_guest' => $user->is_guest,
                'is_verified' => $user->is_verified,
                'is_banned' => $user->is_banned,
                'email_verified_at' => $user->email_verified_at,
                'otp_verified_at' => $user->otp_verified_at,
                'banned_at' => $user->banned_at,
                'created_at' => $user->created_at,
                'updated_at' => $user->updated_at,
                'ban_info' => $banInfo,
                'devices_count' => $user->devices->count(),
                'providers' => $user->providers->pluck('provider')->toArray(),
                'language' => $user->language,
                'country' => $user->country,
            ];

            return response()->json([
                'success' => true,
                'data' => $data
            ]);
        } catch (\Exception $e) {
            Log::error('Error loading user for edit', [
                'user_id' => $user->id,
                'error_message' => $e->getMessage(),
                'error_file' => $e->getFile(),
                'error_line' => $e->getLine(),
                'admin_user_id' => auth()->id(),
            ]);

            return response()->json([
                'success' => false,
                'message' => admin_trans('error_loading_user') . ': ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Update the specified user
     */
    public function update(Request $request, User $user)
    {
        // Enhanced validation with detailed error logging
        try {
            $validatedData = $request->validate([
                'name' => 'required|string|max:255',
                'email' => ['required', 'email', Rule::unique('users')->ignore($user->id)],
                'phone' => 'nullable|string|max:20',
                'country_code' => 'nullable|string|max:5',
                'password' => 'nullable|string|min:8|confirmed',
                'role' => 'required|in:admin,store_owner,user',
                'language_id' => 'nullable|exists:languages,id',
                'country_id' => 'nullable|exists:countries,id',
                'current_country_id' => 'nullable|exists:countries,id',
                'is_guest' => 'nullable|boolean',
                'email_verified' => 'nullable|boolean',
            ]);
        } catch (ValidationException $e) {
            Log::error('User update validation failed', [
                'user_id' => $user->id,
                'errors' => $e->errors(),
                'request_data' => $request->except(['password', 'password_confirmation']),
                'admin_user_id' => auth()->id(),
                'ip' => $request->ip(),
            ]);

            // Format validation errors for toast
            $errorMessages = [];
            foreach ($e->errors() as $field => $messages) {
                foreach ($messages as $message) {
                    $errorMessages[] = $message;
                }
            }

            flash_error(implode(' • ', $errorMessages), admin_trans('validation_errors'));
            return back()->withInput();
        }

        Log::info('Starting user update process', [
            'user_id' => $user->id,
            'request_data' => $request->except(['password', 'password_confirmation']),
            'admin_user_id' => auth()->id(),
            'ip' => $request->ip(),
        ]);

        DB::beginTransaction();
        try {
            // Always get country calling code from selected country (override user input)
            $countryCode = null;
            if ($validatedData['country_id']) {
                $country = Country::find($validatedData['country_id']);
                if ($country && $country->calling_code) {
                    $countryCode = $country->calling_code;
                }
            }

            // Fallback to user input only if no country selected and user provided a valid code
            if (!$countryCode && $validatedData['country_code']) {
                $countryCode = $validatedData['country_code'];
            }

            // Prepare update data
            $updateData = [
                'name' => $validatedData['name'],
                'email' => $validatedData['email'],
                'phone' => $validatedData['phone'],
                'country_code' => $countryCode,
                'role' => $validatedData['role'],
                'language_id' => $validatedData['language_id'],
                'country_id' => $validatedData['country_id'],
                'current_country_id' => $validatedData['current_country_id'] ?? $validatedData['country_id'],
                'is_guest' => $request->boolean('is_guest', false),
            ];

            // Generate E164 number if phone and country code exist
            if (!empty($countryCode) && !empty($validatedData['phone'])) {
                $updateData['e164_number'] = $countryCode . $validatedData['phone'];
            } else {
                $updateData['e164_number'] = null;
            }

            // Update password if provided
            if ($request->filled('password')) {
                $updateData['password'] = Hash::make($validatedData['password']);
                Log::info('Password will be updated for user', ['user_id' => $user->id]);
            }

            // Update email verification status
            if ($request->has('email_verified')) {
                $updateData['email_verified_at'] = $request->boolean('email_verified') ? now() : null;
                Log::info('Email verification status updated', [
                    'user_id' => $user->id,
                    'verified' => $request->boolean('email_verified')
                ]);
            }

            Log::info('Updating user with data', [
                'user_id' => $user->id,
                'update_data' => collect($updateData)->except(['password'])->toArray(),
            ]);

            // Update user
            $updated = $user->update($updateData);

            if (!$updated) {
                throw new \Exception('Failed to update user - update method returned false');
            }

            Log::info('User updated successfully', [
                'user_id' => $user->id,
                'user_email' => $user->email,
                'admin_user_id' => auth()->id(),
            ]);

            DB::commit();
            
            if (function_exists('flash_success')) {
                flash_success(admin_trans('user_updated_successfully'));
            } else {
                session()->flash('success', admin_trans('user_updated_successfully'));
            }
            
            return redirect()->route('admin.users.index');

        } catch (\Exception $e) {
            DB::rollBack();
            
            Log::error('User update failed', [
                'user_id' => $user->id,
                'error_message' => $e->getMessage(),
                'error_file' => $e->getFile(),
                'error_line' => $e->getLine(),
                'stack_trace' => $e->getTraceAsString(),
                'request_data' => $request->except(['password', 'password_confirmation']),
                'admin_user_id' => auth()->id(),
                'ip' => $request->ip(),
            ]);

            if (function_exists('flash_error')) {
                flash_error(admin_trans('error_updating_user') . ': ' . $e->getMessage());
            } else {
                session()->flash('error', admin_trans('error_updating_user') . ': ' . $e->getMessage());
            }
            
            return back()->withInput()->withErrors(['general' => $e->getMessage()]);
        }
    }

    /**
     * Remove the specified user
     */
    public function destroy(User $user)
    {
        // Prevent deleting the current authenticated user
        if ($user->id === auth()->id()) {
            Log::warning('Attempt to delete own account', [
                'user_id' => $user->id,
                'admin_user_id' => auth()->id(),
            ]);
            
            if (function_exists('flash_error')) {
                flash_error(admin_trans('cannot_delete_yourself'));
            } else {
                session()->flash('error', admin_trans('cannot_delete_yourself'));
            }
            return back();
        }

        try {
            Log::info('Starting user deletion', [
                'user_id' => $user->id,
                'user_email' => $user->email,
                'admin_user_id' => auth()->id(),
            ]);

            $user->delete();
            
            Log::info('User deleted successfully', [
                'user_id' => $user->id,
                'admin_user_id' => auth()->id(),
            ]);

            if (function_exists('flash_success')) {
                flash_success(admin_trans('user_deleted_successfully'));
            } else {
                session()->flash('success', admin_trans('user_deleted_successfully'));
            }
        } catch (\Exception $e) {
            Log::error('User deletion failed', [
                'user_id' => $user->id,
                'error_message' => $e->getMessage(),
                'error_file' => $e->getFile(),
                'error_line' => $e->getLine(),
                'admin_user_id' => auth()->id(),
            ]);

            if (function_exists('flash_error')) {
                flash_error(admin_trans('error_deleting_user') . ': ' . $e->getMessage());
            } else {
                session()->flash('error', admin_trans('error_deleting_user') . ': ' . $e->getMessage());
            }
        }

        return redirect()->route('admin.users.index');
    }

    /**
     * Ban a user
     */
    public function ban(Request $request, User $user)
    {
        $request->validate([
            'comment' => 'nullable|string|max:500',
            'expired_at' => 'nullable|date|after:today',
        ]);

        // Prevent banning yourself
        if ($user->id === auth()->id()) {
            Log::warning('Attempt to ban own account', [
                'user_id' => $user->id,
                'admin_user_id' => auth()->id(),
            ]);

            return response()->json([
                'success' => false,
                'message' => admin_trans('cannot_ban_yourself')
            ]);
        }

        try {
            DB::beginTransaction();

            Log::info('Starting user ban process', [
                'user_id' => $user->id,
                'admin_user_id' => auth()->id(),
                'comment' => $request->comment,
                'expires_at' => $request->expired_at,
            ]);

            // Update user ban status
            $user->update(['banned_at' => now()]);

            // Create ban record
            Ban::banModel(
                $user,
                auth()->user(),
                $request->comment,
                $request->expired_at
            );

            Log::info('User banned successfully', [
                'user_id' => $user->id,
                'admin_user_id' => auth()->id(),
            ]);

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => admin_trans('user_banned_successfully')
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            
            Log::error('User ban failed', [
                'user_id' => $user->id,
                'error_message' => $e->getMessage(),
                'admin_user_id' => auth()->id(),
            ]);

            return response()->json([
                'success' => false,
                'message' => admin_trans('error_banning_user') . ': ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Unban a user
     */
    public function unban(User $user)
    {
        try {
            DB::beginTransaction();

            Log::info('Starting user unban process', [
                'user_id' => $user->id,
                'admin_user_id' => auth()->id(),
            ]);

            // Update user ban status
            $user->update(['banned_at' => null]);

            // Remove active bans
            Ban::unbanModel($user);

            Log::info('User unbanned successfully', [
                'user_id' => $user->id,
                'admin_user_id' => auth()->id(),
            ]);

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => admin_trans('user_unbanned_successfully')
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            
            Log::error('User unban failed', [
                'user_id' => $user->id,
                'error_message' => $e->getMessage(),
                'admin_user_id' => auth()->id(),
            ]);

            return response()->json([
                'success' => false,
                'message' => admin_trans('error_unbanning_user') . ': ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Verify user email
     */
    public function verifyEmail(User $user)
    {
        try {
            Log::info('Verifying user email', [
                'user_id' => $user->id,
                'admin_user_id' => auth()->id(),
            ]);

            $user->update(['email_verified_at' => now()]);

            return response()->json([
                'success' => true,
                'message' => admin_trans('user_verified_successfully')
            ]);
        } catch (\Exception $e) {
            Log::error('User email verification failed', [
                'user_id' => $user->id,
                'error_message' => $e->getMessage(),
                'admin_user_id' => auth()->id(),
            ]);

            return response()->json([
                'success' => false,
                'message' => admin_trans('error_verifying_user') . ': ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Unverify user email
     */
    public function unverifyEmail(User $user)
    {
        try {
            Log::info('Unverifying user email', [
                'user_id' => $user->id,
                'admin_user_id' => auth()->id(),
            ]);

            $user->update(['email_verified_at' => null]);

            return response()->json([
                'success' => true,
                'message' => admin_trans('user_unverified_successfully')
            ]);
        } catch (\Exception $e) {
            Log::error('User email unverification failed', [
                'user_id' => $user->id,
                'error_message' => $e->getMessage(),
                'admin_user_id' => auth()->id(),
            ]);

            return response()->json([
                'success' => false,
                'message' => admin_trans('error_unverifying_user') . ': ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get user devices
     */
    public function devices(User $user)
    {
        try {
            $devices = $user->devices()->orderBy('updated_at', 'desc')->get();

            return response()->json([
                'success' => true,
                'devices' => $devices
            ]);
        } catch (\Exception $e) {
            Log::error('Error loading user devices', [
                'user_id' => $user->id,
                'error_message' => $e->getMessage(),
                'admin_user_id' => auth()->id(),
            ]);

            return response()->json([
                'success' => false,
                'message' => admin_trans('error_loading_devices') . ': ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get user activity (login history, etc.)
     */
    public function activity(User $user)
    {
        try {
            // You can extend this to include more activity types
            $activity = [
                'last_login' => $user->updated_at, // Placeholder
                'total_logins' => 0, // Placeholder - implement login tracking
                'devices_count' => $user->devices->count(),
                'offers_count' => $user->offers->count(),
                'stores_count' => $user->stores->count(),
                'providers' => $user->providers->pluck('provider')->toArray(),
            ];

            return response()->json([
                'success' => true,
                'activity' => $activity
            ]);
        } catch (\Exception $e) {
            Log::error('Error loading user activity', [
                'user_id' => $user->id,
                'error_message' => $e->getMessage(),
                'admin_user_id' => auth()->id(),
            ]);

            return response()->json([
                'success' => false,
                'message' => admin_trans('error_loading_activity') . ': ' . $e->getMessage()
            ], 500);
        }
    }

    /**
     * Bulk actions
     */
    public function bulkAction(Request $request)
    {
        $request->validate([
            'action' => 'required|in:delete,verify,unverify,ban,unban',
            'selected' => 'required|array',
            'selected.*' => 'exists:users,id',
            'ban_comment' => 'nullable|string|max:500',
            'ban_expires_at' => 'nullable|date|after:today',
        ]);

        $users = User::whereIn('id', $request->selected);
        $count = count($request->selected);

        // Prevent actions on current user
        if (in_array(auth()->id(), $request->selected)) {
            Log::warning('Bulk action attempted on own account', [
                'action' => $request->action,
                'selected_ids' => $request->selected,
                'admin_user_id' => auth()->id(),
            ]);

            return response()->json([
                'success' => false,
                'message' => admin_trans('cannot_perform_action_on_yourself')
            ]);
        }

        try {
            DB::beginTransaction();

            Log::info('Starting bulk action', [
                'action' => $request->action,
                'user_count' => $count,
                'selected_ids' => $request->selected,
                'admin_user_id' => auth()->id(),
            ]);

            switch ($request->action) {
                case 'delete':
                    $users->delete();
                    break;

                case 'verify':
                    $users->update(['email_verified_at' => now()]);
                    break;

                case 'unverify':
                    $users->update(['email_verified_at' => null]);
                    break;

                case 'ban':
                    $users->update(['banned_at' => now()]);
                    // Create ban records
                    foreach ($request->selected as $userId) {
                        $user = User::find($userId);
                        if ($user) {
                            Ban::banModel(
                                $user,
                                auth()->user(),
                                $request->ban_comment,
                                $request->ban_expires_at
                            );
                        }
                    }
                    break;

                case 'unban':
                    $users->update(['banned_at' => null]);
                    // Remove ban records
                    foreach ($request->selected as $userId) {
                        $user = User::find($userId);
                        if ($user) {
                            Ban::unbanModel($user);
                        }
                    }
                    break;
            }

            Log::info('Bulk action completed successfully', [
                'action' => $request->action,
                'affected_users' => $count,
                'admin_user_id' => auth()->id(),
            ]);

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => "$count " . admin_trans('users') . " {$request->action}d " . admin_trans('successfully')
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            
            Log::error('Bulk action failed', [
                'action' => $request->action,
                'selected_ids' => $request->selected,
                'error_message' => $e->getMessage(),
                'error_file' => $e->getFile(),
                'error_line' => $e->getLine(),
                'admin_user_id' => auth()->id(),
            ]);

            return response()->json([
                'success' => false,
                'message' => admin_trans('error_bulk_action') . ': ' . $e->getMessage()
            ]);
        }
    }

    /**
     * Export users
     */
    public function export(Request $request)
    {
        // Implement CSV/Excel export functionality
        // You can use Laravel Excel package for this
        if (function_exists('flash_info')) {
            flash_info(admin_trans('export_feature_coming_soon'));
        } else {
            session()->flash('info', admin_trans('export_feature_coming_soon'));
        }
        return back();
    }
}