<?php

namespace App\Http\Controllers\Admin\Auth;

use laravelLara\infoinst\utils\ApiCheckHelper;
use Illuminate\Http\Request;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use App\Models\User;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Validation\ValidationException;
use App\Models\Announcement;
use App\Models\Apptitle;
use Auth;
use Spatie\Permission\Models\Role;
use App\Models\VerifyOtp;
use App\Models\Holiday;
use Carbon\Carbon;
use Illuminate\Support\Facades\Session;
use laravelLara\infoinst\Jobs\MailSend;
use App\Models\Setting;
use Torann\GeoIP\Facades\GeoIP;
use Jenssegers\Agent\Agent;
use App\Models\EmployeeActivity;

class LoginController extends Controller
{
    use ApiCheckHelper;
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */


    use ThrottlesLogins, AuthenticatesUsers {
        logout as performLogout;
    }

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    public function showloginform()
    {
        $setting = response()->json(['CAPTCHATYPE' => setting('CAPTCHATYPE'), 'RECAPTCH_ENABLE_ADMIN_LOGIN' => setting('RECAPTCH_ENABLE_ADMIN_LOGIN'), 'GOOGLE_RECAPTCHA_KEY' => setting('GOOGLE_RECAPTCHA_KEY'), 'ANNOUNCEMENT_USER' => setting('ANNOUNCEMENT_USER')]);
        $data['setting'] = $setting;

        $title = Apptitle::first();
        $data['title'] = $title;
        $now = now();
        $announcement = announcement::whereDate('enddate', '>=', $now->toDateString())->whereDate('startdate', '<=', $now->toDateString())->get();
        $data['announcement'] = $announcement;

        $announcements = Announcement::whereNotNull('announcementday')->get();
        $data['announcements'] = $announcements;
        // $holidays = Holiday::whereDate('startdate', '<=', $now->toDateString())->whereDate('enddate', '>=', $now->toDateString())->where('status', '1')->get();
        // $data['holidays'] =  $holidays;

        $now = now();
        $currentYear = $now->year;
        $activeHolidays = Holiday::where('status', 1)->get();


        $data['holidays'] = $activeHolidays->filter(function ($holiday) use ($now, $currentYear) {
            $holidayStart = Carbon::parse($holiday->startdate);
            $holidayEnd = Carbon::parse($holiday->enddate);
            if ($holiday->is_fixed) {
                return $holidayStart->month === $now->month && $holidayStart->day === $now->day;
            }
            return $holidayStart->isSameDay($now);
        });
        return $data;
    }

    protected function credentials(Request $request)
    {
        return [
            'email' => $request->{$this->username()},
            'password' => $request->password,
            'status' => '1'
        ];
    }

