<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Requests\Api\User\ProfileUpdateRequest;
use App\Http\Requests\Api\User\ResendVerifyPhoneRequest;
use App\Http\Requests\Api\User\UserLoginRequest;
use App\Http\Requests\Api\User\UserRequest;
use App\Http\Requests\Api\User\VerifyPhoneRequest;
use App\Http\Resources\Api\CitiesResource;
use App\Http\Resources\Api\CountriesResource;
use App\Http\Resources\Api\MessageResource;
use App\Http\Resources\Api\User\UserResource;
use App\Mail\VerifyPhone;
use App\Models\ActiveGuest;
use App\Models\Chat;
use App\Models\Child;
use App\Models\Country;
use App\Models\Message;
use App\Models\Product;
use App\Models\Setting;
use App\Models\Subscription;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Validator;
use Pusher\Pusher;
use Stevebauman\Location\Facades\Location;
use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Illuminate\Support\Facades\Http;
use Vonage\Client;
use Vonage\Messages\Channel\WhatsApp\WhatsAppText;
use GuzzleHttp\Client as cl;
use GuzzleHttp\Psr7\Request as req;
class AuthController extends Controller
{
    public function login(UserLoginRequest $request)
    {
        $data = $request->validated();
        $credentials = $request->only( 'phone', 'password');
//        $phone = $request->country_code.$request->phone;
        $phone = $request->phone;
        $token = Auth::guard('api')->attempt($credentials);
        if (!$token) {
            return msg(false, trans('lang.invalid_account'), failed());
        }
        if (Auth::guard('api')->user()->email_verified_at == null) {
            $otp = \Otp::generate(Auth::guard('api')->user()->phone);
            $email = Auth::guard('api')->user()->email;
            $result['otp'] = $otp;
            $data = $otp;
//            Mail::to($email)->send(new VerifyPhone($data));
            auth('api')->logout();
            return msg(false, trans('lang.verify_phone_first'), 403);
        }
        if (Auth::guard('api')->user()->status == 'inactive') {
            auth('api')->logout();
            return msg(false, trans('lang.user_inactive'), failed());
        }
        $result['token'] = $token;
        $result['client_data'] = UserResource::make(Auth::guard('api')->user()) ;
        if (isset($data['fcm_token'])) {
            Auth::guard('api')->user()->update(['fcm_token' => $data['fcm_token']]);
        }
        return msgdata(true, trans('lang.login_s'), $result, success());
    }

    public function register(UserRequest $request)
    {

        $dataa = $request->validated();
        $phone = $dataa['phone'];
        $children = $dataa['children'];
        $subscription = Subscription::find($dataa['subscription_id']);
        unset($dataa['children']);
        $dataa['status'] = 1;
        $user = User::create($dataa);
        foreach($children as $childname){
            $child = new Child();
            $child->name=$childname;
            $child->parent_id=$user->id;
            $child->expire_subscription=Carbon::now()->addDays($subscription->days);
            $child->save();
        }
        //sending otp to user
        $otp= \Otp::generate($phone);
//        $result['otp'] = $otp;

        $data = $otp;
        Mail::to($dataa['email'])->send(new VerifyPhone($data));
//        $message = 'كود التفعيل الخاص بك : '.$otp;
//
//        $this->sendWhatsAppMessage($phone,$message);
        return msgdata(true, trans('lang.sign_up_success'), $otp, success());

    }

    public function verifyPhone(Request $request)
    {


            $data = $request->validate([
                'country_code' => 'required|string',
                'phone' => 'required|string',
                'otp' => 'nullable|numeric|digits:4',
            ]);

            $phone =  $request->phone;
            $credentials = $request->only( 'phone');

            $validated_otp = \Otp::validate($phone, $data['otp']);

            if ($validated_otp->status == true) {

                $client = User::where('phone', $data['phone'])->first();
                if ($client) {
                    $client->email_verified_at = Carbon::now();
                    $client->save();
                    $token = JWTAuth::fromUser($client);
                    $result['token'] = $token;
                    $result['client_data'] = UserResource::make($client) ;
                    return msgdata(true, trans('lang.phone_verified_s'), $result, success());

//                    return msg(true, trans('lang.phone_verified_s'), success() ,);
                } else {
                    return msg(false, trans('lang.client_not_found'), failed());
                }
            } else {

                return msg(false, trans('lang.otp_invalid'), failed());

            }

    }


    public function sendOtp(VerifyPhoneRequest $request)
    {
        $data = $request->validated();

        $phone =  $data['phone'];
        $credentials = $request->only( 'phone');

        $otp= \Otp::generate($phone);
//        $result['otp'] = $otp;

        $data = $otp;
//        Mail::to($dataa['email'])->send(new VerifyPhone($data));
        $message = 'كود التفعيل الخاص بك : '.$otp;

        $this->sendWhatsAppMessage($phone,$message);

        return msgdata(true, trans('lang.code_send_to_email'),$otp, success());

    }



