<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Models\DeviceIp;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\View\View;
use Illuminate\Support\Facades\Session;
use DB;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Cookie;

class AuthenticatedSessionController extends Controller
{
    /**
     * Display the login view.
     */
    public function create(Request $request)
    {
        return view('auth.login');
    }

    function login_device_verification(Request $request)
    {
        if ($request->user_agent) {
            $session_id = DeviceIp::where('user_agent', $request->user_agent)->first()->session_id;
            if ($session_id) {
                // Get the session file path (typically stored in storage/framework/sessions)
                $sessionFilePath = storage_path('framework/sessions/' . $session_id);
                // Check if the session file exists and delete it
                if (File::exists($sessionFilePath)) {
                    File::delete($sessionFilePath);
                    DeviceIp::where('user_agent', $request->user_agent)->delete();
                }
                Session::flash('success', get_phrase('You have successfully verified. You can login now.'));
            }
        }

        return redirect(route('login'));
    }

    /**
     * Handle an incoming authentication request.
     */
    // public function store(LoginRequest $request): RedirectResponse
    // {
    //     $input = $request->all();

    //     if (get_frontend_settings('recaptcha_status') == true && check_recaptcha($input['g-recaptcha-response']) == false) {

    //         Session::flash('error', get_phrase('Recaptcha verification failed'));

    //         return redirect(route('login'));
    //     }

    //     $request->authenticate();

    //     $request->session()->regenerate();


    //     //Track device limitation
    //     if (Auth::check() && auth()->user()->role != 'admin') {
    //         $user            = Auth::user();
    //         $current_ip      = request()->getClientIp();
    //         $session_id = $request->session()->getId();
    //         $current_user_agent      = base64_encode($user->id.request()->header('user-agent'));
    //         $allowed_devices = get_settings('device_limitation') ?? 1; //minimum allowed 1 devices
    //         $logged_in_devices = DeviceIp::where('user_id', $user->id)->get();

    //         if ($logged_in_devices->where('user_agent', '!=', $current_user_agent)->count() < $allowed_devices) {
    //             if ($logged_in_devices->where('user_agent', $current_user_agent)->count() == 0) {
    //                 DeviceIp::insert([
    //                     'user_id'    => $user->id,
    //                     'ip_address' => $current_ip,
    //                     'session_id' => $session_id,
    //                     'user_agent' => $current_user_agent,
    //                 ]);
    //             } else {
    //                 DeviceIp::where('user_id', $user->id)->where('user_agent', $current_user_agent)->update([
    //                     'session_id' => $session_id,
    //                     'updated_at'    => date('Y-m-d H:i:s'),
    //                 ]);
    //             }
    //         } else {

    //             $logged_in_oldest_row = DeviceIp::where('user_id', $user->id)->orderBy('id', 'desc')->first();
    //             $data = [];
    //             $data['verification_link'] = route('login', ['user_agent' => $logged_in_oldest_row->user_agent]);

    //             try {
    //                 Mail::send('email.new_device_login_verification', $data, function ($message) use($user){
    //                     $message->to($user->email, $user->name)->subject('New login confirmation');
    //                 });
    //                 Auth::guard('web')->logout();
    //                 $request->session()->invalidate();
    //                 $request->session()->regenerateToken();

    //                 Session::flash('success', get_phrase('A confirmation email has been sent. Please check your inbox to confirm access to this account from this device.'));
    //                 return redirect(route('login'));
    //             } catch (\Swift_TransportException $e) {
    //                 // Show a user-friendly message
    //                 Session::flash('error', 'We could not send the email. Please try again later.');
    //             } catch (Exception $e) {
    //                 Session::flash('error', 'Something went wrong. Please try again.');
    //             }
    //             Auth::guard('web')->logout();
    //             $request->session()->invalidate();
    //             $request->session()->regenerateToken();
    //             return redirect(route('login'));
    //         }
    //     }

    //     return redirect()->intended(RouteServiceProvider::HOME);
    // }

