<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\UserWallet;
use App\Models\UserAdmin;
use Carbon\Carbon;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;
use Laravel\Passport\Passport;
use PHPMailer\PHPMailer\PHPMailer;


class AuthController extends Controller  {


    public function __construct() {

        $this->middleware('auth:api', ['except' => ['login', 'register','checkEmailorPhone',
            'forgetPassword', 'checkToken', 'changePassword', 'testbrevo']]);
    }

    public function register(Request $request)  {
        $recaptchaResponse = $this->verifyRecaptcha($request->recaptchaToken);
        
        Log::info($recaptchaResponse);
        
        if (!$recaptchaResponse['success']) {
            return response()->json([
                'error' => 'reCAPTCHA verification failed. Please try again.'
            ], 400);
        }
        
        $validator = Validator::make($request->all(), [
            'first_name' => 'required|string|max:255',
            'last_name' => 'required|string|max:255',
            'business_name' => 'required|string|max:255',
            'password' => 'required|min:8',
            'phone_number' => 'required|string|min:11',
            'email' => 'required|string|email|max:255'
        ]);

        if($validator->fails()) {

            return response()->json(['errors' => $validator->errors()->all()], 422);
        }


        $tokenExpires = Carbon::now()->addDays(7);
        $request['password' ]  = Hash::make($request['password']);
        $request['email'] = Str::lower($request['email']);
        $id = self::generateUserId();
        $newUser = new User();
        $newUser->id = $id;
        $newUser->first_name = $request['first_name'];
        $newUser->last_name = $request['last_name'];
        $newUser->business_name = $request['business_name'];
        $newUser->password = $request['password'];
        $newUser->phone_number = $request['phone_number'];
        $newUser->email = $request['email'];

        try {
            $newUser->save();
        } catch (Illuminate\Database\QueryException  $ex) {
            $errorCode = $ex->errorInfo[1];
            if ($errorCode == 1062) {
                Log::error("Duplicate entry  error: " .$ex->getMessage());
                return response()->json(['error' =>  $ex->getMessage()], 500);

            }
        }

        $success['token'] = $newUser->createToken('lasaa-api', ['*'], ['expires_at' => $tokenExpires])->accessToken;
        if(ctype_digit($request->phone_number)) {
            $modifyPhoneNumber = substr($request->phone_number, 1);
            $prepend = '234';
            $modifyPhoneNumber = $prepend . $modifyPhoneNumber;
        }

        $verifycode = $this->generateEmailToken();
        $verifycode = (string) $verifycode;
        //$this->composeEmail('OTP', $verifycode, $request->email);

        $templateData = [
           'body' => $verifycode,
           'name' => $request->first_name,
        ];
        $templateContent = view('emailtemplate', $templateData)->render();
        $this->composeEmailV2('OTP', $request->email,  $templateContent);
        $this->sendsmsV2($modifyPhoneNumber, $verifycode);
        User::where('id', $id)->update(['verify_code' => $verifycode]);
        $getUserObj = User::find($id);
        $wallet = new UserWallet();
        $getUserObj->userWallet()->save($wallet);
        return response()->json(["message" => "registered successfully","token" => $success['token']], 200);
    }

//    public function register(Request $request) {
//        $validator = Validator::make($request->all(), [
//            'first_name' => 'required|string|max:255',
//            'last_name' => 'required|string|max:255',
//            'business_name' => 'required|string|max:255',
//            'password' => 'required|min:8',
//            'phone_number' => 'required|string|min:11',
//            'email' => 'required|string|email|max:255'
//        ]);
//
//        if($validator->fails()) {
//            return response()->json(['errors' => $validator->errors()->all()], 422);
//        }
//
//        DB::beginTransaction();
//
//        try {
//            $tokenExpires = Carbon::now()->addDays(7);
//            $request['password' ]  = Hash::make($request['password']);
//            $request['email'] = Str::lower($request['email']);
//            $id = self::generateUserId();
//            $newUser = new User();
//            $newUser->id = $id;
//            $newUser->first_name = $request['first_name'];
//            $newUser->last_name = $request['last_name'];
//            $newUser->business_name = $request['business_name'];
//            $newUser->password = $request['password'];
//            $newUser->phone_number = $request['phone_number'];
//            $newUser->email = $request['email'];
//            try {
//                $newUser->save();
//            } catch (Illuminate\Database\QueryException  $ex) {
//                $errorCode = $ex->errorInfo[1];
//                if ($errorCode == 1062) {
//                    Log::error("Duplicate entry  error: " .$ex->getMessage());
//                    return response()->json(['error' =>  $ex->getMessage()], 500);
//                }
//            }
//            $getUserObj = User::find($id);
//            $wallet = new UserWallet();
//            $getUserObj->userWallet()->save($wallet);
//            DB::commit();
//
//            $success['token'] = $newUser->createToken('lasaa-api', ['*'], ['expires_at' => $tokenExpires])->accessToken;
//            if(ctype_digit($request->phone_number)) {
//                $modifyPhoneNumber = substr($request->phone_number, 1);
//                $prepend = '234';
//                $modifyPhoneNumber = $prepend . $modifyPhoneNumber;
//            }
//
//            $verifycode = $this->generateEmailToken();
//            $verifycode = (string) $verifycode;
//            //$this->composeEmail('OTP', $verifycode, $request->email);
//
//            $templateData = [
//                'body' => $verifycode,
//                'name' => $request->first_name,
//            ];
//            $templateContent = view('emailtemplate', $templateData)->render();
//            $this->composeEmailV2('OTP', $request->email,  $templateContent);
//            $this->sendsmsV2($modifyPhoneNumber, $verifycode);
//            User::where('id', $id)->update(['verify_code' => $verifycode]);
//            return response()->json(["message" => "registered successfully","token" => $success['token']], 200);
//        } catch (\Exception $exception) {
//            DB::rollBack();
//            return response()->json(['error' => 'Unable to create user'], 422);
//        }
//
//    }

