<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\URL;
use Kreait\Firebase\Contract\Messaging;
use App\Models\UserPrivacySetting;

class SettingsController extends Controller
{
    /**
     * Show account settings page.
     */
    public function accountSettings()
    {
        return view('front_end.pages.settings.account_settings');
    }

    /**
     * Show profile settings page.
     */
    public function profileSettings()
    {
        return view('front_end.pages.settings.profile');
    }

    /**
     * Show security settings page.
     */
    public function securitySettings()
    {
        // Get all active sessions for the current user
        $sessions = DB::table('sessions')
            ->where('user_id', Auth::id())
            ->orderBy('last_activity', 'desc')
            ->get();
        
        // Format the sessions data for display
        $formattedSessions = [];
        foreach ($sessions as $session) {
            // Check if this is the current session
            $isCurrentSession = $session->id === session()->getId();
            
            // Format last activity time
            $lastActivity = \Carbon\Carbon::createFromTimestamp($session->last_activity);
            
            // Format the session data
            $formattedSessions[] = [
                'id' => $session->id,
                'device_type' => $session->device_type ?? 'Unknown',
                'device_name' => $session->device_name ?? 'Unknown Device',
                'browser' => $session->browser ?? 'Unknown Browser',
                'platform' => $session->platform ?? 'Unknown OS',
                'ip_address' => $session->ip_address,
                'location' => $session->location ?? 'Unknown Location',
                'country' => $session->country ?? 'Unknown Country',
                'last_activity' => $lastActivity->diffForHumans(),
                'last_activity_date' => $lastActivity->format('M d, Y \a\t h:i A'),
                'is_current' => $isCurrentSession
            ];
        }
        
        return view('front_end.pages.settings.security', compact('formattedSessions'));
    }

    /**
     * Show notification settings page.
     */
    public function notificationSettings()
    {
        return view('front_end.pages.settings.notifications');
    }

    /**
     * Update notification settings.
     */
    public function notificationSettingsUpdate(Request $request)
    {
        $user = Auth::user();

        // Create notification preferences array
        $notificationPreferences = [
            'email_new_messages' => $request->has('email_new_messages'),
            'email_friend_requests' => $request->has('email_friend_requests'),
            'email_post_comments' => $request->has('email_post_comments'),
            'email_post_likes' => $request->has('email_post_likes'),
            'email_mentions' => $request->has('email_mentions'),
            'email_updates' => $request->has('email_updates'),
            'push_new_messages' => $request->has('push_new_messages'),
            'push_friend_requests' => $request->has('push_friend_requests'),
            'push_post_comments' => $request->has('push_post_comments'),
            'push_post_likes' => $request->has('push_post_likes'),
            'push_mentions' => $request->has('push_mentions'),
            'notification_sound' => $request->notification_sound,
            'browser_notifications' => $request->has('browser_notifications'),
            'sound_notifications' => $request->has('sound_notifications'),
            'email_notification_frequency' => $request->email_notification_frequency,
        ];

        // Update user preferences with DB facade instead of model methods
        DB::table('users')
            ->where('id', $user->id)
            ->update($notificationPreferences);

        return redirect()->back()->with('success', 'Notification settings updated successfully!');
    }

    /**
     * Show privacy settings page.
     */
    public function privacySettings()
    {
        $user = Auth::user();

        $privacySettings = UserPrivacySetting::firstOrCreate(
            ['user_id' => $user->id],
            [
                'profile_visibility' => 'public',
                'friend_list_visibility' => 'public',
                'post_visibility' => 'public',
                'message_privacy' => 'everyone',
                'friend_request_privacy' => 'everyone',
                'wall_posts_privacy' => 'everyone',
                'chat_enabled' => true,
                'newsletter_enabled' => true,
                'search_engine_visibility' => false,
                'discoverable_by_contact' => true,
                'personalized_ads' => true,
                'data_collection' => true,
            ]
        );

        return view('front_end.pages.settings.privacy_settings', compact('privacySettings'));
    }