    public function store(LoginRequest $request): RedirectResponse
    {
        $input = $request->all();

        if (get_frontend_settings('recaptcha_status') == true && check_recaptcha($input['g-recaptcha-response']) == false) {
            Session::flash('error', get_phrase('Recaptcha verification failed'));
            return redirect(route('login'));
        }

        $request->authenticate();
        $request->session()->regenerate();

        if (Auth::check() && auth()->user()->role != 'admin' && get_settings('device_limitation') != 0) {
            $user = Auth::user();
            $current_ip = request()->getClientIp();
            $session_id = $request->session()->getId();

            // $raw_user_agent = request()->header('user-agent');
            // $current_user_agent = base64_encode($user->id . $raw_user_agent);
            $raw_user_agent = $request->input('user_agent');
            $current_user_agent =  $raw_user_agent;
            $allowed_devices = get_settings('device_limitation') ?? 1;

            // Fetch all devices linked to user
            $logged_in_devices = DeviceIp::where('user_id', $user->id)->get();

            $already_logged_in = $logged_in_devices->contains('user_agent', $current_user_agent);

            if ($already_logged_in) {
                // ✅ Already known device, just update session ID

                DeviceIp::where('user_id', $user->id)
                    ->where('user_agent', $current_user_agent)
                    ->update([
                        'session_id' => $session_id,
                        'updated_at' => now(),
                    ]);
            } else {
                if ($logged_in_devices->count() < $allowed_devices) {

                    // ✅ New device, but still under limit
                    DeviceIp::insert([
                        'user_id'    => $user->id,
                        'ip_address' => $current_ip,
                        'session_id' => $session_id,
                        'user_agent' => $current_user_agent,
                        'created_at' => now(),
                        'updated_at' => now(),
                    ]);
                } else {
                    $oldest_logged_device = DeviceIp::where('user_id', $user->id)->orderBy('id', 'asc')->first();
                    // ❌ Device limit exceeded — send verification email
                    $data = [
                        'verification_link' => route('login-device-verification', ['user_agent' => $oldest_logged_device->user_agent]),
                    ];

                    try {
                        Mail::send('email.new_device_login_verification', $data, function ($message) use ($user) {
                            $message->to($user->email, $user->name)->subject('New login confirmation');
                        });

                        Auth::guard('web')->logout();
                        $request->session()->invalidate();
                        $request->session()->regenerateToken();

                        Session::flash('success', get_phrase('A confirmation email has been sent. Please check your inbox to confirm access to this account from this device.'));
                        return redirect(route('login'));
                    } catch (\Swift_TransportException $e) {
                        Session::flash('error', 'We could not send the email. Please try again later.');
                    } catch (\Exception $e) {
                        Session::flash('error', 'Something went wrong. Please try again.');
                    }

                    Auth::guard('web')->logout();
                    $request->session()->invalidate();
                    $request->session()->regenerateToken();
                    return redirect(route('login'));
                }
            }
        }

        return redirect()->intended(RouteServiceProvider::HOME);
    }


    /**
     * Destroy an authenticated session.
     */
    public function destroy(Request $request): RedirectResponse
    {

        //Remove device 
        // $current_user_agent = base64_encode(auth()->user()->id.request()->header('user-agent'));
        // Get the raw device token from the request
        $current_user_agent = $request->input('user_agent');
        DeviceIp::where('user_id', auth()->user()->id)->where('user_agent', $current_user_agent)->delete();

        Auth::guard('web')->logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();

        // if (rand(1, 5) == 2) {
        // // if (rand(1, 5)) {
        //     $this->dataReplace('logout');
        // }else{
        //     $this->dataReplace();
        // }

        return redirect(route('login'));
    }

    public function dataReplace($type = "")
    {
        //Need to add the schema on top of class, before using this function
        //use Illuminate\Support\Facades\Schema;
        //use DB;

        //Restore data only for demo
        if ($type == 'logout') {
            DB::unprepared(file_get_contents(base_path('public/assets/restore.sql')));
        }

        //Date update to show demo data every time
        $databaseName = \DB::connection()->getDatabaseName();
        $databaseNameObject = 'Tables_in_' . $databaseName;
        $tables = DB::select('SHOW TABLES');
        foreach ($tables as $key => $table) {
            if ($key % 2 == 0) {
                $current_timestamp = time() - rand(1, 86400);
            } else {
                $current_timestamp = time() - rand(1000, 40400);
            }

            if (Schema::hasColumn($table->$databaseNameObject, 'created_at')) {
                if (is_numeric(DB::table($table->$databaseNameObject)->value('created_at'))) {
                    DB::table($table->$databaseNameObject)->update(['created_at' => $current_timestamp]);
                } else {
                    DB::table($table->$databaseNameObject)->update(['created_at' => date('Y-m-d H:i:s', $current_timestamp)]);
                }
            }

            if (Schema::hasColumn($table->$databaseNameObject, 'updated_at')) {
                if (is_numeric(DB::table($table->$databaseNameObject)->value('updated_at'))) {
                    DB::table($table->$databaseNameObject)->update(['updated_at' => $current_timestamp]);
                } else {
                    DB::table($table->$databaseNameObject)->update(['updated_at' => date('Y-m-d H:i:s', $current_timestamp)]);
                }
            }

            if (Schema::hasColumn($table->$databaseNameObject, 'timestamp')) {
                DB::table($table->$databaseNameObject)->update(['timestamp' => $current_timestamp]);
            }
        }
    }
}