    public function login(Request $request) {

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

        if (!$user) {
            return response()->json(['error' => 'Incorrect email or phonenumber'], 422);
        }

        $validate = Validator::make($request->all(), [
            'password' => 'required|min:8'
        ]);

        if ($validate->fails()) {
            return response()->json(['errors' => $validate->errors()->all()], 422);
        }


        if($user) {
            if(Hash::check($request->password, $user->password)) {
                $activeAccount = $user->account_active;
                $existingToken = $user->tokens()->where('name', 'lasaa-api')->first();
                $expiresAt = Passport::personalAccessTokensExpireIn(now()->addDays(7));
                if($activeAccount == 0) {
                    if($existingToken) {
                        if ($existingToken->expires_at < Carbon::now()) {
                            $existingToken->delete();
                            $success['token'] = $user->createToken('lasaa-api', ['*'], ['expires_at' => $expiresAt])->accessToken;
                            $success['verified_account'] = $user->verified_account;
                            if($user->verified_account == 0){
                                $modifyPhoneNumber = '';
                                if(ctype_digit($user->phone_number)) {
                                    $modifyPhoneNumber = substr($user->phone_number, 1);
                                }
                                $verifyCode = $this->generateEmailToken();
                                $verifyCode = (string) $verifyCode;
                                $templateData = [
                                    'body' => $verifyCode,
                                    'name' => $user->first_name,
                                ];
                                $templateContent = view('emailtemplate', $templateData)->render();
                                if(empty($user->created_by)){
                                }else{
                                    // var_dump($user->created_by);die();
                                    $minna = $user->created_by;
                                    $createdbymail = UserAdmin::find($minna);
                                    $this->composeEmailV2('OTP', $createdbymail->email,  $templateContent);
                                }
                                $this->composeEmailV2('OTP', $request->email,  $templateContent);
                                //$this->composeEmail('OTP', $verifyCode, $user->email);
                                $this->sendsmsV2($modifyPhoneNumber, $verifyCode);
                                User::where('id', $user->id)->update(['verify_code' => $verifyCode]);
                            }

                            return response()->json(['success' => $success], 200);
                        } else {
                            $success['token'] = $user->createToken('lasaa-api', ['*'], ['expires_at' => $expiresAt])->accessToken;
                            $success['verified_account'] = $user->verified_account;
                            if($user->verified_account == 0){
                                $modifyPhoneNumber = '';
                                if(ctype_digit($user->phone_number)) {
                                    $modifyPhoneNumber = substr($user->phone_number, 1);
                                }
                                $verifyCode = $this->generateEmailToken();
                                $verifyCode = (string) $verifyCode;
                                $templateData = [
                                    'body' => $verifyCode,
                                    'name' => $user->first_name,
                                ];
                                $templateContent = view('emailtemplate', $templateData)->render();
                                if(empty($user->created_by)){
                                }else{
                                    // var_dump($user->created_by);die();
                                    $minna = $user->created_by;
                                    $createdbymail = UserAdmin::find($minna);
                                    $this->composeEmailV2('OTP', $createdbymail->email,  $templateContent);
                                }
                                $this->composeEmailV2('OTP', $request->email,  $templateContent);
                                //$this->composeEmail('OTP', $verifyCode, $user->email);
                                $this->sendsmsV2($modifyPhoneNumber, $verifyCode);
                                User::where('id', $user->id)->update(['verify_code' => $verifyCode]);
                            }
                            return response()->json(['success' => $success], 200);
                        }
                    } else {
                        return response()->json(['message' => 'disabled'], 422);
                    }

                } else {
                    return response()->json(['error' => 'Account is not active'], 422);
                }

            } else {
                return response()->json(['error' => 'Wrong Password'], 422);
            }
        } else {
            return response()->json(['error' => 'Email/ Phonenumber and password are wrong'], 422);
        }

    }