    /**
     * Update privacy settings.
     */
    public function privacySettingsUpdate(Request $request)
    {
        $user = Auth::user();

        $validated = $request->validate([
            'profile_visibility' => 'required|in:public,friends,private',
            'friend_list_visibility' => 'required|in:public,friends,private',
            'post_visibility' => 'required|in:public,friends,followers,private',
            'message_privacy' => 'required|in:everyone,friends,friends_of_friends,nobody',
            'friend_request_privacy' => 'required|in:everyone,friends_of_friends,nobody',
            'wall_posts_privacy' => 'required|in:everyone,friends,nobody',
            'chat_enabled' => 'nullable|boolean',
            'newsletter_enabled' => 'nullable|boolean',
            'search_engine_visibility' => 'nullable|boolean',
            'discoverable_by_contact' => 'nullable|boolean',
            'personalized_ads' => 'nullable|boolean',
            'data_collection' => 'nullable|boolean',
        ]);

        UserPrivacySetting::updateOrCreate(
            ['user_id' => $user->id],
            [
                'profile_visibility' => $validated['profile_visibility'],
                'friend_list_visibility' => $validated['friend_list_visibility'],
                'post_visibility' => $validated['post_visibility'],
                'message_privacy' => $validated['message_privacy'],
                'friend_request_privacy' => $validated['friend_request_privacy'],
                'wall_posts_privacy' => $validated['wall_posts_privacy'],
                'chat_enabled' => $request->boolean('chat_enabled'),
                'newsletter_enabled' => $request->boolean('newsletter_enabled'),
                'search_engine_visibility' => $request->boolean('search_engine_visibility'),
                'discoverable_by_contact' => $request->boolean('discoverable_by_contact'),
                'personalized_ads' => $request->boolean('personalized_ads'),
                'data_collection' => $request->boolean('data_collection'),
            ]
        );

        return redirect()->back()->with('success', 'Privacy settings updated successfully!');
    }

    /**
     * Show verification settings page.
     */
    public function verificationSettings()
    {
        return view('front_end.pages.settings.verification');
    }

