<?php

namespace App\Http\Controllers\api\v1;

use App\Http\Controllers\Controller;
use App\Models\Notification;
use App\Models\NotificationSetting;
use App\Models\ParentApproval;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\TempUser;
use App\Models\UserDetail;
use Carbon\Carbon;
use Illuminate\Support\Facades\Validator;
use Hash;
use Kreait\Firebase\Contract\Database;

use Shaggyrec\Sumsubphp\SumSubClient;
use Illuminate\Support\Str;
use GuzzleHttp\Client;
use Shaggyrec\Sumsubphp\DTO\FixedInfo;




class AuthController extends Controller
{
    public $lang = '';
    public $database;

    public $sumsubClient;
    

    public function __construct(Database $database, Request $request)
    {
        $this->database = $database;
        
        if (isset($request->lang)) {
            \App::setLocale($request->lang);
        }
        $this->lang = \App::getLocale();

         $this->appToken = env('SUMSUB_APP_TOKEN');
        $this->secretKey = env('SUMSUB_APP_SECRET');

         $this->sumsubClient = SumSubClient::getInstance(env('SUMSUB_APP_TOKEN'), env('SUMSUB_APP_SECRET'));

    }

    public function getSumsubToken(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'external_customer_id' => 'required',
            'level_name' => 'required'
        ],[
            'external_customer_id.required' => 'External customer ID is required.',
            'level_name.required' => 'Level name is required.',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'status' => 0,
                'message' => 'Validation failed',
                'error' => $validator->messages(),
            ], 200);
        }

        $userId = $request->external_customer_id;
        $levelName = $request->level_name;

        try {
            $sumsubResponse = $this->sumsubClient->getAccessToken($userId, $levelName);

            return response()->json([
                'status' => 1,
                'message' => 'Sumsub access token generated successfully',
                'data' => $sumsubResponse,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status' => 0,
                'message' => 'Error generating Sumsub access token',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

  
    
     protected function signRequest($method, $url, $body = '')
    {
        $currentTimestamp = time();
        $signature = hash_hmac('sha256', $currentTimestamp . strtoupper($method) . $url . $body, $this->secretKey);

        return [
            'X-App-Token'      => $this->appToken,
            'X-App-Access-Ts'  => $currentTimestamp,
            'X-App-Access-Sig' => $signature,
            'Content-Type'     => 'application/json',
        ];
    }

    public function createApplicant(Request $request)
    {
        $validator = Validator::make($request->all(), [
        //  'email'      => 'required|email',
        // 'phone'      => 'required|string',
            'level_name' => 'required|string',
            'source'     => 'required|string',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'status'  => 0,
                'message' => 'Validation failed',
                'error'   => $validator->messages(),
            ], 200);
        }

        $attempt = 0;
        do {
            $externalCustomerId = 'cust_' . Str::uuid();
            $exists = User::where('external_customer_id', $externalCustomerId)->exists() ||
                    TempUser::where('external_customer_id', $externalCustomerId)->exists();
            $attempt++;
            if ($attempt > 5) {
                return response()->json([
                    'status' => 0,
                    'message' => 'Could not generate unique external customer ID',
                ], 500);
            }
        } while ($exists);
        $client = new Client();

        try {
            $payload = json_encode([
                'externalUserId' => $externalCustomerId,
                'phone'          => $request->phone??"",
                'email'          => $request->email??"",
                'fixedInfo'      => [
                    'firstName'   => '',
                    'lastName'    => '',
                    'gender'      => $request->gender??"",
                    'addresses'   => [],
                ],
            ]);

            $levelName = urlencode($request->level_name);

            $url = "https://api.sumsub.com/resources/applicants?levelName={$levelName}";

            $headers = $this->signRequest('POST', "/resources/applicants?levelName={$levelName}", $payload);

            $response = $client->request('POST', $url, [
                'headers' => $headers,
                'body'    => $payload,
            ]);

            $responseData = json_decode($response->getBody(), true);

            return response()->json([
                'status'               => 1,
                'message'              => 'Applicant created successfully',
                'data'                 => $responseData,
                'external_customer_id' => $externalCustomerId,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'status'  => 0,
                'message' => 'Error creating applicant',
                'error'   => $e->getMessage(),
            ], 500);
        }
    }


    // public function getSumsubToken(Request $request)
    // {
    //     $validator = Validator::make($request->all(), [
    //         'applicant_id' => 'required',
    //         'level_name'   => 'required',
    //     ]);

    //     if ($validator->fails()) {
    //         return response()->json([
    //             'status'  => 0,
    //             'message' => 'Validation failed',
    //             'error'   => $validator->messages(),
    //         ], 200);
    //     }

    //     $client = new Client();

    //     try {
    //         $payload = json_encode([
    //             'ttlInSecs'  => 600,
    //             'userId'     => $request->applicant_id,
    //             'levelName'  => $request->level_name,
    //         ]);

    //         $headers = $this->signRequest('POST', '/resources/accessTokens/sdk', $payload);

    //         $response = $client->request('POST', 'https://api.sumsub.com/resources/accessTokens/sdk', [
    //             'headers' => $headers,
    //             'body'    => $payload,
    //         ]);

    //         $responseData = json_decode($response->getBody(), true);

    //         return response()->json([
    //             'status'  => 1,
    //             'message' => 'Sumsub access token generated successfully',
    //             'data'    => $responseData,
    //         ]);
    //     } catch (\Exception $e) {
    //         return response()->json([
    //             'status'  => 0,
    //             'message' => 'Error generating Sumsub access token',
    //             'error'   => $e->getMessage(),
    //         ], 500);
    //     }
    // }
    
    public function getApplicantDetailsByExternalUserId(Request $request)
{
    $validator = Validator::make($request->all(), [
        'external_user_id' => 'required|string',
    ]);

    if ($validator->fails()) {
        return response()->json([
            'status'  => 0,
            'message' => 'Validation failed',
            'error'   => $validator->messages(),
        ], 200);
    }

    $externalUserId = $request->external_user_id;
    $client = new \GuzzleHttp\Client();

    try {
        $urlPath = "/resources/applicants/-;externalUserId={$externalUserId}/one";
        $url = "https://api.sumsub.com{$urlPath}";

        $headers = $this->signRequest('GET', $urlPath, '');

        $response = $client->request('GET', $url, [
            'headers' => $headers,
        ]);

        $responseData = json_decode($response->getBody(), true);

        return response()->json([
            'status'  => 1,
            'message' => 'Applicant details fetched successfully',
            'data'    => $responseData,
        ]);
    } catch (\Exception $e) {
        return response()->json([
            'status'  => 0,
            'message' => 'Error fetching applicant details',
            'error'   => $e->getMessage(),
        ], 500);
    }
}

  

    
    

    public function check_signup(Request $request){
        $status = "1";
        $message = trans('validation.check_signup_successfully');
        $o_data  = [];
        $errors = [];
        $is_social = 0;

        $rules = [
            'email' => 'required|email',
            'dial_code'=> 'required',
            'phone'    => 'required',
        ];

        $validator = Validator::make($request->all(), $rules);
        
        if ($validator->fails()) {
            return response()->json([
                'status' => "0",
                'message' => "Kindly fill all the mandatory fields",
                'error' => (object) $validator->messages(),
            ], 200);
        }

        if(User::where('email', $request->email)->first() !== null){
            $o_data['user']=convert_all_elements_to_string(User::where('email', $request->email)->first());
            return response()->json([
                'status' => "0",
                'error' => (object) array(),
                'message' => trans('validation.email_already_registered_please_login'),
                'oData'=>(object)$o_data
                 
            ], 200);
        }

        if (User::where('phone', $request->phone)->where('dial_code', $request->dial_code)->first() != null) {
            $o_data['user']=convert_all_elements_to_string(User::where('phone', $request->phone)->where('dial_code', $request->dial_code)->first());
            return response()->json([
                'status' => "0",
                'error' => (object) array(),
                'message' => trans('validation.phone_already_registered_please_login'),
                'oData'=>(object)$o_data
            ], 200);
        }

        return response()->json(['status' => $status, 'message' => $message,'oData'=>(object)$o_data,'errors'=>(object)$errors]);
    }
    //
    public function sign_up(Request $request){
        $status = "0";
        $message = "";
        $o_data  = [];
        $errors = [];
        $is_social = 0;


        

      

$rules = [
    'name' => 'required',
    //'nick_name' => 'required',
    'email' => 'required|email',
    'dial_code'=> 'required',
    'phone'    => 'required',
    'dob' => 'required|date',
    'gender' => 'required|in:Male,Female',
    'nationality_id' => 'required|exists:nationalities,id',
    'fcm_token' => 'required',
    'device_type' => 'required|in:android,ios,web',
    'password' => 'required',
];

            // ✅ Add base rules first
            $validator = Validator::make($request->all(), $rules);
            
            // ✅ Add conditional rules
            $validator->sometimes(['parent_name'], 'required', function ($input) {
                if ($input->gender === 'Female' && !empty($input->dob)) {
                    $age = Carbon::parse($input->dob)->age;
                    return $age < 30; // only required if age < 30
                }
                return false;
            });
            
            // $validator->sometimes('parent_email', 'email', function ($input) {
            //     return $input->gender === 'Female' && !empty($input->dob) && Carbon::parse($input->dob)->age < 30;
            // });


        
        if ($validator->fails()) {
            return response()->json([
                'status' => "0",
                'message' => "Kindly fill all the mandatory fields",
                'error' => (object) $validator->messages(),
            ], 200);
        }

        if(User::where('email', $request->email)->first() !== null){
            return response()->json([
                'status' => "0",
                'error' => (object) array(),
                'message' => trans('validation.email_already_registered_please_login'),
            ], 200);
        }

        if (User::where('phone', $request->phone)->where('dial_code', $request->dial_code)->first() != null) {
            return response()->json([
                'status' => "0",
                'error' => (object) array(),
                'message' => trans('validation.phone_already_registered_please_login'),
            ], 200);
        }

        $temp_user = TempUser::where('email', $request->email)->first();
        if(!$temp_user){
            $temp_user = TempUser::where('phone', $request->phone)->where('dial_code', $request->dial_code)->first();
        }
        $phone_otp = generate_otp();
        $email_otp = $phone_otp;

        $user = $temp_user ? $temp_user : new TempUser();

        $user->dial_code = $request->dial_code;
        $user->phone  = $request->phone;
        $user->user_phone_otp = $phone_otp;
        $user->user_email_otp = $email_otp;
        $user->name = $request->name;
        $user->nick_name = "LU-".time();
        $user->dob = $request->dob;
        $user->gender = $request->gender;
        $user->country_id = $request->nationality_id;
        $user->email = $request->email;
        $user->password = bcrypt($request->password);
        $user->user_device_type = $request->device_type;
        $user->user_device_token = $request->fcm_token;
        $user->parent_name = $request->parent_name ?? '';
        $user->parent_email = $request->parent_email ?? '';

         if ($request->is_mother_uae_national==1) {
            $user->is_mother_uae_national = $request->is_mother_uae_national;
            $user->is_pending_from_admin = 1;
        }
        
         if ($request->file('birth_certificate')) {
            $response = image_upload($request, config('global.user_image_upload_dir'), 'birth_certificate');
            if ($response['status']) {
                $user->birth_certificate = $response['link'];
               
            }
        }
        if ($request->file('mothers_emirates_id')) {
            $response = image_upload($request, config('global.user_image_upload_dir'), 'mothers_emirates_id');
            if ($response['status']) {
                $user->mothers_emirates_id = $response['link'];
                
            }
        }

        $user->gardien_relation = $request->gardien_relation ?? '';
        $user->gardien_phone_dial_code = $request->gardien_phone_dial_code ?? '';
        $user->gardien_phone_number = $request->gardien_phone_number ?? '';
        $user->is_mother_uae_nationality =$request->is_mother_uae_nationality??0;
        $user->is_user_uae_nationality =$request->is_user_uae_nationality??0;
        $user->save();
        $user->nick_name = "lUQ-".$user->id;
        $user->save();
        $status = "1";
        $message = "Please verify otp";
        $o_data = convert_all_elements_to_string($user->toArray());
        send_normal_SMS("OTP for verifying your account at Luqia is ".$email_otp,$user->dial_code.$user->phone );
        exec("php " . base_path() . "/artisan app:send-otp-mail " . $user->id . " > /dev/null 2>&1 & ");

        return response()->json(['status' => $status, 'message' => $message,'oData'=>(object)$o_data,'errors'=>(object)$errors]);
    }

    public function verify_otp(Request $request){
        $rules = [
            'user_id' => 'required',
            'otp' => 'required',
        ];
        $messages = [
            'user_id.required' => trans('validation.user_id_required'),
            'otp.required' => trans('validation.otp_required'),
        ];
        $validator = Validator::make($request->all(), $rules, $messages);

        if ($validator->fails()) {
            $message = trans('validation.validation_error_occured');
            $errors = $validator->messages();
            return response()->json([
                'status' => "0",
                'message' => $message,
                'error' => (object) $errors,
            ], 200);
        }

        $temp_user = TempUser::where('id', $request->user_id)->first();
        if (!($temp_user)) {
            $message = trans('validation.invalid_user');
            return response()->json([
                'status' => "0",
                'message' => $message,
                'error' => (object) array(),
            ], 401);
        }

        if (($temp_user->user_phone_otp == $request->otp)) {

            $user = User::where('email', $temp_user->email)->where('phone', $temp_user->phone)->first();
            $user = $user ? $user : new User();

            
            $user->name= $temp_user->name;
            $user->nick_name= $temp_user->nick_name;
            $user->email= $temp_user->email;
            $user->phone= $temp_user->phone ?? '';
            $user->dial_code= $temp_user->dial_code ?? '';
            $user->dob= $temp_user->dob;
            $user->nationality_id = $temp_user->country_id;
            $user->gender= $temp_user->gender;
            $user->email_verified_at= Carbon::now();
            $user->user_device_type= $temp_user->user_device_type;
            $user->user_device_token= $temp_user->user_device_token;
            $user->password= $temp_user->password;
            if ($temp_user->is_mother_uae_national==1) {
                $user->is_mother_uae_national = $temp_user->is_mother_uae_national;
                $user->is_pending_from_admin = $temp_user->is_pending_from_admin;
                $user->birth_certificate = $temp_user->birth_certificate;
                $user->mothers_emirates_id = $temp_user->mothers_emirates_id;
            }
            $user->birth_certificate = $temp_user->birth_certificate??'';
            $user->mothers_emirates_id = $temp_user->mothers_emirates_id??'';
            $user->is_mother_uae_nationality =$temp_user->is_mother_uae_nationality??0;
            $user->is_user_uae_nationality =$temp_user->is_user_uae_nationality??0;
                
            $user->user_phone_otp= '';
            $user->user_email_otp= '';
            $user->role_id= USER_ROLE;
            $user->phone_verified= 1;
            $user->status= 1;
            $user->gardien_relation = $temp_user->gardien_relation;
            $user->gardien_phone_dial_code = $temp_user->gardien_phone_dial_code;
            $user->gardien_phone_number = $temp_user->gardien_phone_number;


        if ($temp_user->gender == GENDER_FEMALE) {
            $age = Carbon::parse($temp_user->dob)->age;

            $user->parent_approval = ($age < 30) ? 0 : 1;
        }else{
            $user->parent_approval =  1;
        }
            $user->parent_name = $temp_user->parent_name;
            $user->parent_email = $temp_user->parent_email;
        

            
            $user->save();
            
            $user->user_number  = 'LQ' . str_pad($user->id, 6, '0', STR_PAD_LEFT);
            $user->save();

            UserDetail::create([
                'user_id' => $user->id,
            ]);

            foreach (NotificationSetting::SLUGS as $slug) {
                NotificationSetting::create([
                    'user_id' => $user->id,
                    'slug' => $slug,
                    'value' => 1,
                ]);
            }

            $tokenResult = $user->createToken('Personal Access Token')->accessToken;
            $token = $tokenResult->token;
            $tokenResult->expires_at = Carbon::now()->addWeeks(100);        
            $user->user_access_token = $token;        
            $user->save();

            if ($user->firebase_user_key == null) {
                $fb_user_refrence = $this->database->getReference('Users/')
                    ->push([
                        'fcm_token' => $user->fcm_token,
                        'user_name' => strtolower($user->user_name),
                        'email' => $user->email,
                        'user_id' => $user->id,
                        'user_image' => $user->profile_image_url,
                    ]);
                $user->firebase_user_key = $fb_user_refrence->getKey();
            }

            $uname = $user->name ?? $user->nick_name;
            $umail = $user->email;
            
            if (config('global.server_mode') == 'local') {
               \Artisan::call("send:send_verification_email --uri=" . urlencode("Your Luqia Account is Now Active!") . " --uri2=" . urlencode($umail) . " --uri3=" . urlencode($uname));
            } else {
               exec("php " . base_path() . "/artisan send:send_verification_email --uri=" . urlencode("Your Luqia Account is Now Active!") . " --uri2=" . urlencode($umail) . " --uri3=" . urlencode($uname) . " > /dev/null 2>&1 & ");
            }

            $temp_user->delete();

            send_notification_to_user(
                $this->database,
                $user,
                ['userId' => "", "imageBlur" => "0"],
                'alert',
                'user_registration',
                time(),
                trans('notification.user_registration_title', [], 'en') . "\n" . trans('notification.user_registration_title', [], 'ar'),
                trans('notification.user_registration_message', [], 'en') . "\n" . trans('notification.user_registration_message', [], 'ar')

            );

            $tokenResult = $user->createToken('Personal Access Token')->accessToken;
            return $this->loginSuccess($tokenResult, $user);

        } else {
            return response()->json([
                'status' => "0",
                'error' => (object) array(),
                'message' => trans('validation.code_does_not_match_you_can_request_for_resending_the_code'),
            ], 200);
        }
    }

    public function email_login(Request $request)
    {
        $rules = [
            'password' => 'required',
            'email' => 'required|email',
            'device_type' => 'required',
            'fcm_token' => 'required',
        ];
        $messages = [
            'password.required' => trans('validation.password_required'),
            'email.required' => trans('validation.email_required'),
            'email.email' => trans('validation.valid_email'),
            'fcm_token.required_if' => trans('validation.fcm_token_required'),
            'device_type.required' => trans('validation.device_type_required'),
        ];
        $validator = Validator::make($request->all(), $rules, $messages);

        if ($validator->fails()) {
            $status = 0;
            $message = trans('validation.validation_error_occured');
            $errors = $validator->messages();
            return response()->json([
                'status' => "0",
                'message' => $message,
                'error' => (object) $errors,
            ], 200);
        }
        $lemail = strtolower($request->email);
        $user = User::whereRaw("LOWER(email) = '$lemail'")->first();
        if ($user != null) {
            if (Hash::check($request->password, $user->password)) {
                $msg = '';
                if (!$user->status) {
                    return response()->json(['status' => "0", 'error' => (object) array(), 'message' => trans('validation.account_deactivated_please_contact_admin_for_more_information'), 'user' => null], 200);
                }
                // if ($user->is_pending_from_admin=='1') {
                //     return response()->json(['status' => "0", 'error' => (object) array(), 'message' => trans('validation.account_waiting_please_contact_admin_for_more_information'), 'user' => null], 200);
                // }
                // if ($user->is_pending_from_admin=='2') {
                //     return response()->json(['status' => "2", 'error' => (object) array(), 'message' => trans('validation.account_rejected_please_contact_admin_for_more_information'), 'reject_reason' => $user->reject_reason], 200);
                // }
                // if (!$user->email_verified) {
                //     return response()->json(['status' => "0", 'error' => (object) array(), 'message' => trans('validation.email_not_verified'), 'user' => $user, 'is_email_verifed' => 0], 200);
                // }
                $user->user_device_token = $request->fcm_token;
                $gen_otp = generate_otp();
                $mobile = $user->dial_code . $user->phone;
                $messagen = "OTP to confirm registration is " . $gen_otp;
                $user->user_phone_otp = $gen_otp;
                $user->save();
                send_notification_to_user(
                $this->database,
                $user,
                ['userId' => "", "imageBlur" => "0"],
                'alert',
                'user_login',
                time(),
                trans('notification.user_otp_title', [], 'en') . "\n" . trans('notification.user_otp_title', [], 'ar'),
                trans('notification.user_otp_message', [], 'en') . "\n" . trans('notification.user_otp_message', [], 'ar')

            );
                // send_normal_SMS($messagen, $mobile);
                $o_data=[]; 
                $o_data['user']=$user;
                return response()->json([
                    'oData' => convert_all_elements_to_string($o_data),
                    'status' => "1",
                    'message' => "To Sign in Successful please verify your Mobile otp",
                ], 200);
            } else {
                $o_data['user']=(object) array();
                return response()->json(['oData' => $o_data,'status' => "0", 'error' => (object) array(), 'message' => trans('invalid credentials')], 200);
            }
        } else {
            return response()->json(['status' => "0", 'error' => (object) array(), 'message' => trans('validation.invalid_credentials'), 'user' => null], 200);
        }
    }

    public function confirm_code(Request $request)
    {
        $rules = [
            'user_id' => 'required',
            'otp' => 'required',
        ];
        $messages = [
            'user_id.required' => trans('validation.user_id_required'),
            'otp.required' => trans('validation.otp_required'),
        ];
        $validator = Validator::make($request->all(), $rules, $messages);

        if ($validator->fails()) {
            $message = trans('validation.validation_error_occured');
            $errors = $validator->messages();
            return response()->json([
                'status' => "0",
                'message' => $message,
                'error' => (object) $errors,
            ], 200);
        }
        $user = User::where('id', $request->user_id)->first();
       
        if (empty($user)) {
            $message = trans('validation.invalid_user');
            return response()->json([
                'status' => "0",
                'message' => $message,
                'error' => (object) array(),
            ], 401);
        }
        if (($user->user_phone_otp == $request->otp)) {
            $user->email_verified_at = date('Y-m-d H:i:s');
            $user->email_verified = 1;
            $user->user_phone_otp = null;
            $tokenResult = $user->createToken('Personal Access Token')->accessToken;
            $token = $tokenResult->token;
            $tokenResult->expires_at = Carbon::now()->addWeeks(100);
            $user->user_access_token = $token;
            $user->save();
           
            // if (config('global.server_mode') == 'local') {
            //    \Artisan::call('update:firebase_node ' . $user->id);
            // } else {
             //   exec("php " . base_path() . "/artisan update:firebase_node " . $user->id . " > /dev/null 2>&1 & ");
            // }

            $uname = $user->name ?? $user->first_name . ' ' . $user->last_name;
            $umail = $user->email;

           
            


            // if (config('global.server_mode') == 'local') {
            //     \Artisan::call("send:send_reg_email --uri=" . urlencode("Welcome to The Laconcierge") . " --uri2=" . urlencode($umail) . " --uri3=" . urlencode($uname));
            // } else {
            //     exec("php " . base_path() . "/artisan send:send_reg_email --uri=" . urlencode("Welcome to The Laconcierge") . " --uri2=" . urlencode($umail) . " --uri3=" . urlencode($uname) . " > /dev/null 2>&1 & ");
            // }

  $users = User::with(['children', 'preference','nationality','emirate', 'country', 'images', 'details.sect', 'details.education', 'details.profession', 'details.maritalStatus', 'details.dressCode',  'plan', 'sports.sport', 'activities.activity', 'known_languages.language', 'notification_settings','geneticDiseases.geneticDisease','geneticDiseases.geneticDiseaseVariant.geneticDiseaseVariant'])
                ->find($user->id)
                ->toArray();
            $o_data=[]; 
                 convertNullRelationsToObjects($users);
                $o_data= convert_all_elements_to_string($users, true);
            return response()->json([
                'user' => $o_data,
                'status' => "1",
                'message' => trans('validation.account_verified_successfully'),
                'access_token' => $token,
            ], 200);
        } else {
            return response()->json([
                'status' => "0",
                'error' => (object) array(),
                'message' => trans('validation.code_does_not_match_you_can_request_for_resending_the_code'),
            ], 200);
        }
    }

    public function resend_phone_code(Request $request)
    {
        $rules = [
            'user_id' => 'required|exists:temp_users,id',
        ];
        $messages = [
            'user_id.required' => trans('validation.user_id_required'),
        ];
        $validator = Validator::make($request->all(), $rules, $messages);

        if ($validator->fails()) {
            $message = trans('validation.validation_error_occured');
            $errors = $validator->messages();
            return response()->json([
                'status' => "0",
                'message' => $message,
                'error' => (object) $errors,
            ], 200);
        }

        $temp_user = TempUser::where('id', $request->user_id)->first();

        $otp = (string)generate_otp();
        $temp_user->user_phone_otp = $otp;
        $temp_user->user_email_otp = $otp;

        $mobile = $temp_user->dial_code . $temp_user->phone;
        $messagen = "OTP to confirm registration is " . $otp;
        // send_normal_SMS($messagen, $mobile);
        $st = 1;
        if ($st != 1) {
            return response()->json([
                'status' => "0",
                'error' => (object) array(),
                'message' => $st,
            ], 201);
        }
        
        $otp = $temp_user->user_email_otp;
        $name = $temp_user->name ?? $temp_user->first_name;
        // $mailbody = view('email_templates.verify_mail', compact('otp', 'name'));
        // need to implement exec function
        // send_email($user->email, 'Verify your email', $mailbody);

        // if (config('global.server_mode') == 'local') {
        //     \Artisan::call("send:send_verification_email --uri=" . urlencode("Verify your email") . " --uri2=" . urlencode($temp_user->email) . " --uri3=" . $otp . " --uri4=" . urlencode($name));
        // } else {
        //     exec("php " . base_path() . "/artisan send:send_verification_email --uri=" . urlencode("Verify your email") . " --uri2=" . urlencode($temp_user->email) . " --uri3=" . $otp . " --uri4=" . urlencode($name) . " > /dev/null 2>&1 & ");
        // }
        
        $temp_user->save();

        return response()->json([
            'status' => "1",
            'message' => trans('validation.verification_code_is_sent_again'),
            'user' => $otp,
        ], 200);
    }

    public function resend_code(Request $request)
    {
        $rules = [
            'user_id' => 'required|exists:users,id',
        ];
        $messages = [
            'user_id.required' => trans('validation.user_id_required'),
        ];
        $validator = Validator::make($request->all(), $rules, $messages);

        if ($validator->fails()) {
            $message = trans('validation.validation_error_occured');
            $errors = $validator->messages();
            return response()->json([
                'status' => "0",
                'message' => $message,
                'error' => (object) $errors,
            ], 200);
        }

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

        if(!$user){
            return response()->json([
                'status' => "1",
                'message' => trans('validation.verification_code_is_sent_again'),
            ], 200);
        }

        $user->user_email_otp = (string)generate_otp();
        $user->user_email_otp = (string)generate_otp();

        $otp = $user->user_email_otp;
        // $name = $user->name ?? $user->first_name . ' ' . $user->last_name;
        // $mailbody = view('email_templates.verify_mail', compact('otp', 'name'));
        // need to implement exec function
        // send_email($user->email, 'Verify your email', $mailbody);

        // if (config('global.server_mode') == 'local') {
        //     \Artisan::call("send:send_verification_email --uri=" . urlencode("Verify your email") . " --uri2=" . urlencode($user->email) . " --uri3=" . $otp . " --uri4=" . urlencode($name));
        // } else {
        //     exec("php " . base_path() . "/artisan send:send_verification_email --uri=" . urlencode("Verify your email") . " --uri2=" . urlencode($user->email) . " --uri3=" . $otp . " --uri4=" . urlencode($name) . " > /dev/null 2>&1 & ");
        // }


        $user->save();

        return response()->json([
            'status' => "1",
            'message' => trans('validation.verification_code_is_sent_again'),
        ], 200);
    }

    protected function loginSuccess($tokenResult, $user, $msg = '')
    {
        $token = $tokenResult->token;
        $tokenResult->expires_at = Carbon::now()->addWeeks(100);
        $users = [];
        if (!empty($user)) {

            $users = User::with(['children', 'preference','nationality','emirate', 'country', 'images', 'details.sect', 'details.education', 'details.profession', 'details.maritalStatus', 'details.dressCode',  'plan', 'sports.sport', 'activities.activity', 'known_languages.language', 'notification_settings','geneticDiseases.geneticDisease','geneticDiseases.geneticDiseaseVariant.geneticDiseaseVariant'])
                ->find($user->id)
                ->toArray();
                 convertNullRelationsToObjects($users);
                $o_data = convert_all_elements_to_string($users, true);
        }

        $user->user_access_token = $token;
        $user->save();
        
        // if (config('global.server_mode') == 'local') {
        //    \Artisan::call('update:firebase_node ' . $user->id);
        // } else {
        //    exec("php " . base_path() . "/artisan update:firebase_node " . $user->id . " > /dev/null 2>&1 & ");
        // }
        return response()->json([
            'status' => "1",
            'message' => $msg ? $msg : trans('validation.successfully_logged_in'),
            'access_token' => $token,
            'token_type' => 'Bearer',
            'expires_at' => Carbon::parse($tokenResult->expires_at)->toDateTimeString(),
            'user' => $o_data,
        ]);
    }

    public function forgot_password(Request $request)
    {
        $status = "0";
        $message = "";
        $o_data = [];
        $errors = [];

        $rules['email'] = 'required';
        $messages = [
            'email.required' => trans('validation.email_required'),
        ];
        $validator = Validator::make($request->all(), $rules, $messages);
        if ($validator->fails()) {
            $status = "0";
            $message = trans('validation.validation_error_occured');
            $errors = $validator->messages();
        } else {

            $lemail = strtolower($request->email);
            $user = User::whereRaw("LOWER(email) = '$lemail'")->first();
            if ($user) {
                if ($user->is_social) {
                    $status = "0";
                    $o_data = (object) [];
                    $message = trans('validation.not_allowed_to_reset_password_for_social_login_account');
                    return response()->json(['status' => $status, 'error' => $errors, 'message' => $message, 'oData' => $o_data], 200);
                }

                $token = $this->get_user_token('password_reset_code');
                $password_reset_time = gmdate('Y-m-d H:i:s');
                $otp = (string)generate_otp();
                User::where("id", $user->id)->update(['password_reset_code' => $token, 'password_reset_time' => $password_reset_time, 'password_reset_otp' => $otp]);
                $name = $user->name ?? $user->nick_name;
                $res = false;
                // $mailbody = view("email_templates.forgot_mail", compact('name', 'otp'));

                // if (config('global.server_mode') == 'local') {
                //     \Artisan::call("send:send_forgot_email --uri=" . urlencode($user->email) . " --uri2=" . $otp . " --uri3=" . urlencode($name));
                // } else {
                //     exec("php " . base_path() . "/artisan send:send_forgot_email --uri=" . urlencode($user->email) . " --uri2=" . $otp . " --uri3=" . urlencode($name) . " > /dev/null 2>&1 & ");
                // }


                $res = true;

                if ($res) {
                    $message = trans('validation.we_have_sent_otp_to_your_phone_number_please_check_your_inbox');
                    $status = "1";
                    $o_data['password_reset_code'] = $token;
                    if($request->is_web){
                        $o_data['redirect_url'] = route('otp',['token'=>$token,'email'=>$lemail]);
                    }

                } else {
                    $status = "0";
                    $o_data = (object) [];
                    $message = trans('validation.something_went_wrong');
                }

            } else {
                $o_data = (object) [];
                $message = trans('validation.user_not_exist');
            }
        }
        return response()->json(['status' => $status, 'error' => $errors, 'message' => $message, 'oData' => $o_data], 200);
    }
    public function get_user_token($type = '')
    {
        $tok = bin2hex(random_bytes(32));
        if (User::where($type, '=', $tok)->first()) {
            $this->get_user_token($type);
        }
        return $tok;
    }

    public function reset_password_otp_verify(Request $request)
    {
        $status = "0";
        $message = "";
        $o_data = [];
        $errors = [];
        

        $rules = [
            'password_reset_code' => 'required',
            'otp' => 'required',
        ];
        $messages = [
            'password_reset_code.required' => trans('validation.password_reset_code_required'),
            'otp.required' => trans('validation.otp_required'),
        ];
        $validator = Validator::make($request->all(), $rules, $messages);

        if ($validator->fails()) {
            $status = "0";
            $message = trans('validation.validation_error_occured');
            $errors = $validator->messages();
        } else {
            $user = User::where('password_reset_code', $request->password_reset_code)->first();
            if ($user) {
                if ($request->otp == $user->password_reset_otp) {
                    $o_data['password_reset_code'] = $request->password_reset_code;
                    $status = "1";
                    $message = 'otp verified successfully';
                } else {
                    $message = trans('validation.invalid_otp');
                }
            } else {
                $message = trans('validation.invalid_otp');
            }
        }
        return response()->json(['status' => $status, 'message' => $message, 'errors' => $errors, 'oData' => (object)$o_data]);
    }
    public function reset_password(Request $request)
    {
        $status = "0";
        $message = "";
        $o_data = [];
        $errors = [];
        

        $rules = [
            'password_reset_code' => 'required',
            'otp' => 'required',
            'password' => 'required|confirmed',
        ];
        $messages = [
            'password_reset_code.required' => trans('validation.password_reset_code_required'),
            'otp.required' => trans('validation.otp_required'),
            'password.required' => trans('validation.password_required'),
            'password.confirmed' => trans('validation.password_confirmed'),
            'password_confirmation.required' => trans('validation.password_confirmation_required'),
        ];
        $validator = Validator::make($request->all(), $rules, $messages);

        if ($validator->fails()) {
            $status = "0";
            $message = trans('validation.validation_error_occured');
            $errors = $validator->messages();
        } else {
            $user = User::where('password_reset_code', $request->password_reset_code)->first();
            if ($user) {
                if ($request->otp == $user->password_reset_otp) {
                    $user->password = bcrypt($request->password);
                    $user->password_reset_code = '';
                    $user->password_reset_otp = 0;
                    $user->save();
                    $status = "1";
                    $message = trans('validation.password_updated_successfully');
                } else {
                    $message = trans('validation.invalid_otp');
                }
            } else {
                $message = trans('validation.invalid_otp');
                // $message = trans('validation.user_not_exist');
            }
        }
        return response()->json(['status' => $status, 'message' => $message, 'errors' => $errors, 'oData' => $o_data]);
    }

    public function resend_forgot_password_otp(Request $request)
    {
        $status = "0";
        $message = "";
        $o_data = [];
        $errors = [];

        $rules = [
            'password_reset_code' => 'required',
        ];
        $messages = [
            'password_reset_code.required' => trans('validation.password_reset_code_required'),
        ];
        $validator = Validator::make($request->all(), $rules, $messages);
        if ($validator->fails()) {
            $status = "0";
            $message = trans('validation.validation_error_occured');
            $errors = $validator->messages();
        } else {

            $user = User::where('password_reset_code', $request->password_reset_code)->first();
            if ($user) {

                $otp = (string)generate_otp();
                User::where("id", $user->id)->update(['password_reset_otp' => $otp]);

                $name = $user->name ?? $user->first_name . ' ' . $user->last_name;
                $res = false;

                // if (config('global.server_mode') == 'local') {
                //     \Artisan::call("send:send_forgot_email --uri=" . urlencode($user->email) . " --uri2=" . $otp . " --uri3=" . urlencode($name));
                // } else {
                //     exec("php " . base_path() . "/artisan send:send_forgot_email --uri=" . urlencode($user->email) . " --uri2=" . $otp . " --uri3=" . urlencode($name) . " > /dev/null 2>&1 & ");
                // }
                $res = true;

                if ($res) {
                    $message = trans('validation.we_have_e_mailed_an_otp_to_reset_your_password_please_check_your_inbox');
                    $status = "1";
                    $o_data['password_reset_code'] = $request->password_reset_code;

                } else {
                    $status = "0";
                    $o_data = (object) [];
                    $message = trans('validation.something_went_wrong');
                }

            } else {
                $o_data = (object) [];
                $message = trans('validation.user_not_exist');
            }
        }
        return response()->json(['status' => $status, 'error' => $errors, 'message' => $message, 'oData' => $o_data], 200);
    }
    
    public function logout(Request $request){
        $status = "0";
        $message = "";
        $o_data  = [];
        $errors = [];
        

        $validator = Validator::make($request->all(), [
            
            'access_token'=>'required'
        ]);
        
        if ($validator->fails()) {
            $status = "0";
            $message = "Kindly fill all the mandatory fields";
            $errors = $validator->messages();
            
        }else{
            $user_id = processAccesToken($request->access_token);
            $user = User::where(['id'=>$user_id])->get();
            if($user->count() > 0){
                $user =  $user->first();

                $user = User::find($user->id);
                $user->user_access_token = '';
                $user->user_device_token = '';
                $user->updated_at = gmdate('Y-m-d H:i:s');
                $user->save();
                $status = "1";
                $message = "Logout successfully ";
                
            }else{
                $status = "1";
                $message = "Alreaday loged out";
            }
            
        }
        return response()->json(['status' => $status, 'message' => $message,'oData'=>(object)$o_data,'errors'=>(object)$errors]);
    }
    
    public function delete_account(Request $request){
        $status = "0";
        $message = "";
        $o_data  = [];
        $errors = [];
        

        $validator = Validator::make($request->all(), [
            
            'access_token'=>'required'
        ]);
        
        if ($validator->fails()) {
            $status = "0";
            $message = "Kindly fill all the mandatory fields";
            $errors = $validator->messages();
            
        }else{
            $user_id = processAccesToken($request->access_token);
            $user = User::where(['id'=>$user_id])->get();
            if($user->count() > 0){
                $user =  $user->first();
                
                $user = User::find($user->id);
                $user->email = $user->email."__deleted_acount".$user->id;
                $user->phone = $user->phone."__deleted_acount".$user->id;
                $user->user_access_token = '';
                $user->user_device_token = '';
                $user->deleted = 1;
                $user->status = 0;
                $user->updated_at = gmdate('Y-m-d H:i:s');
                
                $user->save();
                $status = "1";
                $message = "Account removed successfully ";
                
            }else{
                
                $message = "Alreaday loged out";
                
            }
            
        }
        return response()->json(['status' => $status, 'message' => $message,'oData'=>(object)$o_data,'errors'=>(object)$errors]);
    }
     
}
