<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Http\Request;

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Laravel\Passport\Passport;
use PHPMailer\PHPMailer\PHPMailer;

class AuthController extends Controller  {

        private $createdStatusCode = 201;
        private $successStatusCode = 200;
        private $errorStatusCode = 422;

         public function __construct() {
                $this->middleware('auth:api', ['except' => ['userRegistration' ,'userLogin', 'checkToken', 'checkEmail', 'userLoginV2', 'changePassword']]);
        }

        public function userRegistration(Request $request) {
             $validator = Validator::make($request->all(), [
                 'firstname' => 'required|string|max:255',
                 'lastname' => 'required|string|max:255',
                 'password' => 'required|min:6',
                 'phonenumber' => 'required|string|min:11|unique:users,phone_number',
                 'email' => 'required|email|unique:users,email'
             ]);

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

            $tokenExpires = Passport::personalAccessTokensExpireIn(now()->addDays(7));
            $request['password' ]  = Hash::make($request['password']);
            // Generate the ID for the user
            $id = self::generateId();


            $newUser = new User();
            $newUser->id = $id;
            $newUser->first_name = $request['firstname'];
            $newUser->last_name = $request['lastname'];
            $newUser->password = $request['password'];
            $newUser->phone_number  = $request['phonenumber'];
            $newUser->email = $request['email'];
            // Attempt to save the user
            $newUser->save();

            // Create the token using the same ID
            $calleduser = User::find($id);

            $success['token'] = $calleduser->createToken('laswarco-api', ['*'], ['expires_at' => $tokenExpires])->accessToken;

            // Update the user's verify code
            $verifycode = self::generateEmailToken();
            $verifycode = (string) $verifycode;
            $this->composeEmail('OTP', $verifycode, $request['email']);
            User::where('id', $id)->update(['verify_code' => $verifycode]);
            $templateData = [
                'name' => $calleduser->first_name,
            ];
            $templateContent = view('welcomeuser', $templateData)->render();
            $this->composeEmailV2('Welcome to LASWARCO!', $request['email'],  $templateContent);

            return response()->json(["message" => "registered successfully","token" => $success['token']], $this->createdStatusCode);

        }

