<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\CompanySetting;
use App\Models\PasswordResetToken;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Str;

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;


class AuthController extends Controller
{
    // Register API (POST, FormData)


    public function register(Request $request)
    {
        // dd($request->UserType);
        try {
            $validator = Validator::make($request->all(), [
                'ExistingUser' => ['required', 'string', 'max:191'],
                'FirstName' => ['required', 'string', 'max:191'],
                // 'UserType' => ['required'],
                // 'SurName' => ['required', 'string', 'max:191'],
                'Username' => ['required', 'string', 'max:191', 'unique:users,Username'], // Corrected for uniqueness
                'email' => ['required', 'string', 'email', 'max:191', 'unique:users,email'], // Corrected for uniqueness
                'password' => ['required', 'confirmed', 'min:6'],
                // Rules\Password::defaults() // Uncomment this line if you want to use Laravel's default password rules
            ], [
                'ExistingUser.required' => "The Existing User field is required.",
                'FirstName.required' => "The First Name field is required.",
                // 'SurName.required' => "The Sur Name field is required.",
                'Username.required' => "The Username field is required.",
                'Username.unique' => "This Username is already taken.", // Custom error for uniqueness
                'email.required' => "The Email field is required.",
                'email.unique' => "This Email is already registered.", // Custom error for uniqueness
                'password.required' => "The Password field is required.",
                'password.min' => "The Password must be at least :min characters.",
                'password.confirmed' => "The Password confirmation does not match.",
            ]);

            if ($validator->fails()) {
                $errors = $validator->errors()->all();

                return response()->json([
                    'status' => false,
                    // 'message' => 'Validation failed',
                    'message' => implode(' ', $errors),
                ], 200);
            }

            $user = User::create([
                'ExistingUser' => $request->ExistingUser,
                'CustomerNo' => $request->CustomerNo,
                'InvoiceNo' => $request->InvoiceNo,
                'FirstName' => $request->FirstName,
                'SurName' => $request->SurName,
                'HouseName' => $request->HouseName,
                'StreetNo' => $request->StreetNo,
                'StreetName' => $request->StreetName,
                'Town' => $request->Town,
                'Area' => $request->Area,
                'County' => $request->County,
                'PostCode' => $request->PostCode,
                'ContactNo' => $request->ContactNo,
                'email' => $request->email,
                'Username' => $request->Username,
                'password' => Hash::make($request->password),
                'CustomerType' => $request->CustomerType,
                'ProcessStatus' => 'Active',
                'UserType' =>  'customer'
                // 'LastLogin' => $request->LastLogin
            ]);

            // Send registration email to the user (you can use the previous code for sending emails here)
            $companySettings = CompanySetting::find(1);
            $send = $this->sendRegistrationEmail($user, $companySettings);

            return response()->json([
                'status' => true,
                'message' => 'User registered successfully'
            ], 200);
        } catch (\Exception $e) {
            // Log the exception or handle it as needed
            return response()->json([
                'status' => false,
                'message' => 'Failed to register user',
                'error' => $e->getMessage()
            ], 200);
        }
    }


    private function sendRegistrationEmail($user, $companySettings)
    {

        $mail = new PHPMailer(true);

        try {

            $mail->isMail();

            //Recipients
            $mail->setFrom($companySettings->EmailAddress, $companySettings->Name);
            $mail->addAddress($user->email);
            $mail->addBCC($companySettings->EmailAddress);

            //Content
            $mail->isHTML(true);
            //Set email format to HTML
            $mail->Subject = 'Successful Registration';

            $mail->Body = "
                <html>
                    <head>
                        <style>
                            table {
                                border-collapse: collapse;
                                width: 100%;
                            }

                            th, td {
                                border: 1px solid #dddddd;
                                text-align: left;
                                padding: 8px;
                            }

                            th {
                                background-color: #f2f2f2;
                            }
                        </style>
                    </head>
                    <body>
                        <p>Dear " . $user->FirstName . "</p>
                        <p>Thank you for creating an account with us. We will let you know when your account has been activated.</p>
                        <p>Kind regards,<br>
                        " . $companySettings->Name . "</p>
                    </body>
                </html>";

            $send = $mail->send();
            return $send;
            // dd($send);

        } catch (Exception $e) {
            return response()->json([
                'status' => false,
                'message' => 'Failed to send the registration email',
                'error' => $e->getMessage()
            ], 200);
        }
    }