    /**
     * Submit verification request.
     */
    public function submitVerification(Request $request)
    {
        // Validate the request
        $request->validate([
            'photo' => 'required|image|mimes:jpeg,png,jpg,webp|max:2048',
            'document' => 'required|mimes:jpeg,png,jpg,webp,pdf|max:2048',
            'message' => 'nullable|string|max:1000',
        ]);

        $user = Auth::user();

        // Check if user already has a pending or approved verification request
        $existingRequest = DB::table('verification_requests')
            ->where('user_id', $user->id)
            ->whereIn('status', ['pending', 'approved'])
            ->first();

        if ($existingRequest) {
            if ($existingRequest->status === 'pending') {
                return redirect()->back()->with('error', 'You already have a pending verification request.');
            } else {
                return redirect()->back()->with('error', 'Your account is already verified.');
            }
        }

        // Store the files
        $photoPath = $request->file('photo')->store('verification/photos', 'public');
        $documentPath = $request->file('document')->store('verification/documents', 'public');

        // Create verification request
        DB::table('verification_requests')->insert([
            'user_id' => $user->id,
            'photo' => $photoPath,
            'document' => $documentPath,
            'message' => $request->message,
            'status' => 'pending',
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        return redirect()->back()->with('success', 'Your verification request has been submitted successfully. We will review it shortly.');
    }

    /**
     * Reapply for verification after rejection.
     */
    public function reapplyVerification(Request $request)
    {
        $user = Auth::user();

        // Check if user has a rejected verification request
        $rejectedRequest = DB::table('verification_requests')
            ->where('user_id', $user->id)
            ->where('status', 'rejected')
            ->first();

        if (!$rejectedRequest) {
            return redirect()->back()->with('error', 'You do not have a rejected verification request to reapply.');
        }

        // Update the status to allow reapplication
        DB::table('verification_requests')
            ->where('id', $rejectedRequest->id)
            ->delete();

        return redirect()->back()->with('success', 'You can now submit a new verification request.');
    }

    /**
     * Show blocking settings page.
     */
    public function blockingSettings()
    {
        // Fetch blocked users to display in the view
        $blockedUsers = DB::table('blocked_users')
            ->where('user_id', Auth::id())
            ->join('users', 'blocked_users.blocked_user_id', '=', 'users.id')
            ->select('blocked_users.*', 'users.name', 'users.username', 'users.avatar')
            ->get();

        return view('front_end.pages.settings.blocking_settings', compact('blockedUsers'));
    }

    /**
     * Block a specific user.
     */
    public function blockUser(Request $request)
    {
        $data = $request->validate([
            'user_id' => ['required', 'integer', 'exists:users,id'],
        ]);

        $blockerId = Auth::id();
        $blockedId = (int) $data['user_id'];

        if ($blockerId === $blockedId) {
            return back()->with('error', 'You cannot block yourself.');
        }

        $alreadyBlocked = DB::table('blocked_users')
            ->where('user_id', $blockerId)
            ->where('blocked_user_id', $blockedId)
            ->exists();

        if ($alreadyBlocked) {
            return back()->with('success', 'This user is already blocked.');
        }

        DB::table('blocked_users')->insert([
            'user_id' => $blockerId,
            'blocked_user_id' => $blockedId,
            'created_at' => now(),
            'updated_at' => now(),
        ]);

        return back()->with('success', 'User blocked successfully.');
    }

    /**
     * Unblock a specific user.
     */
    public function unblockUser(int $blockedUserId)
    {
        $deleted = DB::table('blocked_users')
            ->where('user_id', Auth::id())
            ->where('blocked_user_id', $blockedUserId)
            ->delete();

        if ($deleted) {
            return back()->with('success', 'User unblocked successfully.');
        }

        return back()->with('error', 'That user is not currently blocked.');
    }

    /**
     * Show delete account page.
     */
    public function deleteAccount()
    {
        return view('front_end.pages.settings.delete_account');
    }

    /**
     * Process account deletion request.
     */
    public function deleteAccountSettings(Request $request)
    {
        // Validate the request
        $request->validate([
            'password' => 'required',
            'reason' => 'nullable|string|max:255',
            'confirm_delete' => 'required|accepted'
        ]);

        // Get the current user
        $user = Auth::user();

        // Verify password
        if (!Hash::check($request->password, $user->password)) {
            return redirect()->back()->with('error', 'The password you entered is incorrect.');
        }

        // Log the deletion reason
        \Illuminate\Support\Facades\Log::info('User account deletion', [
            'user_id' => $user->id,
            'reason' => $request->reason
        ]);

        // Delete the user account
        Auth::logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();

        // Update user status instead of actual deletion (soft delete)
        DB::table('users')
            ->where('id', $user->id)
            ->update([
                'status' => 'deleted',
                'deleted_at' => now()
            ]);

        return redirect()->route('login')->with('success', 'Your account has been deleted successfully.');
    }

    /**
     * Update account settings.
     */
    public function accountSettingsUpdate(Request $request)
    {
        // Validate the request
        $validatedData = $request->validate([
            'username' => 'required|string|max:255|unique:users,username,' . Auth::id(),
            'email' => 'required|string|email|max:255|unique:users,email,' . Auth::id(),
            'phone' => 'nullable|string|max:20',
            'language' => 'required|string|in:en,es,fr,de,ar',
            'timezone' => 'required|string',
            'date_format' => 'required|string',
            'facebook_username' => 'nullable|string|max:255',
            'twitter_username' => 'nullable|string|max:255',
            'instagram_username' => 'nullable|string|max:255',
            'linkedin_username' => 'nullable|string|max:255',
        ]);

        // If email is changed, mark it as unverified
        if (Auth::user()->email !== $validatedData['email']) {
            $validatedData['email_verified_at'] = null;

            // Send verification email (would implement this in a real application)
            // Mail::to($validatedData['email'])->send(new VerifyEmail($user));
        }

        // Update user data
        DB::table('users')
            ->where('id', Auth::id())
            ->update($validatedData);

        return redirect()->back()->with('success', 'Account settings updated successfully!');
    }

    /**
     * Update profile picture
     */
    public function updateProfilePicture(Request $request)
    {
        // Validate the request
        $request->validate([
            'profile_picture' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
        ]);

        // Handle file upload
        if ($request->hasFile('profile_picture')) {
            // Delete old profile picture if exists
            $user = Auth::user();

            if ($user->avatar) {
                $file = $request->file('profile_picture');
                $path = storeMedia($file, 'avatars');

                // Update the user's avatar path in the database
                DB::table('users')
                    ->where('id', $user->id)
                    ->update([
                        'avatar' => $path
                    ]);
                return redirect()->back()->with('success', 'Profile picture updated successfully!');
            }
        }

        return redirect()->back()->with('error', 'No profile picture was uploaded.');
    }

    /**
     * Update profile settings.
     */
    public function profileSettingsUpdate(Request $request)
    {
        $section = $request->input('section', 'basic');
        $user = Auth::user();

        if ($section === 'basic') {
            $validatedData = $request->validate([
                'first_name' => 'required|string|max:255',
                'last_name' => 'required|string|max:255',
                'bio' => 'nullable|string|max:1000',
                'date_of_birth' => 'nullable|date',
                'gender' => 'nullable|string|in:male,female,other,prefer_not_to_say',
                'website' => 'nullable|url|max:255',
            ]);

            // Handle avatar separately since it's stored in the users table
            if ($request->hasFile('avatar')) {
                $avatarPath = $request->file('avatar')->store('avatars', 'public');
                $user->update(['avatar' => $avatarPath]);
            }

            DB::table('users')
            ->where('id', Auth::id())
            ->update($validatedData);

        } elseif ($section === 'work') {
            $validatedData = $request->validate([
                'job_title' => 'nullable|string|max:255',
                'company' => 'nullable|string|max:255',
                'work_started' => 'nullable|date',
                'work_ended' => 'nullable|date',
                'work_description' => 'nullable|string|max:1000',
            ]);

            foreach ($validatedData as $key => $value) {
                $user->setMeta($key, $value);
            }
        } elseif ($section === 'location') {
            $validatedData = $request->validate([
                'country' => 'nullable|string|max:2',
                'city' => 'nullable|string|max:255',
                'address' => 'nullable|string|max:500',
            ]);
            foreach ($validatedData as $key => $value) {
                $user->setMeta($key, $value);
            }
        } elseif ($section === 'education') {
            $validatedData = $request->validate([
                'school' => 'nullable|string|max:255',
                'degree' => 'nullable|string|max:255',
                'edu_started' => 'nullable|date',
                'edu_ended' => 'nullable|date',
                'edu_description' => 'nullable|string|max:1000',
            ]);

            foreach ($validatedData as $key => $value) {
                $user->setMeta($key, $value);
            }
        }
        // Similar for other sections

        return redirect()->back()->with('success', 'Profile information updated successfully!');
    }

    /**
     * Update security settings.
     */
    public function securitySettingsUpdate(Request $request)
    {
        // Handle different sections
        $section = $request->input('section', 'password');

        if ($section === 'password') {
            // Prepare password validation rules
            $passwordRules = ['required', 'min:8', 'confirmed'];
            
            // Add password complexity rules if enabled
            if (setting('password_complexity') == 1) {
                $passwordRules[] = 'regex:/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]/';
            }
            
            // Validate password change
            $validatedData = $request->validate([
                'current_password' => 'required',
                'new_password' => $passwordRules,
            ]);

            // Add custom error message for password complexity
            if (setting('password_complexity') == 1) {
                $validator = Validator::make($request->all(), []);
                $validator->addCustomAttributes([
                    'new_password' => 'Password must contain at least one uppercase letter, one lowercase letter, one number, and one special character.'
                ]);
            }

            // Verify current password
            if (!Hash::check($validatedData['current_password'], Auth::user()->password)) {
                return redirect()->back()->with('error', 'Current password is incorrect.');
            }

            // Update the password
            DB::table('users')
                ->where('id', Auth::id())
                ->update([
                    'password' => Hash::make($validatedData['new_password'])
                ]);

            return redirect()->back()->with('success', 'Password updated successfully.');
        }

        // Handle other security sections as needed

        return redirect()->back()->with('success', 'Security settings updated successfully.');
    }
    
    /**
     * Revoke a specific session.
     */
    public function revokeSession(Request $request)
    {
        // Validate the request
        $request->validate([
            'session_id' => 'required|string'
        ]);
        
        $sessionId = $request->input('session_id');
        
        // Make sure we're not revoking the current session
        if ($sessionId === $request->session()->getId()) {
            return redirect()->back()->with('error', 'You cannot revoke your current session.');
        }
        
        // Delete the session from the database
        DB::table('sessions')
            ->where('id', $sessionId)
            ->where('user_id', Auth::id()) // Ensure the session belongs to the current user
            ->delete();
            
        return redirect()->back()->with('success', 'Session has been revoked successfully.');
    }
    
    /**
     * Revoke all sessions except the current one.
     */
    public function revokeAllSessions(Request $request)
    {
        // Get the current session ID
        $currentSessionId = $request->session()->getId();
        
        // Delete all other sessions for this user
        DB::table('sessions')
            ->where('user_id', Auth::id())
            ->where('id', '!=', $currentSessionId)
            ->delete();
            
        return redirect()->back()->with('success', 'All other sessions have been revoked successfully.');
    }

    /**
     * Process account deactivation.
     */
    public function accountDeactivate(Request $request)
    {
        // Validate the request
        $request->validate([
            'deactivate_confirm' => 'required|accepted',
        ]);

        $user = Auth::user();

        // Update user status
        DB::table('users')
            ->where('id', $user->id)
            ->update([
                'status' => 'deactivated',
                'deactivated_at' => now()
            ]);

        // Log the user out
        Auth::logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();

        return redirect()->route('login')->with('success', 'Your account has been deactivated. You can reactivate it by logging in again.');
    }

    /**
     * Public API: get-site-settings
     * Returns public settings in plaintext and private settings encrypted with simple salt-based encryption.
     */
    public function getSiteSettingsPublic(Request $request)
    {
        try {
            // Fetch settings
            $rows = DB::table('settings')
                ->select(['name', 'val', 'type', 'visibility'])
                ->whereNull('deleted_at')
                ->get();

            $typed = function ($val, $type) {
                switch (strtolower($type)) {
                    case 'boolean':
                        return (bool) (is_numeric($val) ? ((int) $val) : filter_var($val, FILTER_VALIDATE_BOOLEAN));
                    case 'number':
                        return is_numeric($val) ? ($val + 0) : 0;
                    default:
                        return (string) $val;
                }
            };

            $public = [];
            $private = [];

            foreach ($rows as $row) {
                $value = $typed($row->val, $row->type);
                if ($row->visibility === 'public') {
                    $public[$row->name] = $value;
                } else {
                    // Simple encryption for private settings
                    $private[$row->name] = $this->settingsEncrypt($value);
                }
            }

            // Build response in same format as other APIs
            $response = [
                'status' => 200,
                'message' => 'Site settings retrieved successfully',
                'data' => [
                    'public' => $public,
                    'private' => $private,
                ],
            ];

            return response()->json($response);

        } catch (\Exception $e) {
            return response()->json([
                'status' => 500,
                'message' => 'An error occurred while retrieving site settings',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    /**
     * Simple encryption using salt from .env
     */
    private function settingsEncrypt($value)
    {
        $secretKey = env('SETTINGS_ENCRYPTION_KEY', 'socialink_sada_enc');
        $secretIv  = env('SETTINGS_ENCRYPTION_IV', 'socialink_sada_iv_key');

        $method = "AES-256-CBC";

        // Derive key and iv from secret
        $key = hash('sha256', $secretKey, true);
        $iv  = substr(hash('sha256', $secretIv), 0, 16);

        $encrypted = openssl_encrypt($value, $method, $key, OPENSSL_RAW_DATA, $iv);
        return base64_encode($encrypted);
    }
    public function sendNotification(Messaging $messaging)
    {

        $message = [
            'token' => $deviceToken,
            'notification' => [
                'title' => 'Hello from Laravel 🚀',
                'body'  => 'This push is using try–catch for error handling.',
            ],
        ];

        try {
            $messaging->send($message);

            return response()->json([
                'success' => true,
                'message' => 'Notification sent successfully!',
            ]);

        } catch (\Kreait\Firebase\Exception\Messaging\NotFound $e) {
            // Token not found / invalid
            return response()->json([
                'success' => false,
                'error'   => 'Invalid or expired device token',
            ], 400);

        } catch (\Kreait\Firebase\Exception\MessagingException $e) {
            // General Firebase messaging error
            return response()->json([
                'success' => false,
                'error'   => $e->getMessage(),
            ], 500);

        } catch (\Exception $e) {
            // Any other error
            return response()->json([
                'success' => false,
                'error'   => $e->getMessage(),
            ], 500);
        }
    }
}