    public function checkEmailorPhone(Request $request) {

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

        if($user === null) {
            return response()->json(['error' => 'Email / phonenumber does not exist!'], 422);
        } else {
            $modifyPhoneNumber = '';
            if(ctype_digit($request->email)) {
                $modifyPhoneNumber = substr($request->email, 1);
                $prepend = '234';
                $modifyPhoneNumber = $prepend . $modifyPhoneNumber;
            }
            $verifyCode = $this->generateEmailToken();
            $this->composeEmail('OTP', $verifyCode, $user->email);
            $this->sendsmsV2($modifyPhoneNumber, $verifyCode);
            User::where('id', $user->id)->update(['verify_code' => $verifyCode]);
            return response()->json(['success' => 'Email / phonenumber exists and OTP sent', 'userId' => $user->id], 200);
        }
    }

    public function checkToken(Request $request) {

        if($request->isMethod("PATCH")) {
            $validate =  Validator::make($request->all(), [
                'userid' => 'required',
                'otp' => 'required|integer'
            ]);

            if($validate->fails()) {
                return response()->json(['error' => $validate->errors()->all()], 422);
            }

            //var_dump($request['userid']); die();

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

            $usertoken = $user->verify_code;

            if($usertoken == $request['otp']) {
                return response()->json(['message' => 'Valid OTP!'], 200);

            } else {
                return response()->json(['message' => 'Invalid OTP!'], 422);
            }
        }
    }

    public function checkTokenReg(Request $request) {

        if($request->isMethod("PATCH")) {
            $validate =  Validator::make($request->all(), [
                'otp' => 'required|integer'
            ]);

            if($validate->fails()) {
                return response()->json(['error' => $validate->errors()->all()], 422);
            }


            $userid = Auth::user()->id;
            // var_dump($userid); die();
            $user = User::where('id', $userid)->first();

            $usertoken = $user->verify_code;

            if($usertoken == $request['otp']) {
                User::where('id', $userid)->update(['verify_code' => '', 'verified_account' => '1']);
                return response()->json(['message' => 'Valid OTP!'], 200);

            } else {
                return response()->json(['message' => 'Invalid OTP!'], 422);
            }
        }
    }

    public function changePassword(Request $request) {

        if($request->isMethod('PATCH')) {

            $validate = Validator::make($request->all(), [
                'userid' => 'required|integer',
                'otp' => 'required|integer',
                'password' => 'required|min:8'
            ]);

            if($validate->fails()) {
                return response()->json(['error' => $validate->errors()->all()], 422);
            }

            $user = $request['userid'];
            //var_dump($user); die();
            $request['password' ]  = Hash::make($request['password']);
            User::where('id', $user)->where('verify_code', $request['otp'])->update(['password' => $request['password'], 'verify_code' => '']);
            return response()->json(['message' => 'Password successfully changed'], 200);
        }
    }
    