        public function userLogin(Request $request) {

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

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

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

                if($user) {
                    if(Hash::check($request->password, $user->password)) {
                        $activeAccount = $user->account_active;
                        $existingToken = $user->tokens()->where('name', 'laswarco-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('laswarco-api', ['*'], ['expires_at' => $expiresAt])->accessToken;
                                    $success['verified_account'] = $user->verified_account;
                                    if($user->verified_account == 0){

                                        $verifyCode = $this->generateEmailToken();
                                        $verifyCode = (string) $verifyCode;
                                        $templateData = [
                                            'body' => $verifyCode,
                                            'name' => $user->first_name,
                                        ];
                                        $templateContent = view('emailtemplate', $templateData)->render();
                                        $this->composeEmailV2('OTP', $request->email,  $templateContent);

                                        User::where('id', $user->id)->update(['verify_code' => $verifyCode]);
                                    }
                                    return response()->json(['success' => $success], $this->successStatusCode);
                                } else {
                                    $success['token'] = $user->createToken('laswarco-api', ['*'], ['expires_at' => $expiresAt])->accessToken;
                                    $success['verified_account'] = $user->verified_account;
                                    if($user->verified_account == 0){
                                        $verifyCode = $this->generateEmailToken();
                                        $verifyCode = (string) $verifyCode;
                                        $templateData = [
                                            'body' => $verifyCode,
                                            'name' => $user->first_name,
                                        ];
                                        $templateContent = view('emailtemplate', $templateData)->render();
                                        $this->composeEmailV2('OTP', $request->email,  $templateContent);
                                        User::where('id', $user->id)->update(['verify_code' => $verifyCode]);
                                    }
                                    return response()->json(['success' => $success], $this->successStatusCode);
                                }
                            } else {
                                return response()->json(['message' => 'disabled'], $this->errorStatusCode);
                            }

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

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

            }

       public function userLoginV2(Request $request) {

           $validator = Validator::make($request->all(), [
               'email' => 'required|string|email|max:255',
               'password' => 'required|string|min:6',
           ]);

           if ($validator->fails())
           {
               return response(['errors'=>$validator->errors()->all()], $this->errorStatusCode);
           }

           $user = User::where('email', $request->email)->first();
           if ($user) {
               if (Hash::check($request->password, $user->password)) {
                   $expiresAt = Passport::personalAccessTokensExpireIn(now()->addDays(7));
                   $token = $user->createToken('laswarco-api', ['*'], ['expires_at' => $expiresAt])->accessToken;
                   if($user->verified_account === "0"){
                       $verifycode = self::generateEmailToken();
                       $verifycode = (string) $verifycode;
                       $this->composeEmail('OTP', $verifycode, $user->email);
                       User::where('id', (string)$user->id)->update(['verify_code' => $verifycode]);
                   }
                   $response = ['token' => $token, 'verify_status' => $user->verified_account];
                   return response($response, 200);
               } else {
                   $response = ["message" => "Password mismatch"];
                   return response($response, 422);
               }
           } else {
               $response = ["message" =>'User does not exist'];
               return response($response, 422);
           }
       }

        public function checkEmail(Request $request) {

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

        if($user === null) {
            return response()->json(['error' => 'Email  does not exist!'], 422);
        }
            $verifycode = self::generateEmailToken();
            $verifycode = (string) $verifycode;
            $this->composeEmail('OTP', $verifycode, $user->email);
            User::where('id', (string)$user->id)->update(['verify_code' => $verifycode]);
            return response()->json(['success' => 'Email  exists and OTP sent', 'userId' => $user->id], 200);
        }

        public  function checkToken(Request $request) {

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

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

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

            $usertoken = $user->verify_code;

            if($usertoken == $request['otp']) {
                //User::where('id', $request['userid'])->update(['account_active' => 1]);
                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;
                 $user = User::find((string)$userid);
                 $usertoken = $user->verify_code;

                if($usertoken == $request['otp']) {
                       User::where('id', (string)$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:6'
                    ]);

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

                     $user = $request['userid'];
                    $request['password' ]  = Hash::make($request['password']);
                    User::where('id', (string)$user)->where('verify_code', $request['otp'])->update(['password' => $request['password'], 'verify_code' => '']);
                    return response()->json(['message' => 'Password successfully changed'], 200);
            }
        }

        public function userChangePassword(Request $request) {

            $validator = Validator::make($request->all(), [
                'oldpassword' => 'required|min:6',
                'newpassword' => 'required|min:6'
            ]);

            if ($validator->fails())
            {
                return response(['errors'=>$validator->errors()->all()], $this->errorStatusCode);
            }

            $userId = Auth::user()->id;

            $hashPassword = Hash::make($request['newpassword']);
            $user = User::where('id', $userId)->first();
            $hasholdpassword = Hash::make($request['oldpassword']);
            if(Hash::check($request->oldpassword, $user->password)) {
                if(Hash::check($request->oldpassword, $hashPassword)) {
                    return response()->json(['data' => 'New password and old password can not be same.'], $this->errorStatusCode);
                } else {
                    User::where('id', $userId)->update(['password' => $hashPassword]);
                    return response()->json(['data' => 'Password successfully changed'], $this->successStatusCode);
                }
            } else {
                return response()->json(['data' => 'Wrong current password'], $this->errorStatusCode);
            }
        }

        public function getUserInfo() {

                $user = Auth::user();
                if($user) {
                    $userId  = $user->id;
                    $user = User::where('id', (string)$userId)->with(['kycDetails']);
                    $userInfo = $user->get();
                    $response = $userInfo;
                    return response()->json(['success' => true, 'data' => $response ], $this->successStatusCode);
                }
        }

        public function logout() {

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

        private static function loginCredential(Request $request) {

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

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

        private static  function  generateId() {
                $prefix = mt_rand(10, 99);
                $suffix = mt_rand(10, 99);
                $batchKey = Carbon::now()->format('Ymds');
                // $batchKey = Carbon::now()->format('Ym');
                return $prefix.$batchKey.$suffix;
        }

        // private static function generateId() {
        //     // Generate a random number within the range of BIGINT values
        //     $randomNumber = mt_rand((int)100000000000000, (int)99999999);

        //     // Get the current timestamp
        //     $currentTime = time();

        //     // Combine the random number and current timestamp to create the ID
        //     $id = $randomNumber . $currentTime;

        //     return $id;
        // }



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

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


        $mail = new PHPMailer(true);
        $mail->SMTPDebug = 0;
        $mail->isSMTP();
        $mail->Host = 'ssl://business74.web-hosting.com'; //ssl://smtp.gmail.com
        $mail->SMTPAuth = true;
        $mail->Username = 'noreply@laswarco.lg.gov.ng';
        $mail->Password = 'SH7ZL,&^^pCL';
        $mail->SMTPSecure = 'ssl';
        $mail->Port = 465;
        $mail->setFrom('noreply@laswarco.lg.gov.ng', 'Laswarco');
        $mail->addAddress($userEmail);
        $mail->addReplyTo('noreply@laswarco.lg.gov.ng', 'Laswarco');

        $mail->isHTML(true);

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

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

        $mail = new PHPMailer(true);
        $mail->SMTPDebug = 0;
        $mail->isSMTP();
        $mail->Host = 'ssl://business74.web-hosting.com'; //ssl://smtp.gmail.com
        $mail->SMTPAuth = true;
        $mail->Username = 'noreply@laswarco.lg.gov.ng';
        $mail->Password = 'SH7ZL,&^^pCL';
        $mail->SMTPSecure = 'ssl';
        $mail->Port = 465;
        $mail->setFrom('noreply@laswarco.lg.gov.ng', 'Laswarco');
        $mail->addAddress($userEmail);
        $mail->addReplyTo('noreply@laswarco.lg.gov.ng', 'Laswarco');

        $mail->isHTML(true);

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

    }

}