    public function sendResetCode(Request $request)
    {

        try {

            $validator = Validator::make($request->all(), [
                'email' => ['required', 'string', 'lowercase', 'email', 'max:191'],
            ], [
                'email.required' => "The Email field is required.",
            ]);

            if ($validator->fails()) {
                $errors = $validator->errors()->all();

                return response()->json([
                    'status' => false,
                    // 'message' => 'Validation failed',
                    'message' => implode(' ', $errors),
                ], 200);
            }


            $user = User::where('email', $request->email)->first();
            if (!empty($user)) {
                $tokenCode =  random_int(100000, 999999);
                $tokenCodeString = strval($tokenCode);
                PasswordResetToken::create([
                    'email' =>  $request->email,
                    'token' =>  $tokenCode,
                ]);


                $companySettings = CompanySetting::find(1);
                $send = $this->sendResetCodeEmail($request->email, $tokenCode, $companySettings);

                return response()->json([
                    'status' => true,
                    'email_send' => $send,
                    'message' => $tokenCodeString,
                ], 200);
            } else {
                return response()->json([
                    'status' => false,
                    'email_send' => false,
                    'message' => 'The email address does not found!',
                ], 200);
            }
        } catch (\Exception $e) {
            // Log the exception or handle it as needed
            return response()->json([
                'status' => false,
                'message' => 'Failed to send the code',
                'error' => $e->getMessage()
            ], 200);
        }
    }


    private function sendResetCodeEmail($emailAddress, $tokenCode, $companySettings)
    {

        $mail = new PHPMailer(true);

        try {

            $mail->isMail();

            //Recipients
            $mail->setFrom($companySettings->EmailAddress, $companySettings->Name);
            $mail->addAddress($emailAddress);
            $mail->addBCC($companySettings->EmailAddress);

            //Content
            $mail->isHTML(true);
            //Set email format to HTML
            $mail->Subject = 'Reset Password Code';

            $mail->Body = "
                <html>
                    <head>
                        <style>
                            table {
                                border-collapse: collapse;
                                width: 100%;
                            }

                            th, td {
                                border: 1px solid #dddddd;
                                text-align: left;
                                padding: 8px;
                            }

                            th {
                                background-color: #f2f2f2;
                            }
                        </style>
                    </head>
                    <body>
                        <p>Dear Customer,</p>
                        <p>Please use the following code to proceed to reset the password.</p>
                        <h1>" . $tokenCode . "</h1>
                        <p>Regards,<br>
                        " . $companySettings->Name . "<br>
                        </p>
                    </body>
                </html>";

            $send = $mail->send();
            return $send;
            // dd($send);

        } catch (Exception $e) {
            // Handle exception if the email fails to send
            // Log or notify as needed
            // dd($e);
            return $e;
        }
    }