    // private function verifyRecaptcha($token, $action = null) {
    //     $client = new \GuzzleHttp\Client();
    //     $response = $client->post('https://www.google.com/recaptcha/api/siteverify', [
    //         'form_params' => [
    //             'secret' => '6LeuIhwrAAAAABBbE5ecOqdUVt0BSEWAK1qppnc2',
    //             'response' => $token
    //         ]
    //     ]);
        
    //     $body = json_decode($response->getBody(), true);
        
    //     // Verify not only success and score, but also the action
    //     if ($action && (!isset($body['action']) || $body['action'] !== $action)) {
    //         $body['success'] = false; // Force failure if action doesn't match
    //     }
        
    //     return $body;
    // }
    
    private function verifyRecaptcha($token) {
        $client = new \GuzzleHttp\Client();
        $response = $client->post('https://www.google.com/recaptcha/api/siteverify', [
            'form_params' => [
                'secret' => '6LeuIhwrAAAAABBbE5ecOqdUVt0BSEWAK1qppnc2',
                'response' => $token
            ]
        ]);
        
        return json_decode($response->getBody(), true);
    }

    public function logout() {

        $token = Auth::user()->token();
        $token->revoke();
        return response()->json(['success' => true, 'message' => 'user successfully log out'], 200);

    }

    public function getUserInfo() {

        $user = Auth::user();
        if($user) {
            $userId  = $user->id;
            $user = User::where('id', $userId)->with(['expressionOfStreetLamps', 'kycdetail','kycThirdParty']);
            $userInfo = $user->get();
            $response = $userInfo;

            return response()->json(['success' => true, 'data' => $response ], 200);
        }
    }
    
    public function saveInstitution($id) {

        $user = Auth::user();
        if($user) {
            $userId  = $user->id;
            $user = User::where('id', $userId)->update(['is_institution' => $id]);
            $userInfo = User::where('id', $userId)->with(['expressionOfStreetLamps', 'kycdetail','kycThirdParty'])->get();
            $response = $userInfo;

            return response()->json(['success' => true, 'data' => $response ], 200);
        }
    }

    public function setUserType(Request $request) {
        if($request->isMethod('PATCH')) {
            $validator = Validator::make($request->all(), [
                'usertype' => 'required|string'
            ]);

            if($validator->fails()) {
                return response()->json(['error' => $validator->errors()->all(), 422]);
            }
            $user = Auth::user()->id;
            User::where('id', $user)->update(['user_type' => $request['usertype']]);
            return response()->json(['message' => 'User type set successfully'], 200);
        }
    }

    public static function generateUserId() {

        // $prefix = '121';
        $prefix =  mt_rand(10, 99);
        $suffix =  mt_rand(10, 99);
        $current = Carbon::now()->format('Ymds');
        return $prefix . $current . $suffix;
    }

    protected function loginCredential(Request $request) {

        if(is_numeric($request->get('email'))) {
            return ['phone_number' => $request->get('email'), 'password' => $request->get('password')];
        }
        elseif (filter_var($request->get('email'),  FILTER_VALIDATE_EMAIL)) {
            return ['email' => $request->get('email'), 'password' => $request->get('password')];
        }
    }

    public function generateEmailToken() {
        $emailToken = rand(100000, 999999);
        return $emailToken;
    }

    protected function domainExists($email)
    {
        // Extract the domain from the email address
        $parts = explode('@', $email);
        $domain = array_pop($parts);

        // Perform a DNS lookup for the domain
        $mxRecords = [];
        if (checkdnsrr($domain, 'MX')) {
            // MX records found, domain exists
            return true;
        } else {
            // No MX records found, domain does not exist
            return false;
        }
    }

    public function composeEmail($subject, $body,  $userEmail)
    {
        require base_path('vendor/autoload.php');

        $mail = new PHPMailer(true);
        $mail->SMTPDebug = 0;
        $mail->isSMTP();
        $mail->Host = 'smtp-relay.brevo.com'; //ssl://smtp.gmail.com
        $mail->SMTPAuth = true;
        $mail->Username = 'macdonnad@gmail.com';
        $mail->Password = 'xsmtpsib-93267ec9551960673300f309d7edd9a807648eb7aac5b10b6f80f2e106c7f010-dMSfPhNXDW84pqvY';
        // $mail->SMTPSecure = 'ssl';
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        $mail->Port = 587;
        $mail->setFrom('NoReply@lasaa.lg.gov.ng', 'Lasaa');
        $mail->addAddress($userEmail);
        $mail->addReplyTo('NoReply@lasaa.lg.gov.ng', 'Lasaa');

        $mail->isHTML(true);

        $mail->Subject = $subject;
        $mail->Body = "Verification code: " .$body;
        $mail->send();

    }

