<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\Page;
use App\Models\ContactUs;
use Illuminate\Auth\Events\Registered;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Twilio\Rest\Client;
use Illuminate\Support\Facades\Mail;
use App\Mail\ContactUsMail;
use App\Mail\VpnWelcomeMail;
use Illuminate\Support\Facades\Validator;
use Exception;
use Illuminate\Validation\Rule;

class AuthController extends Controller
{
    
    // public function pages(Request $request)
    // {
    //      try
    //     {
    //         $data = Page::where('type', $request->type)->first();
            
    //         if($data)
    //         {
    //           return $this->jsonResponse(true, 200, 'Detail Fetched.',$data);
    //         }
    //         else
    //         {
    //           return $this->jsonResponse(true, 400, 'Error While Fetching Detail.',[]);
    //         }
    //     }
    //     catch(\Exception $e)
    //     {
    //       return $this->jsonResponse(false, 500, 'An error occurred.', null, 500, ["message" => $e->getMessage()]);
    //     }
    // }
    
    public function singPassLogin(Request $request)
    {
        
        $request->validate([
              'uinfin' => 'nullable',
            ]);
            
         try{
             
                $user = User::where('uinfin',$request->uinfin)->first();
            //  $user = User::where('callback_code', $request->callback_code)->first();
             
             if(!$user){
                return $this->jsonResponse(false, 400, 'No user found with the given code.'); 
             }
             
             // Ensure first_name exists before processing
            if (!empty(trim($user->first_name))) {
                $nameParts = explode(' ', trim($user->first_name), 2);
            
                $user->first_name = $nameParts[0]; // First word remains first_name
                $user->last_name = isset($nameParts[1]) ? $nameParts[1] : ($user->last_name ?? null); // Remaining words become last_name
            
                $user->save();
            }
             
              // Generate a JWT token for the user
                $token = Auth::guard('api')->login($user);
                
                $response =  [
                            'success' => true,
                            'data' => $user,
                            'token' => $token,
                            'status' => 200,
                            'message' => "Login successfull.",
                        ];
           
                return response()->json($response);        
                
            }catch(Exception $e){
                return $this->jsonResponse(false, 500, 'An error occurred.', null, 500, ["message" => $e->getMessage()]);
            }
    }
    
     public function sendVpnMail(Request $request) {
        $request->validate([
            'email' => 'required|email',
            ]);
             
             $data = [
                 'email' =>$request->email,
                 'subject' => 'Welcome Mail',
                 ];
             Mail::send(new VpnWelcomeMail($data));
                $response = [
                    'status' => 200,
                    "message" => "Email Sent Successfully.",
                    ];
            return response()->json($response,200);
            
    }
    
    public function getUserById($id)
    {
        $user = User::find($id);
        return $user;
    }