    protected function validateLogin(Request $request)
    {
        if (setting('CAPTCHATYPE') == 'off') {
            $rules = [
                'email' => 'required|string|max:255',
                'password' => 'required|string|max:255'
            ];
        } else {
            if (setting('CAPTCHATYPE') == 'manual') {
                if (setting('RECAPTCH_ENABLE_ADMIN_LOGIN') == 'yes') {

                    $rules = [
                        'email' => 'required|string|max:255',
                        'password' => 'required|string|max:255',
                        'captcha' => 'required',
                    ];
                } else {

                    $rules = [
                        'email' => 'required|string|max:255',
                        'password' => 'required|string|max:255'
                    ];
                }
            }
            if (setting('CAPTCHATYPE') == 'google') {
                if (setting('RECAPTCH_ENABLE_ADMIN_LOGIN') == 'yes') {

                    $rules = [
                        'email' => 'required|string|max:255',
                        'password' => 'required|string|max:255',
                        'g-recaptcha-response'  =>  'required|recaptcha',
                    ];
                } else {
                    $rules = [
                        'email' => 'required|string|max:255',
                        'password' => 'required|string|max:255'
                    ];
                }
            }
        }




        // User type from email/username
        $user = User::where($this->username(), $request->{$this->username()})->first();

        $this->validate($request, $rules);
    }
    public function userInactiveMessage()
    {
        throw ValidationException::withMessages([
            $this->username() => ['error' => 'Your Account is Inactive. Please Contact to Admin.'],
        ]);
    }
    private function updateSettings($data)
    {
        foreach ($data as $key => $val) {
            $setting = Setting::where('key', $key);
            if ($setting->exists())
                $setting->first()->update(['value' => $val]);
        }
    }
    public function login(Request $request)
    {

        $this->validateLogin($request);

        // User type from email/username
        $user = User::where($this->username(), $request->{$this->username()})->first();
        $geolocation = GeoIP::getLocation(request()->getClientIp());
        $agent = new Agent();


        if ($user) {
            if ($user && $user->status == '0') {
                return $this->userInactiveMessage();
            }

            if ($user && $user->verified == '0') {
                return $this->userverifiedMessage();
            }

            // If the class is using the ThrottlesLogins trait, we can automatically throttle
            // the login attempts for this application. We'll key this by the username and
            // the IP address of the client making these requests into this application.


            if (
                method_exists($this, 'hasTooManyLoginAttempts') &&
                $this->hasTooManyLoginAttempts($request)
            ) {
                $this->fireLockoutEvent($request);

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

            if ($this->attemptLogin($request)) {

                $user = User::findOrFail(Auth::user()->id);
                $data['user'] = $user;
                $role = Role::where('name', $user->getRoleNames()[0])->first();
                $permissions = $role->getPermissionNames();
                if (setting('Employe_google_two_fact') == 'on' && User::where(['id' => $user->id, 'twofactorauth' => 'googletwofact'])->exists()) {
                    $request->session()->put('google2faemail', $request->email);
                    return response()->json(['success' => 'Login successful', 'user' => $user, 'permissions' => $permissions]);
                }

                if (setting('Employe_email_two_fact') == 'on' && User::where(['id' => $user->id, 'twofactorauth' => 'emailtwofact'])->exists()) {
                    if ($verifyuser = VerifyOtp::where('cust_id', $user->email)->exists()) {
                        $verifyuser = VerifyOtp::where('cust_id', $user->email)->first();
                        $verifyuser->delete();
                    }
                    $email = $user->email;
                    $verifyOtp = VerifyOtp::create([
                        'cust_id' => $email,
                        'otp' => rand(100000, 999999),
                        'type' => 'twofactorotp',
                    ]);

                    $guestticket = [

                        'otp' => $verifyOtp->otp,
                        'guestemail' => $verifyOtp->cust_id,
                        'guestname' => 'adminuser',
                    ];
                    try {
                        dispatch((new MailSend($verifyOtp->cust_id, 'two_factor_authentication_otp_send', $guestticket)));
                    } catch (\Exception $e) {
                    }
                    return response()->json(['success' => 'Login successful', 'user' => $user, 'permissions' => $permissions]);
                }

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

                $this->clearLoginAttempts($request);

                $activity = new EmployeeActivity();
                $activity->user_id = $user->id;
                $activity->activity_type = 'Logged in to the application';
                $activity->ip_address = $geolocation->ip;
                $activity->browser = $agent->browser();
                $activity->device = $agent->device();
                $activity->save();
                
                if ($response = $this->authenticated($request, $this->guard()->user())) {
                    return $response;
                }

                return response()->json(['success' => 'Login successful', 'user' => $user, 'permissions' => $permissions]);
            }
        }else {
            throw ValidationException::withMessages([
                $this->username() => ['error'=> lang('Account with email does not exist.', 'alerts')],
            ]);
        }

        $this->incrementLoginAttempts($request);

        $activity = new EmployeeActivity();
        $activity->user_id = $user->id;
        $activity->activity_type = 'Failed login attempt';
        $activity->ip_address = $geolocation->ip;
        $activity->browser = $agent->browser();
        $activity->device = $agent->device();
        $activity->save();

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


    public function userverifiedMessage()
    {
        throw ValidationException::withMessages([
            $this->username() => ['error' => 'Your Account is Not Verified.'],
        ]);
    }

    public function logout(Request $request)
    {
        $authId = auth()->user() ? auth()->user()->id : null; 
        if (!$authId) {
            return response()->json(['error' => 'User not found']);
        }
        $this->performLogout($request);


        $geolocation = GeoIP::getLocation(request()->getClientIp());
        $agent = new Agent();
        $activity = new EmployeeActivity();
        $activity->user_id = $authId;
        $activity->activity_type = 'Logged out of the application';
        $activity->ip_address = $geolocation->ip;
        $activity->browser = $agent->browser();
        $activity->device = $agent->device();
        $activity->save();

        return response()->json(['success' => 'Logout successful']);
    }
}