    public function composeEmailV2($subject, $userEmail, $emailContent) {

        require base_path('vendor/autoload.php');


        $mail = new PHPMailer(true);
        $mail->SMTPDebug = 0;
        $mail->isSMTP();
        $mail->Host = 'smtp-relay.brevo.com'; //ssl://smtp.gmail.com
        $mail->SMTPAuth = true;
        $mail->Username = 'macdonnad@gmail.com';
        $mail->Password = 'xsmtpsib-93267ec9551960673300f309d7edd9a807648eb7aac5b10b6f80f2e106c7f010-dMSfPhNXDW84pqvY';
        // $mail->SMTPSecure = 'ssl';
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        $mail->Port = 587;
        $mail->setFrom('noreply@lasaa.lg.gov.ng', 'Lasaa');
        $mail->addAddress($userEmail);
        $mail->addReplyTo('noreply@lasaa.lg.gov.ng', 'Lasaa');

        $mail->isHTML(true);

        $mail->Subject = $subject;
        $mail->Body = $emailContent;
        $mail->send();
    }

    public function sendsms($receiver, $token)
{
//        $curl = curl_init();
//
//        curl_setopt_array($curl, [CURLOPT_URL => "https://api.sendchamp.com/api/v1/verification/create",
//            CURLOPT_RETURNTRANSFER => true,
//            CURLOPT_ENCODING => "",
//            CURLOPT_MAXREDIRS => 10,
//            CURLOPT_TIMEOUT => 30,
//            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
//            CURLOPT_CUSTOMREQUEST => "POST",
//            CURLOPT_POSTFIELDS => json_encode(['meta_data' => ['first_name' => 'Paul'],
//                 'channel' => 'sms',
//                 'sender' => 'SendChamp',
//                'token_type' => 'numeric',
//                'token_length' => 6,
//                'expiration_time' => 3,
//                'customer_mobile_number' => $receiver,
//                 'token' => $token,
//                 'customer_email_address' => 'idemudiapaul@gmail.com']),
//        CURLOPT_HTTPHEADER => ["Authorization: Bearer sendchamp_live_".env('SENDCHAMP_KEY'),
//            "accept: application/json",
//            "content-type: application/json"],]);
//
//    $response = curl_exec($curl);
//    $err = curl_error($curl);
//
//    curl_close($curl);
//
//        if ($err) {
//                 Log::error( "cURL Error #:" . $err);
//        } else {
//                 Log::info( $response);
//        }

        return true;
    }

    public function sendsmsV2($receiver, $token) {

            try {
                require base_path('vendor/autoload.php');

                $client = new Client();

                $response = $client->request('POST', 'https://api.sendchamp.com/api/v1/sms/send', [
                    'body' => '{"to":["'.$receiver.'"],"message":"Welcome To Lasaa! Your OTP token is '.$token.', to activate your account. Exp in 3minutes. Thanks you lasaa.lg.gov.ng","sender_name":"Sendchamp","route":"dnd"}',
                    'headers' => [
                        'Authorization' => 'Bearer sendchamp_live_$2a$10$9LVM02NWEZ0mV3Z9tMmbb.4jlXR/dGEfMDfEIxgh9aEidal7FclfO',
                        'accept' => 'application/json',
                        'content-type' => 'application/json',
                    ],
                ]);

                // Check if the request was successful
                if ($response->getStatusCode() === 200) {
                    return true; // Return true if SMS was sent successfully
                } else {
                    // Log the error if the request was not successful
                    Log::error('Failed to send SMS. HTTP status code: ' . $response->getStatusCode());
                    return true; // Still return true to indicate that the function was executed successfully
                }
            } catch (\Exception $e) {
                // Log any exceptions that occur
                Log::error('Exception occurred while sending SMS: ' . $e->getMessage());
                return true; // Return true to indicate that the function was executed successfully
            }
        }
}