    public function resendVerifyPhone(ResendVerifyPhoneRequest $request)
    {
//        $data = $request->validated();
        $dataa = $request->validated();

        $phone = $dataa['phone'];
        $client = User::where('phone',$dataa['phone'])->first();
        $otp = \Otp::generate($phone);
//        if (env('APP_ENV') == 'local') {
//            $otp = "9999";
//        }
        $result['otp'] = $otp;
        $data = $otp;
        //TODO :send sms to phone number ...
        //Smsmisr::send("كود التحقق الخاص بك هو: " . $otp, $request->phone, null, 2);
        //sendSMS2($request->phone,$otp);
        //end sending
//        dd($client->email);
        Mail::to($client['email'])->send(new VerifyPhone($data));
        $message = 'كود التفعيل : '.$otp;
        $this->sendWhatsAppMessage($phone,$message);


        return msgdata(true, trans('lang.code_send_again_s'), $result, success());
    }

    public function profile()
    {
        $client = (new UserResource(Auth::guard('api')->user()));

        return msgdata(true, trans('lang.data_display_success'), $client, success());
    }
    public function UserProfile(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'profile_id' => 'nullable|exists:users,id',
        ]);
        if (!is_array($validator) && $validator->fails()) {
            return msg(false, $validator->errors()->first(), validation());
        }
        $BlockUsers = array(11632,11675,11676,11677);
        if(in_array($request->profile_id,$BlockUsers)){
            return msg(false, 'عفوا هذا الحساب مغلق', failed());
        }
        $client = (new UserResource(User::find($request->profile_id)));

        return msgdata(true, trans('lang.data_display_success'), $client, success());
    }
    public function searchProfile(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'search' => 'nullable',
        ]);
        if (!is_array($validator) && $validator->fails()) {
            return msg(false, $validator->errors()->first(), validation());
        }
        $client =  User::OrderBy('name','desc');
        if(isset($request->search)){
            $client->where('name','like','%'.$request->search.'%');
        }

        $data = UserResource::collection($client->paginate(10))->response()->getData(true);
        return msgdata(true, trans('lang.data_display_success'), $data, success());
    }

    public function profileUpdate(ProfileUpdateRequest $request)
    {
        $data = $request->validated();
        unset($data['confirm_password']);
        if (isset($data['image']) && is_file($data['image'])) {
            $data['image'] = upload($data['image'], 'clients_images');
        }

        User::where('id', \auth('api')->user()->id)->update($data);
        return msg(true, trans('lang.data_updated_s'), success());
    }






    /**
     * Write code on Method
     *
     * @return response()
     */

    /**
     * Write code on Method
     *
     * @return response()
     */
    public function submitForgetPasswordForm(Request $request)
    {
        $request->validate([
            'phone' => 'required|exists:users,phone',
        ]);

        $token = rand(1000, 9999);
        $client = User::where('phone',$request->phone)->first();
        if(isset($client)) {
            DB::table('user_password_rest')->insert([
                'phone' => $request->phone,
                'token' => $token,
                'created_at' => Carbon::now()
            ]);
            //TODO will make here send sms to client phone ...

//              Mail::send('email.forgetPassword', ['token' => $token], function($message) use($request){
//                 $message->to($request->email);
//               $message->subject('Reset Password');
//                });
            $otp = (string)$token;
            $result['email']=$client->email;

            Mail::to($client->email)->send(new VerifyPhone($otp));
//            $message = 'كود التفعيل : '.$token;
//            $this->sendWhatsAppMessage($client->phone,$message);
            return msgdata(true, trans('lang.email_sent'), $result, success());
        }else{
            return msg(false, trans('lang.client_not_found'), failed());
        }
    }
    /**
     * Write code on Method
     *
     * @return response()
     */

    /**
     * Write code on Method
     *
     * @return response()
     */
    public function submitResetPasswordForm(Request $request)
    {
        $request->validate([
            'phone' => 'required|exists:users,phone',
            'token' => 'required|numeric',
        ]);
        $updatePassword = DB::table('user_password_rest')
            ->where([
                'phone' => $request->phone,
                'token' => $request->token
            ])
            ->first();
        if (!$updatePassword) {
            return msgdata(true, trans('lang.token_invalid'), (object)[], failed());
        }
        $client = User::where('phone', $request->phone)->first();
        $token = auth('api')->login($client);
        if (!$token) {
            return msg(false, trans('lang.unauthorized'), failed());
        }
        $result['token'] = $token;
        $result['client_data'] = Auth::guard('api')->user();
        DB::table('user_password_rest')->where(['phone' => $request->phone])->delete();
        return msgdata(true, trans('lang.possword_rest'), $result, success());

    }

    public function changePassword(Request $request)
    {
        $request->validate([
            'old_password' => 'nullable|string',
            'password' => 'required|string|min:6|confirmed',
        ]);
        $client = auth('api')->user();
        if ($request->old_password) {
            if ($request->old_password) {
                $old_password = Hash::check($request->old_password, $client->password);
                if ($old_password != true) {
                    return msg(false, trans('lang.old_passwordError'), failed());
                }
            }
        }
        User::where('id', $client->id)
            ->update(['password' => bcrypt($request->password)]);
        return msg(true, trans('lang.password_changed_s'), success());
    }

    public function logout(Request $request)
    {
        User::find(auth('api')->id())->update(['fcm_token'=>null]);
        auth('api')->logout();
        return msg(true, trans('lang.logout_s'), success());
    }
    public function delete(Request $request){

        $array = array('deleted_at'=>Carbon::now());
        Product::where('user_id',Auth::guard('api')->user()->id)->forceDelete();
        User::where('id',Auth::guard('api')->user()->id)->forceDelete();
        return msg(true, trans('lang.deleted_s'), success());

    }
    public function delete2(Request $request){

//        $array = array('deleted_at'=>Carbon::now());
//        User::where('id',Auth::guard('api')->user()->id)->update($array);
        return msg(true, trans('lang.deleted_s'), success());

    }

    public function changePhone(Request $request){
        $validator = Validator::make($request->all(), [
            'country_code'=>'required',
            'phone' => 'required|unique:users,phone,'.Auth::guard('api')->user()->id,
        ]);

        if (!is_array($validator) && $validator->fails()) {
            return msg(false, $validator->errors()->first(), validation());
        }
        $token = rand(1000, 9999);
        DB::table('user_password_rest')->insert([
            'country_code' => $request->country_code,
            'phone' => $request->phone,
            'token' => $token,
            'created_at' => Carbon::now()
        ]);
        //TODO will make here send sms to client phone ...

        //  Mail::send('email.forgetPassword', ['token' => $token], function($message) use($request){
        //     $message->to($request->email);
        //   $message->subject('Reset Password');
        //    });
        $result['otp'] = (string)$token;

        return msgdata(true, trans('lang.updated_s'), $result['otp'] ,success());
    }
    public function ConfirmChangePhone(Request $request){
        $validator = Validator::make($request->all(), [
            'country_code'=>'required',
            'phone' => 'required|unique:users,phone,'.Auth::guard('api')->user()->id,
            'token'=>'required',
        ]);
        if (!is_array($validator) && $validator->fails()) {
            return msg(false, $validator->errors()->first(), validation());
        }
        $updatePhone = DB::table('user_password_rest')
            ->where([
                'country_code' => $request->country_code,
                'phone' => $request->phone,
                'token' => $request->token
            ])
            ->first();
        if (!$updatePhone) {
            return msgdata(true, trans('lang.token_invalid'), (object)[], failed());
        }
        $user = Auth::guard('api')->user();
        $user->phone=$request->phone;
        $user->save();

        return msgdata(true, trans('lang.updated_s') ,null,success());
    }
    public function updateStatus(Request $request){
        $validator = Validator::make($request->all(), [
            'is_active' => 'required|in:1,0',

        ]);
        if (!is_array($validator) && $validator->fails()) {
            return msg(false, $validator->errors()->first(), validation());
        }

        if(Auth::guard('api')->check()){
            $user = Auth::guard('api')->user();
            $user->is_active=$request->is_active;
            $user->fcm_token=$request->fcm_token;
            $user->save();

            $data['is_active']=$request->is_active;

            $options = array(
                'cluster' => env('PUSHER_APP_CLUSTER'),
                'encrypted' => true
            );

            $pusher = new Pusher(
                env('PUSHER_APP_KEY'),
                env('PUSHER_APP_SECRET'),
                env('PUSHER_APP_ID'),
                $options
            );
            $b = $pusher->trigger('userStatus-channel-'.$user->id, 'App\Events\chatEvent', $data);
//            $b2 = $pusher->trigger('MessageSent-channel-' . $user->id, 'App\Events\chatEvent', $data);
        }else{
            $ip = $request->ip();
            if ($position = Location::get($ip)) {
                $data = Country::where('name_en','like','%'.$position->countryName.'%')->first();
                if(isset($data)){
                    if($data->id == 2){
                        $country=  Country::where('id',6)->first();
                    }else{
                        $country=  $data;
                    }
                }else{
                    $country=  Country::where('id',6)->first();
                }
            }else{
                $country=  Country::where('id',6)->first();
            }
            if(isset($request->device_id) && $request->is_active == 1 && ActiveGuest::where('device_id',$request->device_id)->count() == 0){
                $guest = new ActiveGuest();
                $guest->device_id=$request->device_id;
                $guest->fcm_token=$request->fcm_token;
                $guest->type=$request->type;
                $guest->country_id=$country->id;
                $guest->save();
            }elseif(isset($request->device_id) && $request->is_active == 0){
                ActiveGuest::where('device_id',$request->device_id)->delete();
            }
        }

        return msg(true, trans('lang.updated_s'), success());

    }


    public function removeImage(Request $request){
        $validator = Validator::make($request->all(), [
            'type' => 'required|in:image,cover',
        ]);
        if (!is_array($validator) && $validator->fails()) {
            return msg(false, $validator->errors()->first(), validation());
        }
        if($request->type == 'image'){
            User::where('id',Auth::guard('api')->user()->id)->update(['image'=>null]);
        }elseif($request->type == 'cover'){
            User::where('id',Auth::guard('api')->user()->id)->update(['cover'=>null]);
        }
        return msg(true, trans('lang.deleted_s'), success());

    }

    public function updateVerifyOldData(){
        User::OrderBy('id','desc')->update(['email_verified_at' => Carbon::now()]);
        echo 'success';
    }

    public function whatsSendMessage($phone,$message)
    {
        $config = Brevo\Client\Configuration::getDefaultConfiguration()->setApiKey('api-key', 'YOUR_API_KEY');
        // Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
        // $config = Brevo\Client\Configuration::getDefaultConfiguration()->setApiKeyPrefix('api-key', 'Bearer');
        // Configure API key authorization: partner-key
        $config = Brevo\Client\Configuration::getDefaultConfiguration()->setApiKey('partner-key', 'YOUR_API_KEY');
        // Uncomment below to setup prefix (e.g. Bearer) for API key, if needed
        // $config = Brevo\Client\Configuration::getDefaultConfiguration()->setApiKeyPrefix('partner-key', 'Bearer');
        $apiInstance = new Brevo\Client\Api\TransactionalWhatsAppApi(
        // If you want use custom http client, pass your client which implements `GuzzleHttp\ClientInterface`.
        // This is optional, `GuzzleHttp\Client` will be used as default.
            new GuzzleHttp\Client(),
            $config
        );
        $sendWhatsappMessage = new \Brevo\Client\Model\SendWhatsappMessage(); // \Brevo\Client\Model\SendWhatsappMessage | Values to send WhatsApp message

        try {
            $result = $apiInstance->sendWhatsappMessage($sendWhatsappMessage);
            print_r($result);
        } catch (Exception $e) {
            echo 'Exception when calling TransactionalWhatsAppApi->sendWhatsappMessage: ', $e->getMessage(), PHP_EOL;
        }

    }

    public function sendWhatsAppMessage($to ='201099638383',$msg = 'otp is : 9999')
    {

        try {
            $token = "94gkwicoqyvc9qoi" ;
            $instanc = "instance93106" ;

            $params=array(
                'token' => $token,
                'to' => '+'.$to,
                'body' =>$msg
            );



            $client = new cl();
            $headers = [
                'Content-Type' => 'application/x-www-form-urlencoded'
            ];
            $options = ['form_params' =>$params ];
            $request = new req('POST', 'https://api.ultramsg.com/'.$instanc.'/messages/chat', $headers);
            $res = $client->sendAsync($request, $options)->wait();
        }catch (ClientException $e) {
            // Log the error message
            \Log::error('Client error sending message: ' . $e->getMessage());

            // Extract the response body
            $responseBody = $e->getResponse()->getBody()->getContents();

            // Handle the specific client error, for example returning a user-friendly message
            return false ;
        } catch (RequestException $e) {
            // Log the error message
            \Log::error('Error sending message: ' . $e->getMessage());

            // Handle other request exceptions gracefully
            return false ;
        }

//
//        $toNumber = '+201099638383';
//        $message = 'Hello, this is a test message.';
//
//        $whatsAppMessage = new WhatsAppText(
//            to: $toNumber,
//            from: '201099638383',
//            text: $message,
//        );
//
//        app(Client::class)
//            ->messages()
//            ->send($whatsAppMessage);


    }

    // Refresh the token
    public function refresh(Request $request)
    {
        $refreshed = JWTAuth::refresh(JWTAuth::getToken());
        $user = JWTAuth::setToken($refreshed)->toUser();
//
//        $oldToken = $request->bearerToken(); // This retrieves the access token from the Authorization header
//        $newToken = JWTAuth::refresh($oldToken);
        $result['token']=$refreshed;
        return msgdata(true, trans('lang.login_s'), $result, success());

        try {

        } catch (JWTException $e) {
            return msgdata(false, trans('lang.tokenJws_invalid'), (object)[] ,failed());
        }
    }




}
