<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Events\Verified;
use Illuminate\Support\Facades\Validator;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules;
use Illuminate\Support\Str;

class AuthController extends Controller
{

    public function __construct()
    {
        $this->middleware('auth:api', ['except'=>['register', 'login','verify', 'sendPasswordResetLink', 'resetPassword'] ]);
    }

    public function login(Request $request)
    {
        $request->validate([
            'email' => 'required|string|email',
            'password' => 'required|string',
        ]);
        $credentials = $request->only('email', 'password');

        $token = Auth::attempt($credentials);
        if (!$token) {
            return response()->json([
                'status' => 'error',
                'message' => 'Unauthorized',
            ], 401);
        }

        $user = Auth::user();
        return response()->json([
                'status' => 'success',
                'user' => $user,
                'authorisation' => [
                    'token' => $token,
                    'type' => 'bearer',
                ]
            ]);

    }

    public function register(Request $request){

        $validator = Validator::make($request->all(), [
            'first_name' => 'required|string',
            'last_name' => 'required|string',
            'email' => 'required|string|email|unique:users',
            'mobile' => 'required|string|unique:users',
            'password' => 'required|string|confirmed|min:6',
        ],
        [
            'first_name.required' => 'Kindly enter first name',
            'last_name.required' => 'Kindly enter last name',
            'email.required' => 'Kindly enter email',
            'email.unique' => 'Email already exist',
            'mobile.required' => 'Kindly enter mobile number',
            'mobile.unique' => 'Mobile already exist',
            'password.required' => 'Kindly enter password',
            'password.min' => 'Password should be at least 6 characters'
        ]
    );

        if($validator->fails()){
            return response()->json(  ['status' => 'error',
                'message' => $validator->errors()], 400);
        }

        $user = User::create([
            'name' => $request->first_name ." ".$request->last_name,
            'email' => $request->email,
            'mobile' => $request->mobile,
            'user_type' => 'USER',
            'password' => Hash::make($request->password)
        ]);

        event(new Registered($user)); // send email notification to user

      //  $token = Auth::login($user);

        return response()->json([
            'status' => 'success',
            'message' => 'User created successfully',
            'user' => $user
        ],201);

        
    }

    public function logout()
    {
        Auth::logout();
        return response()->json([
            'status' => 'success',
            'message' => 'Successfully logged out',
        ]);
    }

    public function refresh()
    {
        return response()->json([
            'status' => 'success',
            'user' => Auth::user(),
            'authorisation' => [
                'token' => Auth::refresh(),
                'type' => 'bearer',
            ]
        ]);
    }



    public function verify($id, $hash){

        $user = User::find($id);

        if (!$user) {
           return response()->json(['status' => 'error', 'message' => 'No user found'],401);
        }

        if (!hash_equals($hash, sha1($user->getEmailForVerification()))) {

            return response()->json(['status' =>'error', 'message' => 'invalid or expired link'],401);
        }


        if (!$user->hasVerifiedEmail()) {

            $user->markEmailAsVerified();

            event(new Verified($user));
           return response()->json(['status' => 'success','message' => 'Email verified'],200);
        }
    
        return response()->json(['status' => 'success', 'message' => 'Email already verified'],200);

    }


    public function resendVerificationLink(Request $request) {

        $request->user()->sendEmailVerificationNotification();
     
        return response()->json(['status' => 'success', 'message' => 'New verification link sent'],200);
    
    }


    public function sendPasswordResetLink(Request $request){

        $request->validate([
            'email' => ['required', 'email'],
        ]);

        $user = User::where('email',$request->email)->first();

        if (!$user) {
            return response()->json(['status' => 'error', 'message' => 'No user found'],401);
         }

        // We will send the password reset link to this user. Once we have attempted
        // to send the link, we will examine the response then see the message we
        // need to show to the user. Finally, we'll send out a proper response.
        
        $status = Password::sendResetLink($request->only('email'));

         if($status == Password::RESET_LINK_SENT){

            return response()->json(['status' => 'success', 'message' => 'Reset link sent successfully'],200);
         }
       
         return response()->json(['status' => 'error', 'message' => 'Internal server error'],500);
    }


    public function resetPassword(Request $request)
    {

        $request->validate([
            'token' => ['required'],
            'email' => ['required', 'email'],
            'password' => ['required', 'confirmed', Rules\Password::defaults()],
        ]);

        $user = User::where('email',$request->email)->first();

        if (!$user) {
            return response()->json(['status' => 'error' ,'message' => 'No user found'],401);
         }

        // Here we will attempt to reset the user's password. If it is successful we
        // will update the password on an actual user model and persist it to the
        // database. Otherwise we will parse the error and return the response.
        $status = Password::reset(
            $request->only('email', 'password', 'password_confirmation', 'token'),
            function ($user) use ($request) {
                $user->forceFill([
                    'password' => Hash::make($request->password),
                    'remember_token' => Str::random(60),
                ])->save();

                event(new PasswordReset($user));
            }
        );


        if($status == Password::PASSWORD_RESET){
            return response()->json(['status' => 'success' ,'message' => 'password reset successfully'],200);
        }

        

        return response()->json(['status' => 'error' , 'message' => 'Invalid or expired token'],422);
    }


    public function index(Request $request){
        return response()->json(['status' => 'success','message'=> 'Welcome to protected route'],200);
    }

}
