<?php

namespace App\Http\Controllers\User\Auth;

use App\Http\Controllers\Controller;
use App\Lib\Intended;
use App\Models\UserLogin;
use App\Models\OtpVerification;
use App\Constants\Status;
use Carbon\Carbon;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller {

    use AuthenticatesUsers;

    protected $username;

    public function __construct() {
        parent::__construct();
        $this->username = $this->findUsername();
    }

    public function showLoginForm() {
        $pageTitle = "Client Portal — Branco Cayman National Bank & Trust";
        Intended::identifyRoute();
        return view('Template::user.auth.login', compact('pageTitle'));
    }

    public function login(Request $request) {

        $this->validateLogin($request);

        if (!verifyCaptcha()) {
            $notify[] = ['error', 'Invalid captcha provided'];
            return back()->withNotify($notify);
        }

        if ($this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);
            return $this->sendLockoutResponse($request);
        }

        // Check if user is banned before attempting login
        $loginField = $this->username();
        $loginValue = $request->input($loginField);
        
        $user = \App\Models\User::where($loginField, $loginValue)->first();
        
        if ($user && $user->status == 0) {
            // User is banned - show the frozen account message
            $notify[] = ['error', 'We have frozen your account because of a suspicious and unrecognized device login attempt, therefore your Access is Restricted, contact support team.'];
            return back()->withNotify($notify)->withInput();
        }

        if ($this->attemptLogin($request)) {
            return $this->sendLoginResponse($request);
        }

        $this->incrementLoginAttempts($request);
        Intended::reAssignSession();

        return $this->sendFailedLoginResponse($request);
    }

    public function findUsername() {
        $login = request()->input('username');
        $fieldType = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
        request()->merge([$fieldType => $login]);
        return $fieldType;
    }

    public function username() {
        return $this->username;
    }

    protected function validateLogin($request) {
        $validator = Validator::make($request->all(), [
            $this->username() => 'required|string',
            'password' => 'required|string',
        ]);
        if ($validator->fails()) {
            Intended::reAssignSession();
            $validator->validate();
        }
    }

    public function logout() {
        $this->guard()->logout();
        request()->session()->invalidate();

        $notify[] = ['success', 'You have been logged out.'];
        return to_route('user.login')->withNotify($notify);
    }

    public function authenticated(Request $request, $user) {
        // Record login info
        $user->tv = $user->ts == Status::VERIFIED ? Status::UNVERIFIED : Status::VERIFIED;
        $user->save();
        
        $ip = getRealIP();
        $exist = UserLogin::where('user_ip', $ip)->first();
        $userLogin = new UserLogin();
        
        if ($exist) {
            $userLogin->longitude =  $exist->longitude;
            $userLogin->latitude =  $exist->latitude;
            $userLogin->city =  $exist->city;
            $userLogin->country_code = $exist->country_code;
            $userLogin->country =  $exist->country;
        } else {
            $info = json_decode(json_encode(getIpInfo()), true);
            $userLogin->longitude =  isset($info['long']) ? implode(',', $info['long']) : '';
            $userLogin->latitude =  isset($info['lat']) ? implode(',', $info['lat']) : '';
            $userLogin->city =  isset($info['city']) ? implode(',', $info['city']) : '';
            $userLogin->country_code = isset($info['code']) ? implode(',', $info['code']) : '';
            $userLogin->country =  isset($info['country']) ? implode(',', $info['country']) : '';
        }

        $userAgent = osBrowser();
        $userLogin->user_id = $user->id;
        $userLogin->user_ip =  $ip;
        $userLogin->browser = isset($userAgent['browser']) ? $userAgent['browser'] : '';
        $userLogin->os = isset($userAgent['os_platform']) ? $userAgent['os_platform'] : '';
        $userLogin->save();

        // Generate OTP for login verification
        $otpVerification = new OtpVerification();
        $otpVerification->user_id = $user->id;
        $otpVerification->send_via = 'email';
        $otpVerification->otp = verificationCode(6);
        $otpVerification->verifiable_type = '';
        $otpVerification->verifiable_id = 0;
        $otpVerification->expired_at = Carbon::now()->addMinutes(10);
        $otpVerification->additional_data = json_encode([
            'after_verified' => 'user.home',
            'purpose' => 'login_verification'
        ]);
        $otpVerification->save();

        // Store data in session before logout
        session()->put('verification_id', $otpVerification->id);
        session()->put('login_user_id', $user->id);
        
        // Send OTP to user email
        notify($user, 'OTP_LOGIN', [
            'code' => $otpVerification->otp
        ], ['email']);

        // Use a partial logout instead of full logout to keep session data
        $this->guard()->logout();
        $request->session()->regenerate(true);
        
        return to_route('user.otp.verify');
    }
}