    public function verifyResetCode(Request $request)
    {

        try {

            $validator = Validator::make($request->all(), [
                'email' => ['required', 'string', 'lowercase', 'email', 'max:191'],
                'tokenCode' => ['required', 'string', 'max:6'],
            ], [
                'email.required' => "The Email field is required.",
                'tokenCode.required' => "The token code field is required.",
            ]);

            if ($validator->fails()) {
                $errors = $validator->errors()->all();

                return response()->json([
                    'status' => false,
                    // 'message' => 'Validation failed',
                    'message' => implode(' ', $errors),
                ], 200);
            }


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

                $tokenCode = $request->tokenCode;

                $tokenExists = PasswordResetToken::where('email', $request->email)
                    ->orderByDesc('created_at')->first();


                if ($tokenExists->token == $tokenCode) {
                    return response()->json([
                        'status' => true,
                        'message' => 'Token Code matched',
                    ], 200);
                } else {

                    return response()->json([
                        'status' => false,
                        'message' => 'Token code does not matched',
                    ], 200);
                }
            } else {
                return response()->json([
                    'status' => false,
                    'message' => 'The email address does not found!',
                ], 200);
            }
        } catch (\Exception $e) {
            // Log the exception or handle it as needed
            return response()->json([
                'status' => false,
                'message' => 'Failed to verify the code',
                'error' => $e->getMessage()
            ], 200);
        }
    }


    public function submitResetPassword(Request $request)
    {

        try {

            $validator = Validator::make($request->all(), [
                'email' => ['required', 'string', 'lowercase', 'email', 'max:191'],
                'password' => ['required', 'string', 'min:6', 'confirmed'],
            ], [
                'email.required' => "The Email field is required.",
                'password.required' => "The password field is required.",
                'password.confirmed' => "The passwords do not match.",
            ]);

            if ($validator->fails()) {
                $errors = $validator->errors()->all();

                return response()->json([
                    'status' => false,
                    'message' => implode(' ', $errors),
                ], 200);
            }


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

                $password = Hash::make($request->password);
                $user->update(['password' => $password]);

                return response()->json([
                    'status' => true,
                    'message' => 'Password changed successfully.',
                ], 200);
            } else {
                return response()->json([
                    'status' => false,
                    'message' => 'The email address does not found!',
                ], 200);
            }
        } catch (\Exception $e) {
            // Log the exception or handle it as needed
            return response()->json([
                'status' => false,
                'message' => 'Failed to validate the password.',
                'error' => $e->getMessage()
            ], 200);
        }
    }

    //Login API (POST, FormData)
    public function login(Request $request)
    {
        $userType = $request->user_type ? 'supplier' : 'customer';

        $validator = Validator::make($request->all(), [
            'Username' => ['required', 'string', 'max:191'],
            'password' => ['required'],
        ]);

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


        $user = User::where('Username', $request->Username)->where('UserType', $userType)->first();
        if (!empty($user)) {


            // Check if the user's ProcessStatus is Inactive
            if ($user->ProcessStatus === 'Inactive') {
                return response()->json([
                    'status' => false,
                    'message' => 'Please wait for us to activate your account',
                    'data' => null,
                ], 200);
            }


            // if ($user->deactivated_at) {
            //     return response()->json([
            //         'status' => false,
            //         'message' => 'Your account was deleted. Contact support for assistance.',
            //     ], 200); // Forbidden
            // }

            if (Hash::check($request->password, $user->password)) {
                // auth()->user()->tokens()->delete();
                $user->token = $user->createToken('token-api')->plainTextToken;

                // $companySettings = CompanySetting::find(1);
                // Get company settings
                // $companySettings = Config::get('company_settings');
                // dd($companySettings);


                $userData = $user->only(['id', 'FirstName', 'SurName', 'Username', 'email', 'token']);
                $userData = array_map(function ($value) {
                    return $value === null ? '' : $value;
                }, $userData);

                return response()->json([
                    'status' => true,
                    'message' => 'login successful',
                    'data' => $userData,
                    // 'company_settings' => $companySettings,
                    // 'settings' => $settings
                ], 200);
            }
        }



        // return response()->json(['error' => 'Unauthorized'], 401);

        return response()->json([
            'status' => false,
            'message' => 'Invalid username or password',
            'data' => null,
        ], 200);
    }



    //Profile API (GET)
    public function profile()
    {
        $data = auth()->user();


        if (!empty($data)) {
            return response()->json([
                'status' => true,
                'message' => 'Profile Data',
                'data' => $data
            ], 200);
        }


        return response()->json([
            'status' => false,
            'message' => 'Unauthorized'
        ], 401);
    }


    //Logout API (GET)
    public function logout(Request $request)
    {
        auth()->user()->tokens()->delete();
        return response()->json([
            'status' => true,
            'message' => 'User logged out'
        ], 200);
    }
}