    public function register(Request $request){
            
        try{
            // Validator instance
            $validator = Validator::make($request->all(), [
                'first_name' => 'required|string|max:255',
                'last_name'  => 'nullable|string|max:255',
                'email'      => [
                                    'required',
                                    'string',
                                    'email',
                                    'max:255',
                                   Rule::unique('users')->where(function ($query) {
                                        return $query->where('is_otp_verified', 1); 
                                    })
                                ],
                'country_code' => 'required',
                'phone'      =>  [
                                    'required',
                                    Rule::unique('users')->where(function ($query) use($request) {
                                        return $query->where('is_otp_verified', 1)
                                        ->where('user_type', $request->user_type);
                                    }),
                                ],
                'user_type'  => 'required',
                'step'  => 'nullable',
                'timezone' => 'nullable',
                'address_lat' => 'required_if:user_type,2',
                'address_long' => 'required_if:user_type,2',
                'device_type' => 'nullable',
                'device_token' => 'nullable'
            ]);
        
            // If validation fails
            if ($validator->fails()) {
                
                $response = [
                    'status' => 400,
                    'message' => $validator->errors()->first(),
                ];
            
                return response()->json($response, 200);
            }
            
            
            $userExist = User::where('phone',$request->phone)->where('email', $request->email)->where('user_type',$request->user_type)->first();
           
            if($userExist){
                if($userExist->is_otp_verified == 0){
                    $userExist->update($request->all());
                    
                    $user = $this->getUserById($userExist->id);
                }else{
                     return $this->jsonResponse(true, 400, 'User Already Exist.');
                }
            }else{
                 $userEmailExist = User::where('email', $request->email)->exists();
                 if($userEmailExist){
                    return $this->jsonResponse(true, 400, 'The email has already been taken.');
                 }
                 $userData = $request->all();

                // Check if user_type is TYPE_RIDER and set status accordingly
                if ($request->user_type == User::TYPE_RIDER) {
                        $userData['status'] = 1;
                }
                
                    $userData['chat_token'] = $this->createChatToken(); 
                 
                 $user = User::create($userData);
                 
                 $user = $this->getUserById($user->id); 
            }
           
            if($user){
                
                $code = rand(100000, 999999);
                // $code = 111111;
                $user->otp = $code;
                $user->update();
                
                $message = 'Your OTP Verification Code is '.  $user->otp;
                
                $phone = $user->country_code . $user->phone;
                
                 $token = Auth::guard('api')->login($user);
                 
                 //send sms
                 $otpResponse =  $this->sendOtp($phone, $message); 
                   $response = [
                            'success' => true,
                            'data' => $user,
                            'token' => $token,
                            'status' => 200,
                        ];
                        
                 if($otpResponse['success'] == true){
                      $response['message'] = 'User created successfully.';
                 }else{
                       $response['message'] = 'User created successfully. Resend Otp to Verify.';
                 }
                 
            }else{
                 return response()->json([
                     'status' => 400,
                    'success' => false,
                    'message' => 'Error while register',
                ], 404);
            }
            
            return response()->json($response);
        
        } catch (Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'An Error Occur',
                'error' => ["message" =>$e-> getMessage()],
            ], 500);
        }
    }
    
    public function sendOtp($phone, $message)
     {
        $twilioSid = env('TWILIO_SID');
        $twilioAuthToken = env('TWILIO_AUTH_TOKEN');
        $twilioPhoneNumber = env('TWILIO_PHONE_NUMBER');
        
        try
        {
            // Check if values are correct before proceeding
            if (!$twilioSid || !$twilioAuthToken || !$twilioPhoneNumber) {
                
                $response = [
                        'status' => 500,
                        'message' => 'Twilio credentials are missing',
                    ];
                return response()->json($response, 500);
            }
    
            // Initialize the Twilio client
            $twilio = new Client($twilioSid, $twilioAuthToken);
            
            // Send the SMS
            $twilio->messages->create(
                $phone,  // To number
                [
                    'from' => $twilioPhoneNumber, 
                    'body' => $message,
                ]
            );
            
        $response = [
            'success' => true,
            'status' => 200,
            'message' => 'SMS sent successfully'];
          
         }
        catch (Exception $e)
         {
             \Log::info("Error:".$e->getMessage());
              $response = [
            'success' => false,
            'status' => 400,
            'message' => 'Failed to send Otp.Please try again later.',
            'error' => $e->getMessage(),
            ];
            //  echo "Error: " . $e->getMessage();
         }
        return $response;
     }
     
     public function resendOtp(Request $request)
     {
         try{
            //Auth User 
            $user = auth()->user();
            
            //Handle if user not found with given phone 
            if (!$user) {
                 return $this->jsonResponse(true, 401, 'User not found.');
            }
                
                $code = rand(100000, 999999);
                // $code = 222222;
                $user->otp = $code;
                $user->update();
              
                $appSign = $request->app_sign;
                
               
                    $message = 'Your OTP Verification Code is '. $user->otp;
                
                
                
                $phone = $user->country_code . $user->phone; 
                
                //Send Otp For Verification
                try{
                     $this->sendOtp($phone,$message);
                }catch(Exception $e){
                     \Log::info("An error occurred.". $e->getMessage());
                }
                
                return $this->jsonResponse(true, 200, 'OTP resent successfully.');
         }catch(Exception $e){
                 return $this->jsonResponse(false, 500, 'An error occurred.', null, 500, [$e->getMessage()]);
         }
    }

    public function login(Request $request)
    {
          // Validator instance
        $validator = Validator::make($request->all(), [
            'country_code' => 'required',
            'phone' => [
                    'required',
                    function ($attribute, $value, $fail) use ($request) {
                        // Custom logic for exists check
                        $countryCode = $request->input('country_code');
                        $phoneExists = \DB::table('users')
                            ->where('phone', $value)
                            ->where('country_code', $countryCode)
                            ->exists();
            
                        if (!$phoneExists) {
                            $fail('The entered phone number is not registered.');
                        }
                    },
                ],
             'user_type' => 'required',
            //  'device_type' => 'required',
            //  'device_token' => 'required',
        ]);
        
        try{
            // If validation fails
            if ($validator->fails()) {
                
                $response = [
                    'status' => 400,
                    'message' =>$validator->errors()->first(),
                ];
            
                return response()->json($response, 200);
            }
          
            // Fetch the user based on phone number
            $user = User::where('phone', $request->phone)->where('user_type',$request->user_type)->where('is_otp_verified',1)->first();
            
            // If user doesn't exist, return an error
            if (!$user) {
                return $this->jsonResponse(true, 400, 'User type is not matched or user not verified.');
            }
                if(is_null($user->chat_token)){
                    $user->chat_token = $this->createChatToken(); 
                }
                $code = rand(100000, 999999);
                // $code = 111111;
                $user->otp = $code;
                if($request->device_type != null){
                    $user->device_type = $request->device_type;    
                }
                if($request->device_token != null){
                    $user->device_token = $request->device_token;    
                }
                
                $user->update();
                
                $appSign = $request->app_sign;
                
                
                $message = 'Your OTP Verification Code is '. $code;
                
                $phone = $user->country_code . $user->phone; 
                
                
                // Generate a JWT token for the user
                $token = Auth::guard('api')->login($user);
            
                if (!$token) {
                     return $this->jsonResponse(false, 401, 'Unauthorized.');
                }
                
                //Send Otp For Verification
                 $otpResponse =   $this->sendOtp($phone, $message);
                if($otpResponse['success'] == true){
                       $response =     [
                                            'success' => true,
                                            'data' => $user,
                                            'token' => $token,
                                            'status' => 200,
                                            'message' => "Login successfull.",
                                        ];
                }else{
                    $response = [
                                    'success' => true,
                                    'data' => $user,
                                    'token' => $token,
                                    'status' => 200,
                                    'message' => "Login successfull. Resend otp to verify.",
                                ];
                }
            
            // $message = "Login successfull.";
            //check the driver is deactive then dont send authorization token
            // if($user->user_type == User::TYPE_DRIVER && $user->status == User::STATUS_DEACTIVE){
            //     $token = null;
            //     $message = "";
            // }
        
            return response()->json($response);
            
        }catch(Exception $e){
            return $this->jsonResponse(false, 500, 'An error occurred.', null, 500, ["message" => $e->getMessage()]);
        }
     
    }
    
    
    public function verifyOtp(Request $request)
    {
         // Validate phone and OTP
        $validator = Validator::make($request->all(), [
              'otp' => 'required',
        ]);
    
        // If validation fails
        if ($validator->fails()) {
            
            $response = [
                'status' => 400,
                
                'message' => $validator->errors()->first(),
            ];
        
            return response()->json($response, 200);
        }
        
        try{
            $user = auth()->user();
        
            //Match Otp and Empty the field
            if($user->otp == $request->otp){
                $user->otp = null;
                
                //otp verification while register 
                if($user->is_otp_verified == 0)
                {
                    $user->is_otp_verified = 1;        
                }
            
                $user->save();    
            }else{
                return $this->jsonResponse(true, 400, 'Invalid OTP.');
            }
            
            return $this->jsonResponse(true, 200, 'OTP Verified Successfully.');
            
        }catch(Exception $e){
            return $this->jsonResponse(false, 500, 'An error occurred.', null, 500, [$e->getMessage()]);
        }
    }
    
    public function contactUs(Request $request)
    {
        
        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:255',
            'subject' => 'required',
            'message' => 'required',
        ]);
    
        // If validation fails
        if ($validator->fails()) {
            
            $response = [
                'status' => 400,
                'message' => $validator->errors()->first(),
            ];
        
            return response()->json($response, 200);
        }
        try{
            $user = User::where('id', auth()->user()->id)->first();
            $data = $request->all();
            
            ContactUs::create([
                'name' => $request->name,
                'subject' => $request->subject,
                'message' => $request->message,
                'user_id' => $user->id,
            ]);
            
            $data['email'] = $user->email;
            
            // try {
            //     Mail::send(new ContactUsMail($data));
            // } catch (Exception $e) {
            //      return response()->json([
            //         'success' => false,
            //         'message' => 'Email not sent!. Reason: ' . $e->getMessage()
            //     ]);
            // }
            
            return $this->jsonResponse(true, 200, 'Your Request Is Submitted Successfully.');
            
        }catch(Exception $e){
            return $this->jsonResponse(false, 500, 'An error occurred.', null, 500, [$e->getMessage()]);
        }
        
    }


    public function logout()
    {
         try {
             
             Auth::guard('api')->logout();
            
            return $this->jsonResponse(true, 200, 'Log Out Successfully.');
            
         } catch (Exception $e) {
             
            return $this->jsonResponse(false, 500, 'An error occurred.', null, 500, [$e->getMessage()]);
        }
        
    }


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