<?php
require_once($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'include' . DIRECTORY_SEPARATOR . 'helper_functions' . DIRECTORY_SEPARATOR . 'data_request.php');

function invalidEmail($email) {
    
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $result = true;
    } else {
        $result = false;
    }
    return $result;
}

function emailExists($pdo, $email) {

    $userExistsArray = fetchData('users', ['email' => $email, 'deleted_at' => NULL]);
    $userExists = $userExistsArray[0] ?? null;

    if ($userExists) {
        return $userExists;
    }

    $propertyUserExistsArray = fetchData('property_users', ['email' => $email, 'deleted_at' => NULL]);
    $propertyUserExists = $propertyUserExistsArray[0] ?? null;

    if ($propertyUserExists) {
        return $propertyUserExists;
    }

    $adminsExistsArray = fetchdata('dealer_admins', ['email' => $email, 'deleted_at' => NULL]);
    $adminsExists = $adminsExistsArray[0] ?? null;

    return $adminsExists ?: false;
}

function emptyInputLogin($email, $pwd) {
    
    if (empty($email) || empty($pwd)) {
        $result = true;
    } else {
        $result = false;
    }
    return $result;
}

function auditTrail($uid, $prop) {

    if ($_SESSION['layer'] === 'super_admin' || $_SESSION['layer'] === 'admin' || $_SESSION['layer'] === 'dealer') {
        $auditdata = [
            'global_user_id'=>$uid,
            "csrf_token"=>$_SESSION['csrf_token']
        ];
    }else if ($_SESSION['layer'] === 'sub_dealer' || $_SESSION['layer'] === 'organization admin') {
        $auditdata = [
            'dealer_admin_id'=>$uid,
            "csrf_token"=>$_SESSION['csrf_token']
        ];
    }else {
        $auditdata = [
            'property_user_id'=>$uid,
            'property_id'=>$prop,
            "csrf_token"=>$_SESSION['csrf_token']
        ];
    }

    insertData('audit_trail_login', $auditdata);
    return;
}

function loginUser($pdo, $email, $pwd,$remember) {
    require_once('../../include/auth/auth_functions.php');  // Necessary for role-related functions

    session_start();  // Reset session data
    session_unset();
    session_destroy();

    if (invalidEmail($email) !== false) {
        header("Location: ../../login.php?error=invalidemail");
        exit();
    }

    $userExists = emailExists($pdo, $email);

    if ($userExists === false || $userExists['deleted_at'] != null) {
        header("location: ../../login.php?error=wrongemail");
        exit();
    }

    $pwdHashed = $userExists["password"];
    $checkPwd = password_verify($pwd, $pwdHashed);

    if ($checkPwd === false) {
        header("location: ../../login.php?error=invalidpassword");
        exit();
    }

    if (isset($userExists['role_type']) && isset($userExists['creator_type'])) {
        

        // Fetch additional user data if needed
        $userExistsDataArray = fetchData('property_users_data', ['property_user' => $userExists['id'], 'deleted_at' => null]);
        $userExistsData = $userExistsDataArray[0] ?? null;

        // Start session again and set common session variables
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }
        $_SESSION["userid"] = $userExists["id"];
        $_SESSION["propertyUserRole"] = $userExists["role"];
        $_SESSION["isPropertyUser"] = true;
        $_SESSION["isMultiPropUser"] = false;
        $_SESSION["name"] = $userExistsData["firstname"] . " " . $userExistsData["lastname"];
        $_SESSION["firstname"] = $userExistsData["firstname"];
        $_SESSION["lastname"] = $userExistsData["lastname"];
        $_SESSION["mobilenumber"] = formatPhoneNumber($userExistsData['mobile_number']);
        $_SESSION["homenumber"] = formatPhoneNumber($userExistsData['home_number']);
        $_SESSION["email"] = $userExists["email"];
        $_SESSION["custom"] = $userExistsData["custom"];
        $_SESSION["role"] = $userExistsData["role"];
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        $_SESSION["photo_loc"] = $userExistsData["photo_loc"];

        $proData = fetchData('profile_photo', ['user_id' => $userExists['id'], 'user_type' => 'users']);

        if ($proData) {
            $profileLocation = $proData[0]['location'];
            $_SESSION['user_type'] = $proData[0]['user_type'];

            $imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
            $fileExtension = strtolower(pathinfo($profileLocation, PATHINFO_EXTENSION));

            if (in_array($fileExtension, $imageExtensions)) {

                $_SESSION['profile_image'] = $profileLocation;
                unset($_SESSION['avatar_icon']);
            } else {

                $_SESSION['avatar_icon'] = $profileLocation;
                unset($_SESSION['profile_image']);
            }
        } else {

            $_SESSION['avatar_icon'] = "fas fa-user";
            unset($_SESSION['profile_image']);
        }

        // Determine the user's role layer based on the role system (prebuilt vs. custom)
        if ($_SESSION["custom"] === 1) {
            // Custom role logic
            $role = getCustomUserRoles($pdo, $_SESSION["role"]);
            $_SESSION["role_id"] = $role["id"];
            switch ($role["layer"]) {
                case "property":
                    $_SESSION["layer"] = "property admin";
                    break;
                case "organization":
                    $_SESSION["layer"] = "organization admin";
                default :
                    $_SESSION['layer'] = $role['layer'];
                    break;
                // Add other cases as needed based on your role system
            }
        } else {
            // Prebuilt role logic
            $role = getPropertyUserRoles($pdo, $_SESSION["role"]);
            $_SESSION["layer"] = $role["name"];  // Set layer from prebuilt role table
            $_SESSION["role_id"] = $role["id"];
        }

        // Automatically assign property based on role:
        if ($_SESSION["layer"] === "property admin" || $_SESSION["layer"] === "user") {
            // Property Admin only has 1 property
            $_SESSION["property"] = $userExists["property_id"];
        } elseif ($_SESSION["layer"] === "organization admin" || $_SESSION["layer"] === "dealer") {
            // Organization Admin/Dealer has multiple properties
            $properties = getProperty($_SESSION["userid"], $_SESSION["layer"]);   // Custom function to fetch properties
            $_SESSION["properties"] = $properties;  // Store all properties
            $_SESSION["property"] = $properties[0];  // Default to first property for now
        } else {
            // Admin and Super Admin have access to all properties (let them choose later)
            $_SESSION["property"] = null;
        }

        // Log the login action
        auditTrail($userExists["id"], $_SESSION["property"]);

        createAuditLog(
            $_SESSION["userid"],
            'Login',
            'audit_trail_login',
            null,
            $_SESSION["email"],
            $_SESSION["property"],
            null,
            null,
            'Property user login',
            'medium',
            'User management'
        );
        setCookieForLogin($remember);

        // Redirect to the appropriate start page or dashboard
        $settings = fetchDataSingle("app_settings",["userid"=>$_SESSION["userid"],"property_id"=>$_SESSION["property"],"user_email"=>$_SESSION["email"]]);
        if (!empty($settings)) {
            if(!empty($settings['starting_property_id'])){
                $_SESSION["property"]=$settings['starting_property_id'];
                $settings = fetchDataSingle("app_settings",["userid"=>$_SESSION["userid"],"property_id"=>$_SESSION["property"],"user_email"=>$_SESSION["email"]]);
            }
            $_SESSION["logout_duration"]=$settings['auto_logout_time'];
            $_SESSION["loginTime"] = time();
            if(!empty($settings['app_start_page'])) header("Location: /{$settings['app_start_page']}");
            else header("location: ../../dashboard.php");
        } else {
            $_SESSION["loginTime"] = time();
            header("location: ../../dashboard.php");
        }
        exit();
    } else {
        // Non-property level user logic
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }
        $_SESSION["userid"] = $userExists["id"];
        $_SESSION["name"] = $userExists["firstname"] . " " . $userExists["lastname"];
        $_SESSION["firstname"] = $userExists["firstname"];
        $_SESSION["lastname"] = $userExists["lastname"];
        $_SESSION["email"] = $userExists["email"];
        $_SESSION["layer"] = $userExists["layer"];  // Using `layer` from userExists
        $_SESSION["custom"] = 0;
        $rolesData=fetchData('roles', ['name' => $userExists["layer"]]);
        $_SESSION["role"] = $rolesData[0]['id'];
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        // Set a property variable if a property-level user
        if (!empty($userExists["property_id"])) {
            $_SESSION["property"] = $userExists["property_id"];
        } else {
            $_SESSION["property"] = null;
        }

        // Automatically assign property based on role:
        if ($_SESSION["layer"] === "property admin") {
            // Property Admin only has 1 property
            $_SESSION["property"] = $userExists["property_id"];
        }elseif ($_SESSION["layer"] === "dealer") {
            $userExistsDataArray = fetchData('users_data', ['user_id' => $userExists['id'], 'deleted_at' => null]);
            $userExistsData = $userExistsDataArray[0] ?? null;
            $_SESSION["photo_loc"] = $userExistsData["photo_loc"];
            //Dealer has multiple properties
            $properties = getProperty($_SESSION["userid"], $_SESSION["layer"]);  // Custom function to fetch properties
            if($properties) {
                $_SESSION["properties"] = $properties;  // Store all properties
                $_SESSION["property"] = $properties[0]['id'];  // Default to first property for now
            }else {
                $_SESSION["property"] = null;
            }
        }elseif ($_SESSION["layer"] === "organization admin" || $_SESSION["layer"] === "sub_dealer") {
            
            $userExistsDataArray = fetchData('dealer_admins_data', ['dealer_admins_id' => $userExists['id'], 'deleted_at' => null]);
            $userExistsData = $userExistsDataArray[0] ?? null;
            $_SESSION["photo_loc"] = $userExistsData["photo_loc"];
            $properties = getProperty($_SESSION["userid"], $_SESSION["layer"]);  // Custom function to fetch properties
            if($properties) {
                $_SESSION["properties"] = $properties;  // Store all properties
                $_SESSION["property"] = $properties[0]['id'];  // Default to first property for now
            }else {
                $_SESSION["property"] = null;
            }
        }else {
            // Admin and Super Admin have access to all properties (let them choose later)
            $_SESSION["property"] = null;
        }

        if ($_SESSION['layer'] === 'sub_dealer' || $_SESSION['layer'] === 'organization admin') {
            $proData = fetchData('profile_photo', ['user_id' => $userExists['id'], 'user_type' => 'dealer_admins']);
        }else {
            $proData = fetchData('profile_photo', ['user_id' => $userExists['id'], 'creator_type' => 'users']);
        }

        if ($_SESSION['layer'] === 'super_admin' || $_SESSION['layer'] === 'admin' || $_SESSION['layer'] === 'dealer') {
            $adminData = fetchData('users_data', ['user_id' => $userExists['id']]);

            $profileLocation = $adminData[0]['photo_loc'];
            $_SESSION['user_type'] = 'admin';

            $imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
            $fileExtension = strtolower(pathinfo($profileLocation, PATHINFO_EXTENSION));

            if (in_array($fileExtension, $imageExtensions)) {

                $_SESSION['profile_image'] = $profileLocation;
                unset($_SESSION['avatar_icon']);
            } else {

                $_SESSION['avatar_icon'] = $profileLocation;
                unset($_SESSION['profile_image']);
            }

        }else if ($proData) {
            $profileLocation = $proData[0]['location'];
            $_SESSION['user_type'] = $proData[0]['user_type'];

            $imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
            $fileExtension = strtolower(pathinfo($profileLocation, PATHINFO_EXTENSION));

            if (in_array($fileExtension, $imageExtensions)) {

                $_SESSION['profile_image'] = $profileLocation;
                unset($_SESSION['avatar_icon']);
            } else {

                $_SESSION['avatar_icon'] = $profileLocation;
                unset($_SESSION['profile_image']);
            }
        } else {

            $_SESSION['avatar_icon'] = "fas fa-user";
            unset($_SESSION['profile_image']);
        }

        if ($_SESSION['layer'] === 'super_admin' || $_SESSION['layer'] === 'admin' || $_SESSION['layer'] === 'dealer') {
            auditTrail($_SESSION["userid"], $_SESSION["property"]);
            createAuditLog(
                $_SESSION["userid"],
                'Login',
                'audit_trail_login',
                null,
                $_SESSION["email"],
                null,
                null,
                null,
                'Admin Login',
                'medium',
                'User management'
            );
        }else if ($_SESSION['layer'] === 'sub_dealer' || $_SESSION['layer'] === 'organization admin') {
            auditTrail($_SESSION["userid"], $_SESSION["property"]);
            createAuditLog(
                $_SESSION["userid"],
                'Login',
                'audit_trail_login',
                null,
                $_SESSION["email"],
                null,
                null,
                null,
                'Dealer Admin Login',
                'medium',
                'User management'
            );
        }else {
            // Log the login action
            auditTrail($_SESSION["userid"], $_SESSION["property"]);
            createAuditLog(
                $_SESSION["userid"],
                'Login',
                'audit_trail_login',
                null,
                $_SESSION["email"],
                $_SESSION["property"],
                null,
                null,
                'Global user login',
                'medium',
                'User management'
            );
        }
        // Redirect to the appropriate start page or dashboard
        $settings = fetchDataSingle("app_settings",["userid"=>$_SESSION["userid"],"property_id"=>$_SESSION["property"],"user_email"=>$_SESSION["email"]]);
        setCookieForLogin($remember);
        if (!empty($settings)) {
            if(!empty($settings['starting_property_id'])){
                $_SESSION["property"]=$settings['starting_property_id'];
                $settings = fetchDataSingle("app_settings",["userid"=>$_SESSION["userid"],"property_id"=>$_SESSION["property"],"user_email"=>$_SESSION["email"]]);
            }
            $_SESSION["logout_duration"]=$settings['auto_logout_time'];
            $_SESSION["loginTime"] = time();
            if(!empty($settings['app_start_page'])) header("Location: /{$settings['app_start_page']}");
            else header("location: ../../dashboard.php");
        } else {
            $_SESSION["loginTime"] = time();
            header("location: ../../dashboard.php");
        }
        exit();
    }
}

function loginUserAPI($pdo, $email, $pwd) {
    require_once('include/auth/auth_functions.php');  // Necessary for role-related functions

    session_start();  // Reset session data
    session_unset();
    session_destroy();

    if (invalidEmail($email) !== false) {
        echo json_encode(["success" => false, "message" => "Invalid email format"]);
        exit();
    }

    $userExists = emailExists($pdo, $email);

    if ($userExists === false || $userExists['deleted_at'] != null) {
        echo json_encode(["success" => false, "message" => "Invalid email or user deleted"]);
        exit();
    }

    $pwdHashed = $userExists["password"];
    $checkPwd = password_verify($pwd, $pwdHashed);

    if ($checkPwd === false) {
        echo json_encode(["success" => false, "message" => "Invalid password"]);
        exit();
    }

    if (isset($userExists['role_type']) && isset($userExists['creator_type'])) {
        

        // Fetch additional user data if needed
        $userExistsDataArray = fetchData('property_users_data', ['property_user' => $userExists['id'], 'deleted_at' => null]);
        $userExistsData = $userExistsDataArray[0] ?? null;

        // Start session again and set common session variables
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }
        $_SESSION["userid"] = $userExists["id"];
        $_SESSION["propertyUserRole"] = $userExists["role"];
        $_SESSION["isPropertyUser"] = true;
        $_SESSION["isMultiPropUser"] = false;
        $_SESSION["name"] = $userExistsData["firstname"] . " " . $userExistsData["lastname"];
        $_SESSION["firstname"] = $userExistsData["firstname"];
        $_SESSION["lastname"] = $userExistsData["lastname"];
        $_SESSION["mobilenumber"] = formatPhoneNumber($userExistsData['mobile_number']);
        $_SESSION["homenumber"] = formatPhoneNumber($userExistsData['home_number']);
        $_SESSION["email"] = $userExists["email"];
        $_SESSION["custom"] = $userExistsData["custom"];
        $_SESSION["role"] = $userExistsData["role"];
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        $_SESSION["photo_loc"] = $userExistsData["photo_loc"];

        $proData = fetchData('profile_photo', ['user_id' => $userExists['id'], 'creator_type' => 'property_users']);

        if ($proData) {
            $profileLocation = $proData[0]['location'];
            $_SESSION['user_type'] = $proData[0]['user_type'];

            $imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
            $fileExtension = strtolower(pathinfo($profileLocation, PATHINFO_EXTENSION));

            if (in_array($fileExtension, $imageExtensions)) {

                $_SESSION['profile_image'] = $profileLocation;
                unset($_SESSION['avatar_icon']);
            } else {

                $_SESSION['avatar_icon'] = $profileLocation;
                unset($_SESSION['profile_image']);
            }
        } else {

            $_SESSION['avatar_icon'] = "fas fa-user";
            unset($_SESSION['profile_image']);
        }

        // Determine the user's role layer based on the role system (prebuilt vs. custom)
        if ($_SESSION["custom"] === 1) {
            // Custom role logic
            $role = getCustomUserRoles($pdo, $_SESSION["role"]);
            $_SESSION["role_id"] = $role["id"];
            switch ($role["layer"]) {
                case "property":
                    $_SESSION["layer"] = "property admin";
                    break;
                case "organization":
                    $_SESSION["layer"] = "organization admin";
                default :
                    $_SESSION['layer'] = $role['layer'];
                    break;
                // Add other cases as needed based on your role system
            }
        } else {
            // Prebuilt role logic
            $role = getPropertyUserRoles($pdo, $_SESSION["role"]);
            $_SESSION["layer"] = $role["name"];  // Set layer from prebuilt role table
            $_SESSION["role_id"] = $role["id"];
        }

        // Automatically assign property based on role:
        if ($_SESSION["layer"] === "property admin" || $_SESSION["layer"] === "user") {
            // Property Admin only has 1 property
            $_SESSION["property"] = $userExists["property_id"];
        } elseif ($_SESSION["layer"] === "organization admin" || $_SESSION["layer"] === "dealer") {
            // Organization Admin/Dealer has multiple properties
            $properties = getProperty($_SESSION["userid"], $_SESSION["layer"]);   // Custom function to fetch properties
            $_SESSION["properties"] = $properties;  // Store all properties
            $_SESSION["property"] = $properties[0];  // Default to first property for now
        } else {
            // Admin and Super Admin have access to all properties (let them choose later)
            $_SESSION["property"] = null;
        }

        // Log the login action
        auditTrail($userExists["id"], $_SESSION["property"]);
        createAuditLog(
            $_SESSION["userid"],
            'Login',
            'audit_trail_login',
            null,
            $_SESSION["email"],
            $_SESSION["property"],
            null,
            null,
            'Mobile App Login',
            'medium',
            'User management'
        );

        echo json_encode([
            "success" => true,
            "message" => "Login successful",
            "session_id" => session_id(),
            "user" => $_SESSION
        ]);
        
        exit();
    } else {
        // Non-property level user logic
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }
        $_SESSION["userid"] = $userExists["id"];
        $_SESSION["name"] = $userExists["firstname"] . " " . $userExists["lastname"];
        $_SESSION["firstname"] = $userExists["firstname"];
        $_SESSION["lastname"] = $userExists["lastname"];
        $_SESSION["email"] = $userExists["email"];
        $_SESSION["layer"] = $userExists["layer"];  // Using `layer` from userExists
        $_SESSION["custom"] = 0;
        $rolesData=fetchData('roles', ['name' => $userExists["layer"]]);
        $_SESSION["role"] = $rolesData[0]['id'];
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
        // Set a property variable if a property-level user
        if (!empty($userExists["property_id"])) {
            $_SESSION["property"] = $userExists["property_id"];
        } else {
            $_SESSION["property"] = null;
        }

        // Automatically assign property based on role:
        if ($_SESSION["layer"] === "property admin") {
            // Property Admin only has 1 property
            $_SESSION["property"] = $userExists["property_id"];
        }elseif ($_SESSION["layer"] === "dealer") {
            $userExistsDataArray = fetchData('users_data', ['user_id' => $userExists['id'], 'deleted_at' => null]);
            $userExistsData = $userExistsDataArray[0] ?? null;
            $_SESSION["photo_loc"] = $userExistsData["photo_loc"];
            //Dealer has multiple properties
            $properties = getProperty($_SESSION["userid"], $_SESSION["layer"]);  // Custom function to fetch properties
            if($properties) {
                $_SESSION["properties"] = $properties;  // Store all properties
                $_SESSION["property"] = $properties[0]['id'];  // Default to first property for now
            }else {
                $_SESSION["property"] = null;
            }
        }elseif ($_SESSION["layer"] === "organization admin" || $_SESSION["layer"] === "sub_dealer") {
            
            $userExistsDataArray = fetchData('dealer_admins_data', ['dealer_admins_id' => $userExists['id'], 'deleted_at' => null]);
            $userExistsData = $userExistsDataArray[0] ?? null;
            $_SESSION["photo_loc"] = $userExistsData["photo_loc"];
            $properties = getProperty($_SESSION["userid"], $_SESSION["layer"]);  // Custom function to fetch properties
            if($properties) {
                $_SESSION["properties"] = $properties;  // Store all properties
                $_SESSION["property"] = $properties[0]['id'];  // Default to first property for now
            }else {
                $_SESSION["property"] = null;
            }
        }else {
            // Admin and Super Admin have access to all properties (let them choose later)
            $_SESSION["property"] = null;
        }

        if ($_SESSION['layer'] === 'sub_dealer' || $_SESSION['layer'] === 'organization admin') {
            $proData = fetchData('profile_photo', ['user_id' => $userExists['id'], 'user_type' => 'dealer_admins']);
        }else {
            $proData = fetchData('profile_photo', ['user_id' => $userExists['id'], 'creator_type' => 'users']);
        }

        if ($_SESSION['layer'] === 'super_admin' || $_SESSION['layer'] === 'admin' || $_SESSION['layer'] === 'dealer') {
            $adminData = fetchData('users_data', ['user_id' => $userExists['id']]);

            $profileLocation = $adminData[0]['photo_loc'];
            $_SESSION['user_type'] = 'admin';

            $imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
            $fileExtension = strtolower(pathinfo($profileLocation, PATHINFO_EXTENSION));

            if (in_array($fileExtension, $imageExtensions)) {

                $_SESSION['profile_image'] = $profileLocation;
                unset($_SESSION['avatar_icon']);
            } else {

                $_SESSION['avatar_icon'] = $profileLocation;
                unset($_SESSION['profile_image']);
            }

        }else if ($proData) {
            $profileLocation = $proData[0]['location'];
            $_SESSION['user_type'] = $proData[0]['user_type'];

            $imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];
            $fileExtension = strtolower(pathinfo($profileLocation, PATHINFO_EXTENSION));

            if (in_array($fileExtension, $imageExtensions)) {

                $_SESSION['profile_image'] = $profileLocation;
                unset($_SESSION['avatar_icon']);
            } else {

                $_SESSION['avatar_icon'] = $profileLocation;
                unset($_SESSION['profile_image']);
            }
        } else {

            $_SESSION['avatar_icon'] = "fas fa-user";
            unset($_SESSION['profile_image']);
        }

        if ($_SESSION['layer'] === 'super_admin' || $_SESSION['layer'] === 'admin' || $_SESSION['layer'] === 'dealer') {
            auditTrail($_SESSION["userid"], $_SESSION["property"]);
            createAuditLog(
                $_SESSION["userid"],
                'Login',
                'audit_trail_login',
                null,
                $_SESSION["email"],
                null,
                null,
                null,
                'Admin App Login',
                'medium',
                'User management'
            );
        }else if ($_SESSION['layer'] === 'sub_dealer' || $_SESSION['layer'] === 'organization admin') {
            auditTrail($_SESSION["userid"], $_SESSION["property"]);
            createAuditLog(
                $_SESSION["userid"],
                'Login',
                'audit_trail_login',
                null,
                $_SESSION["email"],
                null,
                null,
                null,
                'Dealer Admin App Login',
                'medium',
                'User management'
            );
        }else {
            // Log the login action
            auditTrail($_SESSION["userid"], $_SESSION["property"]);
            createAuditLog(
                $_SESSION["userid"],
                'Login',
                'audit_trail_login',
                null,
                $_SESSION["email"],
                $_SESSION["property"],
                null,
                null,
                'Global User App login',
                'medium',
                'User management'
            );
        }
        
        echo json_encode([
            "success" => true,
            "message" => "Login successful",
            "session_id" => session_id(),
            "user" => $_SESSION
        ]);
        exit();
    }
}

function setCookieForLogin($remember){
    if (!empty($remember)) {
        $sessionData = json_encode($_SESSION);
        $encryptedSession = base64_encode($sessionData);
        setcookie('remember_me', $encryptedSession, time() + (30 * 24 * 60 * 60), "/", "", false, true);
    }else {
        setcookie('remember_me', '', time() - 3600, "/", "", false, true);
    }
}

function updateProfile($pdo, $fName, $lName, $mNum, $hNum) {
    if (session_status() === PHP_SESSION_NONE) {
        session_start();
    }
    $userid = $_SESSION['userid'];

    try {
        if ($_SESSION['layer'] === 'super_admin' || $_SESSION['layer'] === 'admin' || $_SESSION['layer'] === 'dealer' || $_SESSION['layer'] === 'organization admin') {
            updateTable('users', 
                [
                    'firstname' => $fName,
                    'lastname' => $lName
                ], 
                'id = :id', 
                ['id' => $userid]
            );
        }else if ($_SESSION['layer'] === 'sub_dealer' || $_SESSION['layer'] === 'organization admin' ) {
            updateTable('dealer_admins', 
                [
                    'firstname' => $fName,
                    'lastname' => $lName
                ], 
                'id = :id', 
                ['id' => $userid]
            );
        }else {
            updateTable('property_users_data', 
                [
                    'firstname' => $fName,
                    'lastname' => $lName,
                    'mobile_number' => $mNum,
                    'home_number' => $hNum
                ], 
                'id = :id', 
                ['id' => $userid]
            );
        }    

        // Update session variables
        $_SESSION["name"] = $fName . " " . $lName;
        $_SESSION["firstname"] = $fName;
        $_SESSION["lastname"] = $lName;
        $_SESSION["mobilenumber"] = formatPhoneNumber($mNum);
        $_SESSION["homenumber"] = formatPhoneNumber($hNum);

        return true; // Indicate success
    } catch (PDOException $e) {
        return false; // Indicate failure
    }

}

function updateMultiPropProfile($userId, $propertyId, $fName, $lName, $mNum, $hNum) {
    try {
        $updateData = [
            'firstname' => $fName,
            'lastname' => $lName,
            'mobile_number' => $mNum,
            'home_number' => $hNum
        ];
    
        $whereClause = 'user_assoc = :userId AND property_id = :propertyId AND status = :status';
        $whereParams = [
            'userId' => $userId,
            'propertyId' => $propertyId,
            'status' => 'Active'
        ];
    
        $updateSuccess = updateTable('multi_prop_users', $updateData, $whereClause, $whereParams);
    
        if ($updateSuccess) {
            $_SESSION["name"] = $fName . " " . $lName;
            $_SESSION["firstname"] = $fName;
            $_SESSION["lastname"] = $lName;
            $_SESSION["mobilenumber"] = formatPhoneNumber($mNum);
            $_SESSION["homenumber"] = formatPhoneNumber($hNum);
            
            echo "User information updated successfully.";
        } else {
            echo "Failed to update user information.";
        }
    } catch (Exception $e) {
        error_log("Error updating multi-property user: " . $e->getMessage());
        echo "An error occurred while updating user information.";
    }
    
}

function formatPhoneNumber($phoneNumber) {
    $formattedPhone = preg_replace('/[^0-9]/', '', $phoneNumber);
    if (strlen($formattedPhone) == 10) {
        return '(' . substr($formattedPhone, 0, 3) . ') ' . substr($formattedPhone, 3, 3) . '-' . substr($formattedPhone, 6, 4);
    }
    return $phoneNumber;
}

function updateProfilePhotoForMultiPropUser($userId, $propertyId, $location) {
    try {
        $updateData = [
            'photo_loc' => $location
        ];
    
        $whereClause = 'user_assoc = :userId AND property_id = :propertyId AND status = :status';
        $whereParams = [
            'userId' => $userId,
            'propertyId' => $propertyId,
            'status' => 'Active'
        ];
    
        $updateSuccess = updateTable('multi_prop_users', $updateData, $whereClause, $whereParams);
    
        if ($updateSuccess) {
            echo "Photo location updated successfully.";
        } else {
            echo "Failed to update photo location.";
        }
    } catch (Exception $e) {
        error_log("Error updating photo location: " . $e->getMessage());
        echo "An error occurred while updating photo location.";
    }
    
}

function deleteProfilePhotoForAdmins($userId, $logo_loc="") {
    // var_dump($_SESSION);
    // exit();
    if (!isset($_SESSION["avatar_icon"])) {
        $avatar = '';
    } else {
        $avatar = $_SESSION["avatar_icon"];
    }

    try {
        $conditions = [
            'user_id' => $userId,
            'deleted_at' => null
        ];
    
        $photo = fetchDataSingle('users_data', $conditions);

        if($logo_loc != ""){
            if ($photo && !empty($photo['logo_loc'])) {
                // If the location is not an icon, delete the physical image file
                $filePath = "../../../../data/profile_images/" . $photo['logo_loc'];
                if (file_exists($filePath)) {
                    unlink($filePath);
                }
            }

            $updateData = [
                'logo_loc' => "",
            ];
        }
        else{
            if ($photo && !empty($photo['photo_loc']) && strpos($photo['photo_loc'], 'fa-') === false) {
                // If the location is not an icon, delete the physical image file
                $filePath = "../../../../data/profile_images/" . $photo['photo_loc'];
                if (file_exists($filePath)) {
                    unlink($filePath);
                }
            }

            $updateData = [
                'photo_loc' => $avatar
            ];
        }
    
        $whereClause = 'user_id = :userId AND deleted_at IS NULL';
        $whereParams = [
            'userId' => $userId
        ];
    
        $updateSuccess = updateTable('users_data', $updateData, $whereClause, $whereParams);
    
        if ($updateSuccess) {
            unset($_SESSION["profile_image"]);
            echo "Photo location cleared successfully.";
        } else {
            echo "Failed to clear photo location.";
        }
    } catch (Exception $e) {
        error_log("Error clearing photo location: " . $e->getMessage());
        echo "An error occurred while clearing photo location.";
    }
    
}

function deleteProfilePhotoForDealerAdmins($userId) {
    // var_dump($_SESSION);
    // exit();
    if (!isset($_SESSION["avatar_icon"])) {
        $avatar = '';
    } else {
        $avatar = $_SESSION["avatar_icon"];
    }

    try {
        $conditions = [
            'user_id' => $userId,
            'user_type' => 'dealer_admins',
            'deleted_at' => null
        ];
    
        $photo = fetchDataSingle('profile_photo', $conditions);

        if ($photo && !empty($photo['location']) && strpos($photo['location'], 'fa-') === false) {

            $filePath = "../../../../data/profile_images/" . $photo['location'];
            if (file_exists($filePath)) {
               $unLink = unlink($filePath);
            }
        }

        $updateData = [
            'location' => $avatar
        ];
    
        $whereClause = 'user_id = :userId AND user_type = :user_type AND deleted_at IS NULL';
        $whereParams = [
            'userId' => $userId,
            'user_type' => 'dealer_admins'
        ];
    
        $updateSuccess = updateTable('profile_photo', $updateData, $whereClause, $whereParams);
    
        if ($updateSuccess) {
            unset($_SESSION["profile_image"]);
            echo "Photo location cleared successfully.";
        } else {
            echo "Failed to clear photo location.";
        }
    } catch (Exception $e) {
        error_log("Error clearing photo location: " . $e->getMessage());
        echo "An error occurred while clearing photo location.";
    }
    
}

function deleteProfilePhotoForMultiPropUser($userId, $propertyId) {
    // var_dump($_SESSION);
    // exit();
    if (!isset($_SESSION["avatar_icon"])) {
        $avatar = '';
    } else {
        $avatar = $_SESSION["avatar_icon"];
    }

    try {
        $conditions = [
            'user_id' => $userId,
            'property_id' => $propertyId,
            'deleted_at' => null
        ];
    
        $photo = fetchDataSingle('profile_photo', $conditions);

        if ($photo && !empty($photo['location']) && strpos($photo['location'], 'fa-') === false) {
            // If the location is not an icon, delete the physical image file
            $filePath = "../../../../data/profile_images/" . $photo['location'];
            if (file_exists($filePath)) {
                unlink($filePath);
            }
        }

        $updateData = [
            'location' => $avatar
        ];
    
        $whereClause = 'user_id = :userId AND property_id = :propertyId AND deleted_at IS NULL';
        $whereParams = [
            'userId' => $userId,
            'propertyId' => $propertyId,
        ];
    
        $updateSuccess = updateTable('profile_photo', $updateData, $whereClause, $whereParams);
    
        if ($updateSuccess) {
            unset($_SESSION["profile_image"]);
            echo "Photo location cleared successfully.";
        } else {
            echo "Failed to clear photo location.";
        }
    } catch (Exception $e) {
        error_log("Error clearing photo location: " . $e->getMessage());
        echo "An error occurred while clearing photo location.";
    }
    
}

function deleteProfilePhotoForPropertyUser($userId, $propertyId) {

    if (!isset($_SESSION["avatar_icon"])) {
        $avatar = '';
    } else {
        $avatar = $_SESSION["avatar_icon"];
    }

    try {

        $conditions = [
            'user_id' => $userId,
            'property_id' => $propertyId,
            'deleted_at' => null
        ];
    
        $photo = fetchDataSingle('profile_photo', $conditions);

        if ($photo && !empty($photo['location']) && strpos($photo['location'], 'fa-') === false) {
            // If the location is not an icon, delete the physical image file
            $filePath = "../../../../data/profile_images/" . $photo['location'];
            if (file_exists($filePath)) {
                unlink($filePath);
            }
        }

        $updateData = [
            'location' => $avatar
        ];
    
        $whereClause = 'user_id = :userId AND property_id = :propertyId AND deleted_at IS NULL';
        $whereParams = [
            'userId' => $userId,
            'propertyId' => $propertyId
        ];
    
        $updateSuccess = updateTable('profile_photo', $updateData, $whereClause, $whereParams);
    
        if ($updateSuccess) {
            unset($_SESSION['profile_image']);
            $_SESSION['avatar_icon'] = $avatar;
        } else {
            echo "Failed to update photo location.";
        }

        echo "Profile photo deleted and replaced with default avatar icon.";
    } catch (PDOException $e) {
        error_log("Error deleting profile photo: " . $e->getMessage());
        echo "An error occurred while deleting the profile photo.";
    }
}
// Original
// function newProperty($pdo, $propName, $propAddress, $propCity, $propState, $propZip, $propContact, $propContactPhone, $proOrgId, $propType, $imagePath, $propDemo, $propNotes) {
//     if ($_SESSION['layer'] === 'sub_dealer') {
//         $getDealer = fetchData('dealer_admins', ['id' => $_SESSION['userid']]);
//         $dealerInfo = fetchData('dealer_slots', ['dealer_id' => $getDealer[0]['dealer_assoc']]);
//     }else {
//         $dealerInfo = fetchData('dealer_slots', ['dealer_id' => $_SESSION['userid']]);
//     }
//     if (!$dealerInfo) {
//         $result = 'Not a Dealer';
//         return $result;
//     } else if ($dealerInfo[0]['slots_avail'] > $dealerInfo[0]['slots_used']) {

//         if (!$propDemo) {
//             $propDemo = '2020/01/01';
//         }

//         insertData('properties', [
//             'name' => $propName,
//             'address' => $propAddress,
//             'city' => $propCity,
//             'state' => $propState,
//             'zipcode' => $propZip,
//             'contact' => $propContact,
//             'contact_phone_number' => $propContactPhone,
//             'organization_id' => $proOrgId,
//             'property_type' => $propType,
//             'image_path' => $imagePath,
//             'demo_expiry_date' => $propDemo,
//             'notes' => $propNotes
//         ]);

//         $lastInsertIdNP = getLastInsertId();

//         insertData('property_groups', ['name' => 'Default', 'property_id' => $lastInsertIdNP, 'created_by' => $_SESSION['userid'], 'creator_type' => 'users']);

//         $slotUsed = 1;

//         // Step 1: Fetch the current value of `slots_used`
//         $currentSlotData = fetchData('dealer_slots', ['dealer_id' => $_SESSION['userid']]);
//         $currentSlotsUsed = $currentSlotData[0]['slots_used'] ?? 0; // Fallback to 0 if not found

//         // Step 2: Add the new value to the current value
//         $newSlotsUsed = $currentSlotsUsed + $slotUsed;

//         // Step 3: Update the `slots_used` column
//         if ($_SESSION['layer'] === 'sub_dealer') {
//             updateTable('dealer_slots', ['slots_used' => $newSlotsUsed], 'dealer_id = :dealerid', ['dealerid' => $getDealer[0]['dealer_assoc']]);
//             insertData('dealer_properties', ['dealer_id' => $getDealer[0]['dealer_assoc'], 'property_id' => $lastInsertIdNP]);
//         }else {
//             updateTable('dealer_slots', ['slots_used' => $newSlotsUsed], 'dealer_id = :dealerid', ['dealerid' => $_SESSION['userid']]);
//             insertData('dealer_properties', ['dealer_id' => $_SESSION['userid'], 'property_id' => $lastInsertIdNP]);
//         }

//         // Update Session variable to include new property
//         $properties = getProperty($_SESSION["userid"], $_SESSION["layer"]);  // Custom function to fetch properties
//         $_SESSION["properties"] = $properties;  // Store all properties

//         $org_dealer = fetchDataSingle('organizations', ['id' => $proOrgId]);
//         if(isset($org_dealer['dealer_id']) && !empty($org_dealer['dealer_id'])){
//             create_sub_project($lastInsertIdNP, $propName, $org_dealer['dealer_id'], "new");
//         }

//         return $lastInsertIdNP;
//     } else {
//         $result = 'No Available Slots';
//         return $result;
//     }
// }

function newProperty($pdo, $propName, $propAddress, $propCity, $propState, $propZip, $propContact, $propContactPhone, $proOrgId, $propType, $imagePath, $propDemo, $propNotes, $propreferral="", $propLink="") {
    if ($_SESSION['layer'] === 'sub_dealer') {
        $getDealer = fetchData('dealer_admins', ['id' => $_SESSION['userid']]);
        $dealerInfo = fetchData('dealer_slots', ['dealer_id' => $getDealer[0]['dealer_assoc']]);
        $dealerid = $getDealer[0]['dealer_assoc'];
    } else {
        $dealerInfo = fetchData('dealer_slots', ['dealer_id' => $_SESSION['userid']]);
        $dealerid = $_SESSION['userid'];
    }

    if (!$dealerInfo) {
        return 'Not a Dealer';
    } else if ($dealerInfo[0]['slots_avail'] > $dealerInfo[0]['slots_used']) {
        if (!$propDemo) {
            $propDemo = '2020/01/01';
        }

        insertData('properties', [
            'name' => $propName,
            'address' => $propAddress,
            'city' => $propCity,
            'state' => $propState,
            'zipcode' => $propZip,
            'contact' => $propContact,
            'contact_phone_number' => $propContactPhone,
            'organization_id' => $proOrgId,
            'property_type' => $propType,
            'image_path' => $imagePath,
            'demo_expiry_date' => $propDemo,
            'notes' => $propNotes,
            'property_link' => $propLink
        ]);

        $lastInsertIdNP = getLastInsertId();
        // Aamir this is not correct. There is missing user_id on insert.
        // insertData('referrals', [
        //     'referral_code' => $propreferral,
        //     'property_id' => $lastInsertIdNP,
        // ]);
        createAuditLog($_SESSION["userid"], "Add New Property", "properties", $lastInsertIdNP, $_SESSION["email"]??null, $lastInsertIdNP, null, $propName, "Added new property", "Medium", "Properties");

        insertData('property_groups', [
            'name' => 'Default',
            'property_id' => $lastInsertIdNP,
            'created_by' => $_SESSION['userid'],
            'creator_type' => 'users'
        ]);

        $slotUsed = 1;
        $currentSlotData = fetchData('dealer_slots', ['dealer_id' => $_SESSION['userid']]);
        $currentSlotsUsed = $currentSlotData[0]['slots_used'] ?? 0;
        $newSlotsUsed = $currentSlotsUsed + $slotUsed;

        if ($_SESSION['layer'] === 'sub_dealer') {
            updateTable('dealer_slots', ['slots_used' => $newSlotsUsed], 'dealer_id = :dealerid', ['dealerid' => $getDealer[0]['dealer_assoc']]);
            insertData('dealer_properties', ['dealer_id' => $getDealer[0]['dealer_assoc'], 'property_id' => $lastInsertIdNP]);
        } else {
            updateTable('dealer_slots', ['slots_used' => $newSlotsUsed], 'dealer_id = :dealerid', ['dealerid' => $_SESSION['userid']]);
            insertData('dealer_properties', ['dealer_id' => $_SESSION['userid'], 'property_id' => $lastInsertIdNP]);
        }

        $usersWithOrgAccess = fetchData('dealer_admins_access', ['access_id' => $proOrgId, 'access_type' => 'organization']);
        
        foreach ($usersWithOrgAccess as $user) {
            $userId = $user['dealer_admin_id'];

            $existingAccess = fetchData('dealer_admins_access', [
                'dealer_admin_id' => $userId,
                'access_id' => $lastInsertIdNP,
                'access_type' => 'property'
            ]);

            if (!$existingAccess) {

                insertData('dealer_admins_access', [
                    'dealer_admin_id' => $userId,
                    'access_id' => $lastInsertIdNP,
                    'access_type' => 'property',
                    'assigned_by' => $dealerid
                ]);
            }
        }

        $_SESSION["properties"] = getProperty($_SESSION["userid"], $_SESSION["layer"]);

        // Handle sub-project creation
        $org_dealer = fetchDataSingle('organizations', ['id' => $proOrgId]);
        if (isset($org_dealer['dealer_id']) && !empty($org_dealer['dealer_id'])) {
            create_sub_project($lastInsertIdNP, $propName, $org_dealer['dealer_id'], "new");
        }

        return $lastInsertIdNP;
    } else {
        return 'No Available Slots';
    }
}

function create_sub_project($lastInsertIdNP, $propName, $dealer_id, $type){
    $signalire_setting_id = 1;
    if($type == "update"){
        $get_prop_sg = fetchDataSingle('signalwire_settings', ['user_id' => $lastInsertIdNP, 'is_property' => 1, 'is_active' => 1]);
        if(isset($get_prop_sg['id']) && !empty($get_prop_sg['id'])){
            $updateData = [
                'is_active' => 0,
            ];
            $whereClause = 'id = :id';
            $whereParams = ['id' => $get_prop_sg['id']];
            updateTable('signalwire_settings', $updateData, $whereClause, $whereParams);
        }
    }
    $signawire_setting = fetchDataSingle('signalwire_settings', ['user_id' => $dealer_id, 'is_dealer' => 1, 'is_active' => 1]);
   
    if(isset($signawire_setting['id']) && !empty($signawire_setting['id'])){
        
        // $explode_name = explode(" ", $propName);
        // $propName = $explode_name[0];
        $signalwire_id = $signawire_setting['id'];  
        
        //SignalWire credentials
        $projectId = $signawire_setting['project_id'];
        $spaceUrl = $signawire_setting['space_url'];
        $authToken = $signawire_setting['api_token'];

        if (!preg_match('/^[a-z0-9\-]+\.signalwire\.com$/i', $spaceUrl)) {
            throw new Exception("Invalid SignalWire space URL.");
        }

        // Resolve IP and deny private/internal IP ranges
        $resolvedIp = gethostbyname($spaceUrl);
        $privatePrefixes = ['127.', '10.', '192.168.', '169.254.'];
        foreach ($privatePrefixes as $prefix) {
            if (strpos($resolvedIp, $prefix) === 0) {
                throw new Exception("Resolved IP is a private/internal address.");
            }
        }
        if ($resolvedIp === '::1') {
            throw new Exception("Resolved IP is IPv6 localhost.");
        }

        // The SignalWire API endpoint for creating a sub-account
        $apiUrl = "https://$spaceUrl/api/laml/2010-04-01/Accounts.json";
        // Initialize cURL
        $ch = curl_init();

        // Set cURL options
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);

        // Set headers for authentication and content type
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/x-www-form-urlencoded',
            'Authorization: Basic ' . base64_encode($projectId . ':' . $authToken),
        ]);

        // Set POST fields for creating a sub-account
        $propName = htmlspecialchars(trim($propName), ENT_QUOTES, 'UTF-8');
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([

            'FriendlyName' => $propName . $lastInsertIdNP,
            // Other fields as required by the API
        ]));

        // Execute the request
        $response = curl_exec($ch);
        
        // Check for errors
        if (curl_errno($ch)) {
            throw new Exception('cURL error: ' . curl_error($ch));
        } else {
            // Decode and display the response
            $responseData = json_decode($response, true);
            if (empty($responseData['sid']) || !preg_match('/^[a-zA-Z0-9\-]+$/', $responseData['sid'])) {
                throw new Exception("Invalid SID returned by SignalWire.");
            }
            $sub_sid = $responseData['sid'];
        }
        // Close cURL session
        curl_close($ch);

        $url = "https://$spaceUrl/api/project/tokens";

        // Data for the API request to create a token in the sub-project
        $data = [
            'name' => $propName . $lastInsertIdNP . "token",          // Name of the new token
            'permissions' => ['calling', 'chat', 'fax', 'management', 'messaging', 'numbers', 'pubsub', 'storage', 'tasking', 'video', 'datasphere'], // Define the permissions
            'subproject_id' => $sub_sid  // Replace with your sub-project ID
        ];

        // Initialize cURL
        $ch = curl_init($url);

        // Set cURL options
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); // Convert the data array to JSON
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json',  // Set content type to JSON
        'Accept: application/json',        // Set to accept JSON responses
        ]);
        curl_setopt($ch, CURLOPT_USERPWD, "$projectId:$authToken"); // Use main project credentials for authentication

        // Execute the cURL request
        $response = curl_exec($ch);

        // Handle any cURL errors
        if (curl_errno($ch)) {
            throw new Exception('cURL error: ' . curl_error($ch));
        } else {
            $responsed = json_decode($response);
            $api_key = $responsed->token;
            
        }

        // Close cURL session
        curl_close($ch);
        $explode_name = explode(" ", $propName);
        $new_name = $explode_name[0];
        $random_string = sprintf("%03d", rand(0, 999));
        $sip_name = $new_name . $lastInsertIdNP . $random_string;
        $base_url = base_url();
        $sipUrl = "$base_url/signalwire_call/connect_stream.php";
        if (empty($api_key)) {
            throw new Exception("API key was not returned by SignalWire.");
        }
        $sip = create_sip_domain_app($sub_sid, $spaceUrl, $api_key, $sip_name, $sipUrl);
        $is_sub_project = 1;
        $is_property = 1;
        $is_dealer = 0;

        if(!empty($sip)){
            $tab_name = "signalwire_settings";
            $tab_data = [
                'user_id' => $lastInsertIdNP,
                'is_dealer' => $is_dealer,
                'is_property' => $is_property,
                'project_id' => $sub_sid,
                'space_url' => $spaceUrl,
                'api_token' => $api_key,
                'is_sub_project' => $is_sub_project,
                'sip_url' => $sip,
            ];
            insertData($tab_name, $tab_data);
            $signalire_setting_id = getLastInsertId();
        }
        return $signalire_setting_id;
    }
    else{
        return "no";
    }
    
}

function update_sub_project_name($propId, $newName, $dealer_id, $type){
    $signawire_setting = fetchDataSingle('signalwire_settings', ['user_id' => $dealer_id, 'is_dealer' => 1]);
    $sub_project_credentials = fetchDataSingle('signalwire_settings', ['user_id' => $propId, 'is_property' => 1, 'is_active' => 1]);
    
    if(isset($signawire_setting['id']) && !empty($signawire_setting['id']) && isset($sub_project_credentials['id']) && !empty($sub_project_credentials['id'])){

        $projectId = $signawire_setting['project_id'];
        $spaceUrl = $signawire_setting['space_url'];
        $authToken = $signawire_setting['api_token'];
        // Sub-account (sub-project) SID - This is the account you want to update
        $sub_sid = $sub_project_credentials['project_id'];

        // New friendly name for the sub-project

        $newName = $newName . $propId;

        // SignalWire API endpoint to update the sub-account
        $apiUrl = "https://$spaceUrl/api/laml/2010-04-01/Accounts/$sub_sid.json";
        // Initialize cURL
        $ch = curl_init();

        // Set cURL options
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); // Use POST for updates

        // Set headers for authentication and content type
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/x-www-form-urlencoded',
            'Authorization: Basic ' . base64_encode($projectId . ':' . $authToken),
        ]);

        // Set POST fields for updating the sub-account name
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
            'FriendlyName' => $newName
        ]));

        // Execute the request
        $response = curl_exec($ch);
        curl_close($ch);
        return $response;
        // Close cURL session
        
    }
}

function deleteSgNumber($property_id, $phone_number, $userId){
    $number_data = fetchDataSingle('my_numbers', ['phone_number' => $phone_number]);
    if(isset($number_data['phone_sid'])){
        $cehck_door_assign = fetchDataSingle('gate_doors', ['iiNumber' => $phone_number]);
        if(isset($cehck_door_assign['id']) && !empty($cehck_door_assign['iiNumber']))
        {
            echo "<p class='alert alert-danger'>You can not delete this number because door added with this number</p>";
        }
        else{
            $delete_number = delete_number($number_data, $userId);
            echo $delete_number;    
        }
    }
}

function delete_number($number_data, $userId){
    $phone_number = $number_data['phone_number'];
    $signalwire_setting = getSignalwireCredentials($phone_number);
    if(isset($signalwire_setting['id'])){
        $space_url = $signalwire_setting['space_url'];  
        $project_id = $signalwire_setting['project_id'];  
        $api_token = $signalwire_setting['api_token'];
        
        $phone_sid = $number_data['phone_sid'];
        $curl = curl_init();
        curl_setopt_array($curl, [
            CURLOPT_URL => "https://$space_url/api/laml/2010-04-01/Accounts/$project_id/IncomingPhoneNumbers/$phone_sid.json",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CUSTOMREQUEST => "DELETE",
            CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
            CURLOPT_USERPWD => "$project_id:$api_token",
        ]);

        $response = curl_exec($curl);
        $response_array = json_decode($response, true);

        $error = curl_error($curl);

        curl_close($curl);

        if ($error) {
            return "<p class='alert alert-danger'>cURL Error: " . $error . "<p>";
        } else if(isset($response_array['message'])) {
            $response_array['message'];
                return "<p class='alert alert-danger'>" . $response_array['message'] . "</p>";
        }
        else{
            $property_id = $number_data['property_id'];
            
            $update_data = [
                'deleted_at' => date('Y-m-d H:i:s'),
            ];
            $where = 'id = :id';
            $params = ['id' => $number_data['id']];
            $updateSuccess = updateTable('my_numbers', $update_data, $where, $params);

            createAuditLog($userId, "Delete Number", "my_numbers", $number_data['id'], $_SESSION["email"]??null, $property_id, $number_data['phone_number'], null, "Number Deleted", "High","My ii Numbers");
            
            return "<p class='alert alert-success'>Phone number deleted successfully</p>";
        }
    }
}

function create_sip_domain_app($project_id, $space_url, $auth_token, $sip_name, $sipUrl){

    // SIP domain app data
    $data = [
        "name" => $sip_name,  // The name of your SIP domain app
        "identifier" => $sip_name. "-id",  // Unique identifier for your app
        "call_handler" => "laml_webhooks",  // Use LaML for call handling
        "call_request_url" => $sipUrl,  // Your webhook to handle calls
        "call_request_method" => "POST",
        "encryption" => "optional",  // Enable encryption for calls
        "codecs" => ["PCMU", "PCMA"],  // Allowed codecs
        "ciphers" => ["AEAD_AES_256_GCM_8", "AES_256_CM_HMAC_SHA1_80", "AES_CM_128_HMAC_SHA1_80", "AES_256_CM_HMAC_SHA1_32", "AES_CM_128_HMAC_SHA1_32"]  // Supported ciphers
    ];

    // Initialize cURL session
    $ch = curl_init();

    // SignalWire API endpoint for domain applications
    $url = "https://$space_url/api/relay/rest/domain_applications";

    // Set the options for cURL
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json',
        'Accept: application/json'
    ]);
    curl_setopt($ch, CURLOPT_USERPWD, "$project_id:$auth_token");
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

    // Execute the request
    $response = curl_exec($ch);
    // Check for errors
    if (curl_errno($ch)) {
        echo 'Error:' . curl_error($ch);
    } else {
        // Print the response
        $data = json_decode($response, true);

        // Extract name and domain
        $name = $data['name'];
        $domain = $data['domain'];

        $sip = "sip:" . $name . "@" . $domain . ".dapp.signalwire.com";
        return $sip;
    }

    // Close the cURL session
    curl_close($ch);
}

function performCurlRequest($url, $project_id, $auth_token, $postData = null) {
    
    $ch = curl_init();
    
    // Set common cURL options
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_USERPWD, "$project_id:$auth_token");
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', 'Accept: application/json']);
    
    // If POST data is provided, set POST options
    if ($postData !== null) {
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));
    }
    
    // Execute the request and get the response
    $response = curl_exec($ch);
    
    // Check for errors
    if (curl_errno($ch)) {
        echo 'Error:' . curl_error($ch);
    } else {
        // Decode and print the response
        $result = json_decode($response, true);
        print_r($result);
    }
    
    // Close cURL session
    curl_close($ch);
}

function numberDealerProperties($pdo, $dealer_id){
    $sql = "SELECT p.*, o.id as organization_id FROM organizations o  LEFT JOIN properties p ON o.id = p.organization_id WHERE o.dealer_id = :d_id";
    $params = [':d_id' => $dealer_id];
    $proerties = fetchDataWithJoins($sql, $params);
    return $proerties;
}

function getPurchasedNumbers($pdo, $userId, $userLayer, $property_id){
    try {
        $user_id = $userId;      
        $signawire_settings = fetchDataSingle('signalwire_settings', ['user_id' => $property_id, 'is_property' => 1, 'is_active' => 1]);
        // }
        if(isset($signawire_settings['id'])){
            incomingPhoneNumbers($signawire_settings, $userId, $userLayer, $property_id);
                
                $my_numbers = fetchData('my_numbers', ['status' => 'pending', 'property_id' => $property_id, 'deleted_at' => null]);
                foreach ($my_numbers as $num) {
                    checkNumberStatus($num['phone_number']);
                }
                $sql = "SELECT mn.*, u.firstname, u.lastname, p.name as property_name FROM my_numbers mn LEFT JOIN users u ON mn.dealer_id = u.id LEFT JOIN properties p ON mn.property_id = p.id WHERE mn.property_id = :mnid AND mn.deleted_at IS NULL";
                $params = [':mnid' => $property_id];
                $phone_numbers = fetchDataWithJoins($sql, $params);
            return $phone_numbers;
        }
        else{
            return 0;
        }

    } catch (PDOException $e) {
        // Handle and log any errors
        error_log("Get purchase number error: " . $e->getMessage());
        echo "An unexpected error occurred.";
        return [];
    }
}

function getSignalwireCredentials($number){
    $sql = "SELECT sg.*, fn.phone_sid FROM my_numbers fn LEFT JOIN signalwire_settings sg ON sg.id = fn.signalwire_id WHERE fn.phone_number = :phone_number and sg.is_active = :is_active AND fn.deleted_at IS NULL";
    $params = [':phone_number' => $number, 'is_active' => 1];
    $signalwire_credentials = fetchSingleDataWithJoins($sql, $params);
    return $signalwire_credentials;
}

function call_curl_request($url, $signalwire_setting, $type="", $data=[]){
    $space_url = $signalwire_setting['space_url'];
    $project_id = $signalwire_setting['project_id'];
    $api_token = $signalwire_setting['api_token'];
    $ch = curl_init($url);

    // Set cURL options
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    if($type == "post"){
        curl_setopt($ch, CURLOPT_POST, true);
    }
    if(!empty($data)){
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
    }
    curl_setopt($ch, CURLOPT_USERPWD, "$project_id:$api_token"); // Set the username and password for authentication
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);

    // Execute the cURL request
    $response = curl_exec($ch);
    curl_close($ch);
    return $response;
}

function incomingPhoneNumbers($signalwire_setting, $userId, $userLayer, $property_id){
    if(isset($signalwire_setting['id']) && !empty($signalwire_setting)){
        $signalwire_id = $signalwire_setting['id'];
        $space_url = $signalwire_setting['space_url'];
        $project_id = $signalwire_setting['project_id'];
        $api_token = $signalwire_setting['api_token'];

        $url = "https://$space_url/api/laml/2010-04-01/Accounts/$project_id/IncomingPhoneNumbers.json";
        $response = call_curl_request($url, $signalwire_setting);
        $data = json_decode($response, true);

        if (isset($data['incoming_phone_numbers']) && is_array($data['incoming_phone_numbers'])) {
            foreach ($data['incoming_phone_numbers'] as $number) {
                $number_check = fetchDataSingle('my_numbers', ['phone_number' => $number['phone_number']]);
                if(empty($number_check['id'])){
                    $sql = "SELECT org.dealer_id FROM organizations org LEFT JOIN properties up ON org.id = up.organization_id WHERE up.id = :upid";
                    $params = [':upid' => $property_id];
                    $property_dealer = fetchSingleDataWithJoins($sql, $params);
                    if(isset($property_dealer['dealer_id']) && !empty($property_dealer['dealer_id'])){
                        $dealer_id = $property_dealer['dealer_id'];
                    }
                    else{
                        $dealer_id = NULL;  
                    }
                    $tab_name = "my_numbers";
                    $tab_data = [
                        'signalwire_id' => $signalwire_id,
                        'user_id' => $userId,
                        'dealer_id' => $dealer_id,
                        'phone_number' => $number['phone_number'],
                        'property_id' => $property_id,
                        'phone_sid' => $number['sid'],
                        'voice_url' => $number['voice_url'],
                        'sms_url' => $number['sms_url']
                    ];
                    insertData($tab_name, $tab_data);
                }
            }
        }
    }
}

function checkNumberStatus($number){
    $signalwire_credentials = getSignalwireCredentials($number);
    if(isset($signalwire_credentials['id']) && !empty($signalwire_credentials['id'])){
        $space_url = $signalwire_credentials['space_url'];
        $project_id = $signalwire_credentials['project_id'];
        $api_token = $signalwire_credentials['api_token'];
        $campaignID = '365a282f-0331-4031-9045-d707acbe3178';
        $url = "https://$space_url/api/relay/rest/registry/beta/campaigns/$campaignID/numbers";
        $response = call_curl_request($url, $signalwire_credentials);
        $data = json_decode($response, true);
        foreach ($data['data'] as $item) {
            $phone_number = $item['phone_number']['number'];                    
            $status = $item['state'];
            $update_data = [
                'status' => $status,
            ];
            $where = 'phone_number = :phone_number';
            $params = ['phone_number' => $phone_number];
            $updateSuccess = updateTable('my_numbers', $update_data, $where, $params);
        }
    }
}

// function getAvailableNumbers($property_id, $pdo, $userId, $userLayer, $number_type, $contains="", $in_region="", $area_code="", $number_terms=""){
//     try {
//         $signawire_setting = fetchDataSingle('signalwire_settings', ['user_id' => $property_id, 'is_property' => 1, 'is_active' => 1]);
//         $projectId = "";
//         $spaceUrl = "";
//         $apiToken = "";
//         $signalwire_id = "";
//         if(isset($signawire_setting['id']) && !empty($signawire_setting['id'])){
//             $signalwire_id = $signawire_setting['id'];
//             $projectId = $signawire_setting['project_id'];
//             $spaceUrl = $signawire_setting['space_url'];
//             $apiToken = $signawire_setting['api_token'];

//             $ch = curl_init();

//             // Set the URL
//             $url = "https://$spaceUrl/api/laml/2010-04-01/Accounts/$projectId/AvailablePhoneNumbers/US/$number_type";
            
//             if (!empty($in_region) && ($number_type == 'Local')) {
                
//                 $url .= "?InRegion=$in_region";
//             }
//             if (!empty($area_code) && ($number_type == 'Local')) {
//                 if(!empty($in_region)){
//                     $url .= "&AreaCode=$area_code";
//                 }
//                 else{
//                     $url .= "?AreaCode=$area_code";   
//                 }
//             }
//             if(!empty($number_terms)){
//                 if((!empty($in_region) || !empty($area_code)) && ($number_type == 'Local')){
//                     $url .= "&$contains=$number_terms";
//                 }
//                 else{
//                     $url .= "?$contains=$number_terms";   
//                 }
//             }

//             // Set cURL options
//             curl_setopt($ch, CURLOPT_URL, $url);
//             curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//             curl_setopt($ch, CURLOPT_HTTPHEADER, array(
//                 'Accept: application/json',
//                 'Authorization: Basic ' . base64_encode("$projectId:$apiToken")
//             ));

//             // Execute cURL request
//             $response = curl_exec($ch);

//             // Check for errors
//             if (curl_errno($ch)) {
//                 echo json_encode(['error' => 'cURL error: ' . curl_error($ch)]);
//             } else {
//                 $data = json_decode($response, true);
//                 $phone_numbers = [];
//                 if (isset($data['available_phone_numbers'])) {
//                     // Loop through the available phone numbers
//                     foreach ($data['available_phone_numbers'] as $number) {
//                         $phone_numbers[] = [
//                             'friendly_name' => $number['friendly_name'],
//                             'phone_number' => $number['phone_number'],
//                             'region' => $number['region'],
//                         ];
//                     }
//                     return $phone_numbers;
//                 } else {
//                     echo "No available phone numbers found.";
//                 }
//             }
//             // Close cURL
//             curl_close($ch);
//         }
//     } catch (PDOException $e) {
//         // Handle and log any errors
//         echo "Error: " . $e->getMessage();
//         return [];
//     }
// }

function is_space_url_safe($url) {
    $host = parse_url("https://$url", PHP_URL_HOST);
    $ip = gethostbyname($host);

    if (
        $ip === '127.0.0.1' || $ip === '::1' || $ip === '0.0.0.0' ||
        preg_match('/^10\./', $ip) ||
        preg_match('/^192\.168\./', $ip) ||
        preg_match('/^172\.(1[6-9]|2[0-9]|3[0-1])\./', $ip) ||
        preg_match('/^169\.254\./', $ip)
    ) {
        return false;
    }

    // Optionally match against a known trusted domain
    return preg_match('/^[a-z0-9.-]+\.signalwire\.com$/i', $host);
}

// function getAvailableNumbers($property_id, $pdo, $userId, $userLayer, $number_type, $contains = "", $in_region = "", $area_code = "", $number_terms = "")
// {
//     try {
//         $signawire_setting = fetchDataSingle('signalwire_settings', ['user_id' => $property_id, 'is_property' => 1, 'is_active' => 1]);

//         if (!isset($signawire_setting['id']) || empty($signawire_setting['id'])) {
//             return [];
//         }
//         if(isset($signawire_setting['id']) && !empty($signawire_setting['id'])){
//             $projectId = $signawire_setting['project_id'];
//             $spaceUrl = $signawire_setting['space_url'];
//             $apiToken = $signawire_setting['api_token'];
//             if (!is_space_url_safe($spaceUrl)) {
//                 error_log("Blocked unsafe space URL: $spaceUrl");
//                 return [];
//             }

//             // 1. Whitelist allowed number types
//             $allowed_types = ['Local', 'TollFree'];
//             if (!in_array($number_type, $allowed_types)) {
//                 return [];
//             }

//             // 2. Whitelist allowed search fields
//             $allowed_contains = ['Contains', 'FriendlyName'];
//             if (!in_array($contains, $allowed_contains)) {
//                 $contains = '';
//             }

//             // 3. Sanitize inputs
//             $in_region = preg_replace('/[^A-Za-z ]/', '', $in_region);
//             $area_code = preg_replace('/\D/', '', $area_code);
//             $number_terms = preg_replace('/\D/', '', $number_terms);

//             // 4. Build base URL and query params
//             $url = "https://$spaceUrl/api/laml/2010-04-01/Accounts/$projectId/AvailablePhoneNumbers/US/$number_type";
//             $queryParams = [];

//             if (!empty($in_region) && $number_type === 'Local') {
//                 $queryParams['InRegion'] = $in_region;
//             }

//             if (!empty($area_code) && $number_type === 'Local') {
//                 $queryParams['AreaCode'] = $area_code;
//             }

//             if (!empty($number_terms) && !empty($contains)) {
//                 $queryParams[$contains] = $number_terms;
//             }

//             if (!empty($queryParams)) {
//                 $url .= '?' . http_build_query($queryParams);
//             }

//             // 5. Execute cURL request
//             $ch = curl_init();
//             curl_setopt($ch, CURLOPT_URL, $url);
//             curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//             curl_setopt($ch, CURLOPT_HTTPHEADER, [
//                 'Accept: application/json',
//                 'Authorization: Basic ' . base64_encode("$projectId:$apiToken")
//             ]);

//             $response = curl_exec($ch);

//             if (curl_errno($ch)) {
//                 error_log('cURL error in getAvailableNumbers: ' . curl_error($ch));
//                 curl_close($ch);
//                 return [];
//             }

//             curl_close($ch);

//             $data = json_decode($response, true);
//             $phone_numbers = [];

//             if (isset($data['available_phone_numbers'])) {
//                 foreach ($data['available_phone_numbers'] as $number) {
//                     $phone_numbers[] = [
//                         'friendly_name' => htmlspecialchars($number['friendly_name'], ENT_QUOTES, 'UTF-8'),
//                         'phone_number' => htmlspecialchars($number['phone_number'], ENT_QUOTES, 'UTF-8'),
//                         'region' => htmlspecialchars($number['region'], ENT_QUOTES, 'UTF-8'),
//                     ];
//                 }
//             }

//             return $phone_numbers;    
//         }
//         else{
//             return [];       
//         }

        
//     } catch (PDOException $e) {
//         error_log('Database error in getAvailableNumbers: ' . $e->getMessage());
//         return [];
//     }
// }

function getAvailableNumbers($property_id, $pdo, $userId, $userLayer, $number_type, $contains = "", $in_region = "", $area_code = "", $number_terms = "")
{
    try {
        $signawire_setting = fetchDataSingle('signalwire_settings', ['user_id' => $property_id, 'is_property' => 1, 'is_active' => 1]);

        if (empty($signawire_setting['id'])) {
            return [];
        }

        $projectId = $signawire_setting['project_id'];
        $spaceUrl  = $signawire_setting['space_url'];
        $apiToken  = $signawire_setting['api_token'];

        if (!is_space_url_safe($spaceUrl)) {
            error_log("Blocked unsafe space URL: $spaceUrl");
            return [];
        }

        // 1) Whitelist number type
        $allowed_types = ['Local', 'TollFree'];
        if (!in_array($number_type, $allowed_types, true)) {
            return [];
        }

        // 2) Whitelist search field and normalize
        $allowed_contains = ['Contains', 'FriendlyName'];
        if (!in_array($contains, $allowed_contains, true)) {
            $contains = '';
        }
        // SignalWire docs: "Contains" supports [0-9a-zA-Z]; map FriendlyName -> Contains
        if ($contains === 'FriendlyName') {
            $contains = 'Contains';
        }

        // 3) Sanitize inputs
        $in_region   = preg_replace('/[^A-Za-z ]/', '', $in_region);
        $area_code   = preg_replace('/\D/', '', $area_code);

        // For Contains, keep letters and digits (docs allow [0-9a-zA-Z])
        if ($contains === 'Contains') {
            $number_terms = preg_replace('/[^A-Za-z0-9]/', '', $number_terms);
        } else {
            $number_terms = '';
        }

        // 4) Build URL + query
        $url         = "https://$spaceUrl/api/laml/2010-04-01/Accounts/$projectId/AvailablePhoneNumbers/US/$number_type";
        $queryParams = [];

        if (!empty($in_region) && $number_type === 'Local') {
            $queryParams['InRegion'] = $in_region;
        }
        if (!empty($area_code) && $number_type === 'Local') {
            $queryParams['AreaCode'] = $area_code;
        }
        if (!empty($number_terms) && !empty($contains)) {
            $queryParams[$contains] = $number_terms; // Contains with letters/digits OK
        }

        if (!empty($queryParams)) {
            $url .= '?' . http_build_query($queryParams);
        }

        // 5) cURL call
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Accept: application/json',
            'Authorization: Basic ' . base64_encode("$projectId:$apiToken")
        ]);
        $response = curl_exec($ch);

        if (curl_errno($ch)) {
            error_log('cURL error in getAvailableNumbers: ' . curl_error($ch));
            curl_close($ch);
            return [];
        }
        curl_close($ch);

        $data = json_decode($response, true);
        $phone_numbers = [];

        if (!empty($data['available_phone_numbers'])) {
            foreach ($data['available_phone_numbers'] as $number) {
                $phone_numbers[] = [
                    'friendly_name' => htmlspecialchars($number['friendly_name'] ?? '', ENT_QUOTES, 'UTF-8'),
                    'phone_number'  => htmlspecialchars($number['phone_number'] ?? '', ENT_QUOTES, 'UTF-8'),
                    'region'        => htmlspecialchars($number['region'] ?? '', ENT_QUOTES, 'UTF-8'),
                ];
            }
        }

        return $phone_numbers;
    } catch (PDOException $e) {
        error_log('Database error in getAvailableNumbers: ' . $e->getMessage());
        return [];
    }
}



function transfer_number($phone_number, $number_id, $property_id){
    $yourSpaceUrl = "";
    $originProjectId = "";
    $originApiKey = "";
    $phoneNumberId = "";
    $destinationProjectId = "";
    $number_data = fetchDataSingle('my_numbers', ['id' => $number_id]);
    if(isset($number_data['id'])){
        $assigned_property_id = $number_data['property_id'];
        if(!empty($assigned_property_id) && ($assigned_property_id != 0)){
            $sg_credentials = fetchDataSingle('signalwire_settings', ['user_id' => $assigned_property_id, 'is_property' => 1, 'is_active' => 1]);
            if(isset($sg_credentials['id']) && !empty($sg_credentials['id'])){
                $yourSpaceUrl = $sg_credentials['space_url'];
                $originProjectId = $sg_credentials['project_id'];
                $originApiKey = $sg_credentials['api_token'];
                $phoneNumberId = $number_data['phone_sid'];
            }
        }
    }

    $property_sg_credentials = fetchDataSingle('signalwire_settings', ['user_id' => $property_id, 'is_property' => 1, 'is_active' => 1]);
    if(isset($property_sg_credentials['id']) && !empty($property_sg_credentials['id'])){
        $destinationProjectId = $property_sg_credentials['project_id'];
    }

    if(!empty($originProjectId) && !empty($originApiKey) && !empty($phoneNumberId) && !empty($destinationProjectId)){
        $apiUrl = "https://$yourSpaceUrl/api/laml/2010-04-01/Accounts/$originProjectId/IncomingPhoneNumbers/$phoneNumberId"; 

        // Initialize cURL session 
        $ch = curl_init($apiUrl); 

        // Set cURL options 
        curl_setopt_array($ch, [ 
            CURLOPT_RETURNTRANSFER => true, // Return the response as a string 
            CURLOPT_CUSTOMREQUEST => "POST", // Set the request method to POST 
            CURLOPT_POSTFIELDS => http_build_query([ 
                'AccountSid' => $destinationProjectId, // Send the destination project ID 
            ]), 
            CURLOPT_USERPWD => "$originProjectId:$originApiKey", // Set Basic Authentication 
        ]); 

        $response = curl_exec($ch);  
        if (curl_errno($ch)) { 
            echo 'cURL error: ' . curl_error($ch); 
        } else { 
            echo $response; 
        }  
        curl_close($ch); 
    }
    
}
function assignDealerProject($pdo, $userId, $layer, $project_id, $space_url, $api_token, $dealer_id, $number_limit){
    $is_dealer = 1;
    $credentials_check = fetchDataSingle('signalwire_settings', ['user_id' => $dealer_id, 'is_dealer' => 1, 'is_active' => 1]);

    if(empty($credentials_check['id'])){
        $tab_name = "signalwire_settings";
        $tab_data = [
            'user_id' => $dealer_id,
            'is_dealer' => $is_dealer,
            'project_id' => $project_id,
            'space_url' => $space_url,
            'api_token' => $api_token,
            'dealer_purchase_number_limit' => $number_limit,
        ];
        insertData($tab_name, $tab_data);
        $sg_id = getLastInsertId();
        createAuditLog($userId, "Added Dealer Voip Setting", "voip_settings", $sg_id, $_SESSION["email"]??null, null, null, $sg_id, "Voip Settings", "high","Dealer set up voip settings");
        return "Credentials added successfully";
    }
    else{
        $update_data = [
            'project_id' => $project_id,
            'space_url' => $space_url,
            'api_token' => $api_token,
            'dealer_purchase_number_limit' => $number_limit,
        ];
        $where = 'id = :id';
        $params = ['id' => $credentials_check['id']];
        
        $updateSuccess = updateTable('signalwire_settings', $update_data, $where, $params);
        if($project_id != $credentials_check['project_id']){
            createAuditLog($userId, "Update Dealer Voip Project ID", "voip_settings", $credentials_check['id'], $_SESSION["email"]??null, null, $credentials_check['project_id'], $project_id, "Voip Settings", "hingh","Updated dealer voip project id");
        }
        if($space_url != $credentials_check['space_url']){
            createAuditLog($userId, "Update Dealer Voip Space URL", "voip_settings", $credentials_check['id'], $_SESSION["email"]??null, null, $credentials_check['space_url'], $space_url, "Voip Settings", "hingh","Updated dealer voip space url");
        }
        if($api_token != $credentials_check['api_token']){
            createAuditLog($userId, "Update Dealer Voip API Token", "voip_settings", $credentials_check['id'], $_SESSION["email"]??null, null, $credentials_check['api_token'], $api_token, "Voip Settings", "hingh","Updated dealer voip api token");
        }
        if($number_limit != $credentials_check['dealer_purchase_number_limit']){
            createAuditLog($userId, "Update Dealer Voip Number Limit", "voip_settings", $credentials_check['id'], $_SESSION["email"]??null, null, $credentials_check['dealer_purchase_number_limit'], $number_limit, "Voip Settings", "hingh","Updated dealer voip number limit");
        }
        return "Credentials updated successfully";
    }
}

function assignDelaerNumber($pdo, $userId, $phone_number, $dealer_id, $number_id, $property_id){
    // Escape output to prevent XSS
    $safe_phone = htmlspecialchars($phone_number, ENT_QUOTES, 'UTF-8');

    $signawire_setting = fetchDataSingle('signalwire_settings', [
        'user_id' => $dealer_id,
        'is_dealer' => 1,
        'is_active' => 1
    ]);
    $is_limit = 1;

    if(isset($signawire_setting['id']) && !empty($signawire_setting['id']) && !empty($phone_number)){
        $signalwire_id = $signawire_setting['id'];
        $dealer_purchase_number_limit = $signawire_setting['dealer_purchase_number_limit'];
        $my_numbers = fetchData('my_numbers', ['dealer_id' => $dealer_id]);
        $count_numbers = count($my_numbers);

        if ($count_numbers >= $dealer_purchase_number_limit) {
            $is_limit = 0;
        }

        if($is_limit == 1){
            // Temporarily disabled logic
            // $transfer_number = transfer_number($userId, $phone_number, $dealer_id, $number_id, $property_id);
            // $update_data = ['deleted_at' => date('Y-m-d H:i:s')];
            // $where = 'id = :id';
            // $params = ['id' => $number_id];
            // $updateSuccess = updateTable('my_numbers', $update_data, $where, $params);
            // if($updateSuccess){
            //     echo "<h4 class='alert alert-success'>Phone number assigned successfully : " . $safe_phone . "</h4>";
            // } else {
            //     echo "<h4 class='alert alert-success'>Phone number unassigned : " . $safe_phone . "</h4>";   
            // }

            echo "<h4 class='alert alert-danger'>There is a technical issue transferring the number. We are resolving it.</h4>";
        } else {
            echo "<h4 class='alert alert-danger'>You have reached the maximum number limit.</h4>";
        }
    } else {
        if (!empty($phone_number)) {
            $sql = "UPDATE my_numbers SET dealer_id = ? WHERE phone_number = ?";
            $stmt = $pdo->prepare($sql);
            $stmt->execute([$dealer_id, $phone_number]);

            echo "<h4 class='alert alert-success'>Phone number unassigned: " . $safe_phone . "</h4>";
        } else {
            echo "<h4 class='alert alert-danger'>Invalid phone number.</h4>";
        }
    }
}


// function assignDelaerNumber($pdo, $userId, $phone_number, $dealer_id, $number_id, $property_id){
//     // Escape output to prevent XSS
//     $safe_phone = htmlspecialchars($phone_number, ENT_QUOTES, 'UTF-8');

//     $signawire_setting = fetchDataSingle('signalwire_settings', [
//         'user_id' => $dealer_id,
//         'is_dealer' => 1,
//         'is_active' => 1
//     ]);
//     $is_limit = 1;

//     if(isset($signawire_setting['id']) && !empty($signawire_setting['id']) && !empty($phone_number)){
//         $signalwire_id = $signawire_setting['id'];
//         $dealer_purchase_number_limit = $signawire_setting['dealer_purchase_number_limit'];
//         $my_numbers = fetchData('my_numbers', ['dealer_id' => $dealer_id]);
//         $count_numbers = count($my_numbers);

//         if ($count_numbers >= $dealer_purchase_number_limit) {
//             $is_limit = 0;
//         }

//         if($is_limit == 1){
//             // Temporarily disabled logic
//             // $transfer_number = transfer_number($userId, $phone_number, $dealer_id, $number_id, $property_id);
//             // $update_data = ['deleted_at' => date('Y-m-d H:i:s')];
//             // $where = 'id = :id';
//             // $params = ['id' => $number_id];
//             // $updateSuccess = updateTable('my_numbers', $update_data, $where, $params);
//             // if($updateSuccess){
//             //     echo "<h4 class='alert alert-success'>Phone number assigned successfully : " . $safe_phone . "</h4>";
//             // } else {
//             //     echo "<h4 class='alert alert-success'>Phone number unassigned : " . $safe_phone . "</h4>";   
//             // }

//             echo "<h4 class='alert alert-danger'>There is a technical issue transferring the number. We are resolving it.</h4>";
//         } else {
//             echo "<h4 class='alert alert-danger'>You have reached the maximum number limit.</h4>";
//         }
//     } else {
//         if (!empty($phone_number)) {
//             $sql = "UPDATE my_numbers SET dealer_id = ? WHERE phone_number = ?";
//             $stmt = $pdo->prepare($sql);
//             $stmt->execute([$dealer_id, $phone_number]);

//             echo "<h4 class='alert alert-success'>Phone number unassigned: " . $safe_phone . "</h4>";
//         } else {
//             echo "<h4 class='alert alert-danger'>Invalid phone number.</h4>";
//         }
//     }
// }


function getMyNumbers($pdo, $userId, $userLayer, $property_id){
    $my_numbers = fetchData('my_numbers', ['property_id' => $property_id, 'deleted_at' => null]);
    return $my_numbers;
}

function getMyCallFlow($pdo, $userId, $userLayer, $property_id){
    $my_call_flow = fetchDataSingle('my_call_flow', ['property_id' => $property_id]);
    
    if(isset($my_call_flow['id']) && !empty($my_call_flow['id'])){
        // if(!empty($my_call_flow['first_number'])){
        //     $first_number = getCallPropNumbers($my_call_flow['first_number']);
        //     if($first_number != 1){
        //         updateCallnumber($my_call_flow['id'], "first_number");
        //     }
        // }
        // if(!empty($my_call_flow['second_number'])){
        //     $second_number = getCallPropNumbers($my_call_flow['second_number']);
        //     if($first_number != 1){
        //         updateCallnumber($my_call_flow['id'], "second_number");
        //     }
        // }
        // if(!empty($my_call_flow['third_number'])){
        //     $third_number = getCallPropNumbers($my_call_flow['third_number']);
        //     if($first_number != 1){
        //         updateCallnumber($my_call_flow['id'], "third_number");
        //     }
        // }

        return $my_call_flow;
    }
    else{
        return 0;
    }
}

function updateCallnumber($call_flow_id, $field_name){
    $update_data = [
        $field_name => NULL,
    ];
    $where = 'id = :id';
    $params = ['id' => $call_flow_id];
    $updateSuccess = updateTable('my_call_flow', $update_data, $where, $params);
}

function getCallPropNumbers($number){
    $mobile_data = fetchDataSingle('property_users_data', ['mobile_number' => $number, 'deleted_at' => NULL]);
    if(isset($mobile_data['id']) && !empty($mobile_data['mobile_number'])){
        return 1;
    }
    
    $home_data = fetchDataSingle('property_users_data', ['home_number' => $number, 'deleted_at' => NULL]);
    if(isset($home_data['id']) && !empty($home_data['home_number'])){
        return 1;
    }
    
    $table2_mobile_data = fetchData('multi_prop_users', ['mobile_number' => $number, 'deleted_at' => NULL]);
    if(isset($table2_mobile_data['id']) && !empty($table2_mobile_data['mobile_number'])){
        return 1;
    }

    $table2_home_data = fetchData('multi_prop_users', ['home_number' => $number, 'deleted_at' => NULL]);
    if(isset($table2_home_data['id']) && !empty($table2_home_data['home_number'])){
        return 1;
    }

    return 0;
}

function getPropertyNumbers($pdo, $userId, $userLayer, $property_id){
    $table1_data = fetchData('property_users_data', ['property_id' => $property_id, 'deleted_at' => NULL]);
    $table2_data = fetchData('multi_prop_users', ['property_id' => $property_id, 'deleted_at' => NULL]);
    $merged_data = array_merge($table1_data, $table2_data);
    if(isset($merged_data[0]['id']) && !empty($merged_data[0]['id'])){
        return $merged_data;
    }
    else{
        return 0;
    }   
}

function getDealers($pdo, $userId, $userLayer){
    if ($userLayer === 'admin' || $userLayer === 'super_admin') {
        try {
            $dealers = fetchData('users', ['layer' => 'dealer']);
            return $dealers;
        } catch (PDOException $e) {
            error_log("Database error: " . $e->getMessage());
            echo "A database error occurred. Please try again later.";
            return [];
        }
    }else if ($userLayer === 'dealer') {
        try {
            $dealers = fetchData('users', ['layer' => 'dealer', 'id' => $_SESSION['userid']]);
            return $dealers;
        } catch (PDOException $e) {
            error_log("Database error: " . $e->getMessage());
            echo "A database error occurred. Please try again later.";
            return [];
        }
    }else {
        return [];
    }
}

function purchaseNumber($pdo, $userId, $userLayer, $number, $property_id, $number_type){
    try {

        $signawire_setting = fetchDataSingle('signalwire_settings', ['user_id' => $property_id, 'is_property' => 1, 'is_active' => 1]);
        $projectId = "";
        $spaceUrl = "";
        $apiToken = "";
        $signalwire_id = "";
        $is_limit = 1;
        if(isset($signawire_setting['id']) && !empty($signawire_setting['id'])){
            $signalwire_id = $signawire_setting['id'];
            $projectId = $signawire_setting['project_id'];
            $spaceUrl = $signawire_setting['space_url'];
            $apiToken = $signawire_setting['api_token'];
            
            $sql = "SELECT org.dealer_id FROM organizations org LEFT JOIN properties up ON org.id = up.organization_id WHERE up.id = :upid";
            $params = [':upid' => $property_id];
            $property_dealer = fetchSingleDataWithJoins($sql, $params);
            $dealer_id = $property_dealer['dealer_id'];
            if($userLayer == 'dealer'){
                $dealer_data = fetchDataSingle('signalwire_settings', ['user_id' => $dealer_id, 'is_dealer' => 1, 'is_active' => 1]);
                $my_numbers = fetchData('my_numbers', ['dealer_id' => $userId, 'deleted_at' => null]);
                $dealer_purchase_number_limit = $dealer_data['dealer_purchase_number_limit'];
                $count_numbers = count($my_numbers);
                if ($count_numbers >= $dealer_purchase_number_limit) {
                    $is_limit = 0;
                }   
            }

            if($is_limit == 1){
                $url = "https://$spaceUrl/api/laml/2010-04-01/Accounts/$projectId/IncomingPhoneNumbers.json";

                // Prepare the data to send in the request
                $data = [
                    'PhoneNumber' => $number, // The specific phone number you want to buy
                ];
                // Initialize cURL
                $ch = curl_init($url);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
                curl_setopt($ch, CURLOPT_USERPWD, "$projectId:$apiToken");

                // Execute the request
                $response = curl_exec($ch);
                curl_close($ch);

                // Handle the response
                if ($response === false) {
                    echo "Error: " . curl_error($ch);
                } else {
                    $responseData = json_decode($response, true);
                    if (isset($responseData['sid'])) {
                        $sid = $responseData['sid'];
                        
                        $tab_name = "my_numbers";
                        $tab_data = [
                            'signalwire_id' => $signalwire_id,
                            'user_id' => $userId,
                            'dealer_id' => $dealer_id,
                            'property_id' => $property_id,
                            'phone_number' => $responseData['phone_number'],
                            'phone_sid' => $responseData['sid'],
                            'number_type' => $number_type,
                        ];
                        insertData($tab_name, $tab_data);
                        $number_id = getLastInsertId();
                        createAuditLog($userId, "Buy Number", "my_numbers", $number_id, $_SESSION["email"]??null, $property_id, null, $responseData['phone_number'], "Buy Number", "Medium","My ii Numbers");
                        
                        // Campaign ID
                        $campaign_id = '365a282f-0331-4031-9045-d707acbe3178';         // Replace with your actual campaign ID

                        // Phone numbers to add to the campaign
                        $phone_numbers = [
                            $responseData['phone_number']
                        ];

                        // API endpoint
                        $url_cmp = "https://$spaceUrl/api/relay/rest/registry/beta/campaigns/$campaign_id/orders";

                        // Data to send (JSON format)
                        $data_cmp = json_encode([
                            'phone_numbers' => $phone_numbers
                        ]);
                        $ch = curl_init();
                        // Set the cURL options
                        curl_setopt($ch, CURLOPT_URL, $url_cmp);
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                        curl_setopt($ch, CURLOPT_POST, 1);
                        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_cmp);
                        curl_setopt($ch, CURLOPT_USERPWD, "$projectId:$apiToken");
                        curl_setopt($ch, CURLOPT_HTTPHEADER, [
                            'Content-Type: application/json',
                            'Accept: application/json'
                        ]);

                        // Execute the request and get the response
                        $response = curl_exec($ch);

                        // Check for errors
                        if (curl_errno($ch)) {
                            echo 'Error:' . htmlspecialchars(curl_error($ch), ENT_QUOTES, 'UTF-8');
                        } else {
                            // Decode JSON response and print
                            $result = json_decode($response, true);
                        }

                        // Close cURL session
                        curl_close($ch);

                        applyUrl($sid);

                        echo "<h4 class = 'alert alert-success'>Phone number purchased successfully: " . htmlspecialchars($responseData['phone_number'], ENT_QUOTES, 'UTF-8') . "</h4>";
                    } else {
                        echo "<h4 class = 'alert alert-danger'>Error purchasing phone number: " . htmlspecialchars($response, ENT_QUOTES, 'UTF-8') . "</h4>";
                    }
                }
            }
            else{
                echo "<h4 class = 'alert alert-danger'>You have reached maximum buy number limit.</h4>";
            }

            // echo "Phone number purchased successfully:";
        }
    } catch (PDOException $e) {
            // Handle and log any errors
            error_log("Purchase number exception error: " . $e->getMessage());
            echo "An unexpected error occurred.";
            return [];
    }
}

function applyUrl($sid, $type=""){
    try {
        if (!preg_match('/^[a-zA-Z0-9\-]{10,100}$/', $sid)) {
            throw new Exception("Invalid SID.");
        }

        $number_data = fetchDataSingle('my_numbers', ['phone_sid' => $sid, 'deleted_at' => null]);
        if(isset($number_data['id']) && !empty($number_data['id'])){
            $signalwire_credentials = getSignalwireCredentials($number_data['phone_number']);

            if(!empty($signalwire_credentials['id'])){
                $projectId = $signalwire_credentials['project_id'];
                $apiToken = $signalwire_credentials['api_token'];
                $spaceUrl = $signalwire_credentials['space_url'];
                if (!preg_match('/^[a-z0-9-]+\.signalwire\.com$/', $spaceUrl)) {
                    throw new Exception("Invalid SignalWire space URL.");
                }
                $base_url = base_url();
                $stream_data = fetchDataSingle('stream_url');
                $smsUrl = "$base_url/signalwire_call/inbound_sms.php"; // URL to handle incoming SMS
                if(isset($stream_data['id']) && !empty($stream_data['stream_url'])){
                    $smsUrl = $stream_data['stream_url'] . "/api/handle_incoming_sms";
                }
                $voiceUrl = "$base_url/signalwire_call/inbound_call.php"; // URL to handle call staus
                $StatusCallbackUrl = "$base_url/signalwire_call/call_back_status.php"; // URL to handle change call status
                $url = "https://$spaceUrl/api/laml/2010-04-01/Accounts/$projectId/IncomingPhoneNumbers/$sid.json";
                // Initialize cURL session
                $ch = curl_init();

                // Set cURL options
                curl_setopt($ch, CURLOPT_URL, $url);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($ch, CURLOPT_USERPWD, "$projectId:$apiToken");  // Authentication
                curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
                    'SmsUrl' => $smsUrl,
                    'VoiceUrl' => $voiceUrl,
                    'StatusCallback' => $StatusCallbackUrl,
                    'StatusCallbackMethod' => "POST"
                ]));

                // Execute the cURL request and get the response
                $response = curl_exec($ch);
                if (curl_errno($ch)) {
                    echo 'Error:' . curl_error($ch);
                } else {
                    // Decode the response
                    $responseData = json_decode($response, true);
                    if (isset($responseData['sid'])) {

                        $update_data = [
                            'voice_url' => $voiceUrl,
                            'sms_url' => $smsUrl,
                            'status_call_back_url' => $StatusCallbackUrl,
                        ];
                        $where = 'id = :id';
                        $params = ['id' => $number_data['id']];
                        $updateSuccess = updateTable('my_numbers', $update_data, $where, $params);

                        if($type == "new"){
                            if($voiceUrl != $number_data['voice_url']){
                                createAuditLog($_SESSION["userid"], "Change voice URL", "my_numbers", $number_data['id'], $_SESSION["email"]??null, $number_data['property_id'], $number_data['voice_url'], $voiceUrl, "Apply URL", "high","My ii Number");
                            }
                            if($smsUrl != $number_data['sms_url']){
                                createAuditLog($_SESSION["userid"], "Change SMS URL", "my_numbers", $number_data['id'], $_SESSION["email"]??null, $number_data['property_id'], $number_data['sms_url'], $smsUrl, "Apply URL", "high","My ii numbers");
                            }
                        }
                        return 1;
                    } else {
                        echo "Failed to update phone number. Response: " . htmlspecialchars($response, ENT_QUOTES, 'UTF-8');
                    }
                }
            }
        }
        
        
        
    } catch (PDOException $e) {
        // Handle and log any errors
        error_log("ApplyUrl exception Error: " . $e->getMessage());
        echo "An unexpected error occurred.";
        return [];
    } 
}

function getBaseUrl() {
    $scheme = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http';
    // Get the host (domain name)
    $host = $_SERVER['HTTP_HOST'];
    // Construct the base URL
    $base_url = 'http://' . $host;
    return $base_url;
}

function base_url() {
    // Default to localhost if not set
    $host = $_SERVER['HTTP_HOST'] ?? 'localhost';

    // Remove anything except letters, numbers, dots, and hyphens
    $host = preg_replace('/[^a-zA-Z0-9.\-]/', '', $host);

    // Avoid double dots or malformed domains
    $host = preg_replace('/\.+/', '.', $host);

    // Limit length to prevent abuse
    $host = substr($host, 0, 255);

    // Final validation (optional but safe)
    if (!filter_var("http://$host", FILTER_VALIDATE_URL)) {
        $host = 'localhost';
    }

    // Determine scheme
    $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';

    return "$scheme://$host";
}

function format_number($phone_number) {
    // Remove all non-numeric characters
    $phone_number = preg_replace('/[^0-9]/', '', $phone_number);

    // If the number does not start with 1, add it as the country code
    if (strlen($phone_number) === 10) {
        $phone_number = '1' . $phone_number;
    }

    // Ensure the number is now 11 digits long (1 + 10)
    if (strlen($phone_number) === 11 && substr($phone_number, 0, 1) === '1') {
    }
    else if (strlen($phone_number) === 11 && strpos($phone_number, '0') === 0) {
        $phone_number = '44' . substr($phone_number, 1);
    }
    else if (strlen($phone_number) === 12 && strpos($phone_number, '00') === 0) 
    {
        $phone_number = '44' . substr($phone_number, 2);
    }
    return '+' . $phone_number;
}

function checkLimitNumber($pdo, $userId, $userLayer){
    try {
        if ($userLayer === 'super_admin' || $userLayer === 'admin') {
            $properties = fetchData('properties');
        }else if ($userLayer === 'dealer') {
            // Retrieve organizations assigned to the dealer
            $orgData = fetchData('organizations', ['dealer_id' => $userId]);
            $orgIds = array_column($orgData, 'id');

            if (empty($orgIds)) {
                return [];
            }

            // Create placeholders for the organization IDs
            $placeholders = implode(',', array_fill(0, count($orgIds), '?'));

            // Create a new statement with the organization IDs
            $stmt = $pdo->prepare("SELECT * FROM properties WHERE organization_id IN ($placeholders)");
            $stmt->execute($orgIds);
            $properties = $stmt->fetchAll(PDO::FETCH_ASSOC);
        }else if ($userLayer === "property admin") {
            $properties = fetchData('properties', ['id' => $_SESSION['property']]);
            
        }else if ($userLayer === "user") {

        }

        // Fetch the properties

        return $properties;
    } catch (PDOException $e) {
        // Handle and log any errors
        error_log("ApplyUrl exception Error: " . $e->getMessage());
        echo "An unexpected error occurred.";
        return [];
    }
}

function checkProDetail($pdo, $user_id, $userLayer){
    $signawire_setting = fetchDataSingle('signalwire_settings', ['user_id' => $user_id, 'is_dealer' => 1, 'is_active' => 1]);
    if(isset($signawire_setting['id'])){
        return $signawire_setting;
    }
    else{
        return 0;
    }
}

function checkPropertyDoorHardware($property_id){
    $check_door = fetchDataSingle('gate_doors', ['property_id' => $property_id]);
    if(isset($check_door['id'])){
        $check_hardware = fetchDataSingle('hardware_devices', ['property_id' => $property_id]);
        if(isset($check_hardware['id'])){
            return 1;
        }
        else{
            return 2;
        }
    }
    else{
        return 0;
    }
}

function calculateNumber($pdo, $userId, $userLayer){
    $signawire_setting = fetchDataSingle('signalwire_settings', ['user_id' => $userId, 'is_dealer' => 1, 'is_active' => 1]);
    $is_limit = 1;
    if(isset($signawire_setting['id']) && !empty($signawire_setting['id'])){
        $signalwire_id = $signawire_setting['id'];
        $dealer_purchase_number_limit = $signawire_setting['dealer_purchase_number_limit'];
        $my_numbers = fetchData('my_numbers', ['dealer_id' => $userId, 'deleted_at' => null]);
        $count_numbers = count($my_numbers);

        if ($count_numbers >= $dealer_purchase_number_limit) {
            $is_limit = 0;
        }
    }

    if($is_limit == 0){
        return 0;
    }
    else{
        return "Buy (" . $count_numbers . " of " . $dealer_purchase_number_limit . " Numbers)";
    }
}

// function getProperty($userId, $userLayer) {
//     try {
//         if ($userLayer === 'super_admin' || $userLayer === 'admin') {

//             $stmt = fetchData('properties');

//         } else if ($userLayer === 'dealer') {

//             $organizations = fetchData('organizations', ['dealer_id' => $userId]);

//             if (empty($organizations)) {
//                 return [];
//             }

//             $allProperties = [];

//             foreach ($organizations as $org) {
//                 $properties = fetchData('properties', ['organization_id' => $org['id']]);
//                 $allProperties = array_merge($allProperties, $properties);
//             }

//             $stmt = $allProperties;

//         } else {
//             $stmt = fetchData('properties', ['id' => $_SESSION['property']]);
//         }

//         return $stmt;
//     } catch (PDOException $e) {
//         echo "Error: " . $e->getMessage();
//         return [];
//     }
// }
function getProperty($userId, $userLayer) {

    try {
        global $pdo;

        if ($userLayer === 'super_admin' || $userLayer === 'admin') {

            $properties = fetchData('properties');
            foreach ($properties as &$prop) {

                $voip_setting = fetchDataSingle('signalwire_settings', ['user_id' => $prop['id'], 'is_property' => 1, 'is_active' => 1]);
                if(isset($voip_setting['id']) && !empty($voip_setting['id'])){
                    $prop['check_voip'] = 1;
                }
                else{
                    $prop['check_voip'] = 0;
                }
            }
            return $properties;
        }

        if ($userLayer === 'dealer') {

            $organizations = fetchData('organizations', ['dealer_id' => $userId]);

            if (empty($organizations)) {
                return [];
            }

            $allProperties = [];
            foreach ($organizations as $org) {
                $properties = fetchData('properties', ['organization_id' => $org['id']]);
                foreach ($properties as &$prop) {
                    $voip_setting = fetchDataSingle('signalwire_settings', ['user_id' => $prop['id'], 'is_property' => 1, 'is_active' => 1]);
                    if(isset($voip_setting['id']) && !empty($voip_setting['id'])){
                        $prop['check_voip'] = 1;
                    }
                    else{
                        $prop['check_voip'] = 0;
                    }
                }                
                $allProperties = array_merge($allProperties, $properties);
            }

            return $allProperties;
        }

        if ($userLayer === 'sub_dealer' || $userLayer === 'organization admin') {
            try {

                $accessEntries = fetchData('dealer_admins_access', [
                    'dealer_admin_id' => $userId,
                    'access_type' => 'property'
                ]);
        
                if (!empty($accessEntries)) {
                    $propertyIds = array_column($accessEntries, 'access_id');
        
                    if (!empty($propertyIds)) {

                        $placeholders = [];
                        $params = [];
                        foreach ($propertyIds as $index => $id) {
                            $key = ":id" . $index;
                            $placeholders[] = $key;
                            $params[$key] = $id;
                        }

                        $query = "SELECT * FROM properties WHERE id IN (" . implode(',', $placeholders) . ")";

                        $properties = fetchDataWithJoins($query, $params);

                        return $properties;
                    } else {
                        return [];
                    }
                } else {
                    return [];
                }
            } catch (Exception $e) {
                // error_log("Error fetching allowed properties: " . $e->getMessage());
                return [];
            }
        }
        
        
        

        $primaryPropertyEntries = fetchData('property_users', ['id' => $userId]);
        $primaryProperty = [];
        if (!empty($primaryPropertyEntries)) {
            $primaryPropertyId = $primaryPropertyEntries[0]['property_id'];
            $primaryProperty = fetchData('properties', ['id' => $primaryPropertyId]);
        }

        $multiPropEntries = fetchData('multi_prop_users', ['user_assoc' => $userId, 'status' => 'Active']);
        $multiPropProperties = [];

        if (!empty($multiPropEntries)) {
            $propertyIds = array_column($multiPropEntries, 'property_id');

            if (!empty($propertyIds)) {

                $placeholders = [];
                $params = [];

                foreach ($propertyIds as $index => $id) {
                    $placeholder = ":property_id_$index";
                    $placeholders[] = $placeholder;
                    $params[$placeholder] = $id;
                }

                $sql = "SELECT * FROM properties WHERE id IN (" . implode(', ', $placeholders) . ")";
                $multiPropProperties = fetchDataWithJoins($sql, $params);
            }
        }

        $allProperties = array_merge($primaryProperty, $multiPropProperties);
        $uniqueProperties = [];
        foreach ($allProperties as &$property) {
            $property['check_voip'] = 1;
            $uniqueProperties[$property['id']] = $property;
        }

        return array_values($uniqueProperties);

    } catch (PDOException $e) {
        error_log("Database error: " . $e->getMessage());
        echo "A database error occurred. Please try again later.";
        return [];
    }
}

function updateProperty($pdo, $propId, $propImage, $propName, $propAddress, $propCity, $propState, $propZip, $propContact, $propContactPhone, $proporg, $propNotes, $propLink = null) {
    try {

        if ($proporg === 'View Only') {

            $updateData = [
                'name' => $propName,
                'address' => $propAddress,
                'city' => $propCity,
                'state' => $propState,
                'zipcode' => $propZip,
                'contact' => $propContact,
                'contact_phone_number' => $propContactPhone,
                'notes' => $propNotes,
                'property_link' => $propLink
            ];

        }else {
            $prop_old_organization_dealer = fetchDataSingle('properties', ['id' => $propId]);
            $check_pro = fetchDataSingle('signalwire_settings', ['user_id' => $propId, 'is_property' => 1, 'is_active' => 1]);
            $new_org_dealer = fetchDataSingle('organizations', ['id' => $proporg]);
            $update_name = 0;
            if(isset($check_pro['id']) && !empty($check_pro['id'])){
                if($prop_old_organization_dealer['organization_id'] != $proporg){
                    $old_org_dealer = fetchDataSingle('organizations', ['id' => $prop_old_organization_dealer['organization_id']]);
                    if($new_org_dealer['dealer_id'] != $old_org_dealer['dealer_id']){
                        create_sub_project($propId, $propName, $new_org_dealer['dealer_id'], "update");
                    }
                }
                else if($prop_old_organization_dealer['name'] != $propName){
                    $up_main = update_sub_project_name($propId, $propName, $new_org_dealer['dealer_id'], "update_name");
                }
            }
            else{
                create_sub_project($propId, $propName, $new_org_dealer['dealer_id'], "update");
            }

            $updateData = [
                'name' => $propName,
                'address' => $propAddress,
                'city' => $propCity,
                'state' => $propState,
                'zipcode' => $propZip,
                'contact' => $propContact,
                'contact_phone_number' => $propContactPhone,
                'organization_id' => $proporg,
                'notes' => $propNotes,
                'property_link' => $propLink
            ];
        }

        if ($propImage !== null) {
            $updateData['image_path'] = $propImage;
        }

        $property_data = fetchDataSingle('properties', ['id' => $propId]);

        if($property_data['name'] != $propName){
            createAuditLog($_SESSION["userid"], "Updated Property Name", "properties", $propId, $_SESSION["email"]??null, $propId, $property_data['name'], $propName, "updated property name", "medium", "Properties");
        }
        if($property_data['address'] != $propAddress){
            createAuditLog($_SESSION["userid"], "Updated Property Address", "properties", $propId, $_SESSION["email"]??null, $propId, $property_data['address'], $propAddress, "updated property address", "medium", "Properties");
        }
        if($property_data['city'] != $propCity){
            createAuditLog($_SESSION["userid"], "Updated Property City", "properties", $propId, $_SESSION["email"]??null, $propId, $property_data['city'], $propCity, "updated property city", "medium", "Properties");
        }
        if($property_data['state'] != $propState){
            createAuditLog($_SESSION["userid"], "Updated Property State", "properties", $propId, $_SESSION["email"]??null, $propId, $property_data['state'], $propState, "updated property state", "medium", "Properties");
        }
        if($property_data['zipcode'] != $propZip){
            createAuditLog($_SESSION["userid"], "Updated Property Zipcode", "properties", $propId, $_SESSION["email"]??null, $propId, $property_data['zipcode'], $propZip, "updated property zipcode", "medium", "Properties");
        }
        if($property_data['contact'] != $propContact){
            createAuditLog($_SESSION["userid"], "Updated Property Contact", "properties", $propId, $_SESSION["email"]??null, $propId, $property_data['contact'], $propContact, "updated property contact", "medium", "Properties");
        }
        if($property_data['contact_phone_number'] != $propContactPhone){
            createAuditLog($_SESSION["userid"], "Updated Property Contact Phone Number", "properties", $propId, $_SESSION["email"]??null, $propId, $property_data['contact_phone_number'], $propContactPhone, "updated property contact phone number", "medium", "Properties");
        }
        if($property_data['organization_id'] != $proporg){
            createAuditLog($_SESSION["userid"], "Updated Property organization", "properties", $propId, $_SESSION["email"]??null, $propId, $property_data['organization_id'], $proporg, "updated property organization", "medium", "Properties");
        }
        if($property_data['notes'] != $propNotes){
            createAuditLog($_SESSION["userid"], "Updated Property Notes", "properties", $propId, $_SESSION["email"]??null, $propId, $property_data['notes'], $propNotes, "updated property notes", "medium", "Properties");
        }

        $whereClause = 'id = :id';
        $whereParams = ['id' => $propId];

        return updateTable('properties', $updateData, $whereClause, $whereParams);
    } catch (Exception $e) {
        error_log("Error updating property: " . $e->getMessage());
        return false;
    }
}

function getOrg($pdo, $userId, $userLayer) {
    try {
        if ($userLayer === 'super_admin' || $userLayer === 'admin') {
            $organizations = fetchData('organizations');
        }else if ($userLayer === 'sub_dealer' || $userLayer === 'organization admin') {
            $assocDealer = fetchData('dealer_admins', ['id' => $userId]);
            $organizations = fetchData('organizations', ['dealer_id' => $assocDealer[0]['dealer_assoc']]);
        } else {
            $organizations = fetchData('organizations', ['dealer_id' => $userId]);
        }
        return $organizations;
    } catch (Exception $e) {
        error_log("Unhandled exception: " . $e->getMessage());
        echo "An error occurred. Please try again later.";
        return [];
    }
}

function updateOrganization($pdo, $orgId, $orgName, $orgAddress, $orgCity, $orgState, $orgZip, $orgContact, $orgContactPhone, $orgdealer) {
    try {
        $org_data = fetchDataSingle('organizations', ['id' => $orgId]);
        $change = 0;
        if($org_data['name'] != $orgName){
            createAuditLog($_SESSION["userid"], "Updated Organization Name", "organizations", $orgId, $_SESSION["email"]??null, null, $org_data['name'], $orgName, "updated organization name", "hIgh", "Organizations");
        }
        if($org_data['address'] != $orgAddress){
            createAuditLog($_SESSION["userid"], "Updated Organization Address", "organizations", $orgId, $_SESSION["email"]??null, null, $org_data['address'], $orgAddress, "updated organization Address", "hIgh", "Organizations");
        }
        if($org_data['city'] != $orgCity){
            createAuditLog($_SESSION["userid"], "Updated Organization City", "organizations", $orgId, $_SESSION["email"]??null, null, $org_data['city'], $orgCity, "updated organization city", "hIgh", "Organizations");
        }
        if($org_data['state'] != $orgState){
            createAuditLog($_SESSION["userid"], "Updated Organization State", "organizations", $orgId, $_SESSION["email"]??null, null, $org_data['state'], $orgState, "updated organization state", "hIgh", "Organizations");
        }
        if($org_data['zipcode'] != $orgZip){
            createAuditLog($_SESSION["userid"], "Updated Organization Zip Code", "organizations", $orgId, $_SESSION["email"]??null, null, $org_data['zipcode'], $orgZip, "updated organization zip code", "hIgh", "Organizations");
        }
        if($org_data['contact'] != $orgContact){
            createAuditLog($_SESSION["userid"], "Updated Organization contact", "organizations", $orgId, $_SESSION["email"]??null, null, $org_data['contact'], $orgContact, "updated organization contact", "hIgh", "Organizations");
        }
        if($org_data['contact_phone_number'] != $orgContactPhone){
            createAuditLog($_SESSION["userid"], "Update Organization Phone Number", "organizations", $orgId, $_SESSION["email"]??null, null, $org_data['contact_phone_number'], $orgContactPhone, "updated organization phone number", "hIgh", "Organizations");
        }
        if($org_data['dealer_id'] != $orgdealer){
            createAuditLog($_SESSION["userid"], "Updated Organization Dealer", "organizations", $orgId, $_SESSION["email"]??null, null, $org_data['dealer_id'], $orgdealer, "updated organization dealer", "hIgh", "Organizations");
        }
        $updateData = [
            'name' => $orgName,
            'address' => $orgAddress,
            'city' => $orgCity,
            'state' => $orgState,
            'zipcode' => $orgZip,
            'contact' => $orgContact,
            'contact_phone_number' => $orgContactPhone,
            'dealer_id' => $orgdealer
        ];
    
        $whereClause = 'id = :id';
        $whereParams = ['id' => $orgId];
        
        return updateTable('organizations', $updateData, $whereClause, $whereParams);
    } catch (Exception $e) {
        error_log("Error updating organization: " . $e->getMessage());
        return false;
    }
    
}


function newOrganization($pdo, $orgName, $orgAddress, $orgCity, $orgState, $orgZip, $orgContact, $orgContactPhone, $dealerId) {
    try {
        insertData('organizations', [
            'name' => $orgName,
            'address' => $orgAddress,
            'city' => $orgCity,
            'state' => $orgState,
            'zipcode' => $orgZip,
            'contact' => $orgContact,
            'contact_phone_number' => $orgContactPhone,
            'dealer_id' => $dealerId
        ]);
        $org_id = getLastInsertId();
        createAuditLog($_SESSION["userid"], "Add New Organization", "organizations", $org_id, $_SESSION["email"]??null, null, null, $orgName, "Added new organization", "hIgh", "Organizations");
        return true;
    } catch (Exception $e) {
        error_log("Error: " . $e->getMessage());
        echo "An error occurred. Please try again later.";
        return false;
    }
}

function getDealerSlots($pdo) {
    try {
        $sql = "SELECT ds.dealer_id, u.firstname, u.lastname, ds.slots_avail, ds.slots_used 
                FROM dealer_slots ds 
                JOIN users u ON ds.dealer_id = u.id 
                WHERE u.layer = :layer";
        
        $dealerSlots = fetchDataWithJoins($sql, ['layer' => 'dealer']);
        return $dealerSlots;
    } catch (Exception $e) {
        error_log("Unhandled exception: " . $e->getMessage());
        echo "An error occurred. Please try again later.";
        return [];
    }
}

function addDealerSlots($pdo, $dealerId, $slots) {
    try {
        $currentSlotData = fetchDataSingle('dealer_slots', ['dealer_id' => $dealerId]);
        $currentSlotsAvail = $currentSlotData['slots_avail'] ?? 0;
    
        $newSlotsAvail = $currentSlotsAvail + $slots;
    
        updateTable('dealer_slots', 
            ['slots_avail' => $newSlotsAvail], 
            'dealer_id = :dealer_id', 
            ['dealer_id' => $dealerId]
        );
        createAuditLog($_SESSION["userid"], "Update dealer slots", "dealer_slots", $currentSlotData['id'], $_SESSION["email"]??null, null, $currentSlotsAvail, $newSlotsAvail, "dealer slots updated", "high", "Dealer slots");
    } catch (Exception $e) {
        error_log("Unhandled exception: " . $e->getMessage());
        echo "An unexpected error occurred. Please try again later.";
    }
}

function removeDealerSlots($pdo, $dealerId, $slotsToRemove) {
    try {
        $pdo->beginTransaction();
    
        $result = fetchDataSingle('dealer_slots', ['dealer_id' => $dealerId]);
    
        if (!$result) {
            throw new Exception("Dealer not found.");
        }
    
        $slotsAvail = $result['slots_avail'];
        $slotsUsed = $result['slots_used'];
    
        if ($slotsAvail - $slotsToRemove < $slotsUsed) {
            throw new Exception("Cannot remove slots: not enough available slots.");
        }
    
        $newSlotsAvail = $slotsAvail - $slotsToRemove;
        $updateSuccess = updateTable(
            'dealer_slots',
            ['slots_avail' => $newSlotsAvail],
            'dealer_id = :dealer_id',
            ['dealer_id' => $dealerId]
        );
    
        if ($updateSuccess) {
            $pdo->commit();
            return 'success';
        } else {
            $pdo->rollBack();
            return 'error: failed to remove slots';
        }
    } catch (Exception $e) {
        $pdo->rollBack();
        throw new Exception("Error removing slots: " . $e->getMessage());
    }
}

function getUsedSlots($pdo, $dealerId) {
    try {

        $sql = "
            SELECT COUNT(p.id) as used_slots 
            FROM properties p
            JOIN organizations o ON p.organization_id = o.id
            WHERE o.dealer_id = :dealerId
        ";
    
        $result = fetchSingleDataWithJoins($sql, ['dealerId' => $dealerId]);
        $usedSlots = $result['used_slots'] ?? 0;
        
        return $usedSlots;
    } catch (Exception $e) {
        // log_error("Error in getUsedSlots: " . $e->getMessage());
        return 0; // or handle error appropriately
    }
}

function fetchCustomRolesForProperties($properties) {
    $allRoles = [];
    
    foreach ($properties as $property) {
        $propertyId = $property['id'];

        $roles = fetchData('custom_roles', ['site_id' => $propertyId]);

        $allRoles[$propertyId] = $roles;
    }
    
    return $allRoles;
}

function mergeRoles($mergedArray, $customRoles) {
    
    foreach ($customRoles as $propertyId => $roles) {
        foreach ($roles as $role) {

            $role['is_custom'] = true;
            $role['property_id'] = $propertyId;
            
            $mergedArray[] = $role;
        }
    }
    
    return $mergedArray;
}

function getRoles($pdo, $layer) {
    require '../../include/helper_functions/data_request.php';

    $setroleId = fetchData('roles', ['name' => $layer]);
    $userRoleId = $setroleId[0]['id'];

    // Define which roles each role can see
    $roleVisibility = [
        1 => [1, 2, 3, 4, 5, 6, 7, 8],  // super_admin
        2 => [3, 4, 5, 6, 7, 8],        // admin
        3 => [4, 5, 6, 7, 8],           // dealer
        4 => [5, 6, 7, 8],              // sub_dealer
        5 => [6, 7, 8],                 // organization admin
        6 => [6, 7, 8],                 // property admin
        7 => [6, 7, 8],                 // user
        8 => []                         // visitor
    ];

    // Fetch all default roles
    $roles = fetchData('roles');

    // Fetch all custom roles
    $site_ID = getProperty($_SESSION['userid'], $_SESSION['layer']);

    if (!empty($site_ID)) {
        // Fetch custom roles for each property
        $customRoles = fetchCustomRolesForProperties($site_ID);

        // Filter roles based on the user's role ID
        $filteredRoles = array_filter($roles, function($role) use ($roleVisibility, $userRoleId) {
            return in_array($role['id'], $roleVisibility[$userRoleId]);
        });

        $roleDesc = fetchData('role_desc');

        // Add description with the Role
        $mergedArray = [];

        foreach ($filteredRoles as $filteredRole) {
            foreach ($roleDesc as $roleDescRole) {
                if ($filteredRole['id'] === $roleDescRole['role_id']) {
                    $mergedArray[] = array_merge($filteredRole, $roleDescRole);
                    break;
                }
            }
        }

        // Merge custom roles into the default roles
        $mergedCustom = mergeRoles($mergedArray, $customRoles);

        // echo json_encode(array_values($mergedCustom));
        return array_values($mergedCustom);
        
    } else {
        echo "No properties found.";
    }    
}

function getResources($pdo, $layer) {
    require '../../include/helper_functions/data_request.php';

    $setroleId = fetchData('roles', ['name' => $layer]);
    $userRoleId = $setroleId[0]['id'];

    $roleVisibility = [
        1 => [1, 2, 3, 4, 5, 6, 7, 8],  // super_admin
        2 => [3, 4, 5, 6, 7, 8],        // admin
        3 => [4, 5, 6, 7, 8],           // dealer
        4 => [5, 6, 7, 8],              // sub_dealer
        5 => [6, 7, 8],                 // organization admin
        6 => [6, 7, 8],                 // property admin
        7 => [6, 7, 8],                 // user
        8 => []                         // visitor
               
    ];

    $roles = fetchData('roles');

    $filteredRoles = array_filter($roles, function($role) use ($roleVisibility, $userRoleId) {
        return in_array($role['id'], $roleVisibility[$userRoleId]);
    });

    $roleresources = fetchData('role_resources');
    
    $roleIds = array_column($filteredRoles, 'id');

    $filteredResources = array_filter($roleresources, function($resource) use ($roleIds) {
        return in_array($resource['role_id'], $roleIds);
    });

    $resources = fetchData('resources');

    $resourceMap = [];
    foreach ($resources as $resource) {
        $resourceMap[$resource['id']] = $resource['name'];
    }

    foreach ($filteredRoles as $key => &$role) {
        $role['resources'] = [];
        foreach ($filteredResources as $res) {
            if ($res['role_id'] == $role['id']) {
                $role['resources'][] = [
                    'resource_id' => $res['resource_id'],
                    'resource_name' => $resourceMap[$res['resource_id']],
                    'action_id' => $res['action_id']
                ];
            }
        }
    }
    
    $_SESSION['current_user_permissions'] = $filteredRoles;
    echo json_encode($filteredRoles);
}

function processSingleFile($inputName) {
    $fileTmpPath = $inputName['tmp_name'];
    $fileName = $inputName['name'];
    $fileSize = $inputName['size'];
    $fileType = $inputName['type'];
    $fileNameCmps = explode('.', $fileName);
    $fileExtension = strtolower(end($fileNameCmps));

    // Specify the allowed file extensions
    $allowedExtensions = ['wav', 'mp4'];
    if (in_array($fileExtension, $allowedExtensions)) {
        // Directory where the file will be saved
        $uploadFileDir = "../../../../data/audio_messages/";
        $namefile = $fileNameCmps[0] . bin2hex(random_bytes(16)) . "." . $fileExtension;
        $dest_path = $uploadFileDir . $namefile;

        // Create directory if it doesn't exist
        if (!is_dir($uploadFileDir)) {
            mkdir($uploadFileDir, 0755, true);
        }

        // Move the file to the specified directory
        if (move_uploaded_file($fileTmpPath, $dest_path)) {
            return $namefile;
        } else {
            echo "There was an error moving the uploaded file.";
        }
    } else {
        echo "Upload failed. Allowed file types: " . implode(', ', $allowedExtensions);
    }
}

function delete_audio_file($file_name){
    $allowedDir = "../../../../data/audio_messages/";
    $realPath = $allowedDir . $file_name;
    unlink($realPath);
}

function call_log_audio_file($old_audio_file, $new_audio_file, $my_call_flow_id, $more_info, $text_to_speech_message, $text_to_speech_more_info){
    if(!empty($old_audio_file) && !empty($new_audio_file)){
        createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_id, $_SESSION["email"]??null, $_SESSION['property'], $old_audio_file, $new_audio_file, $more_info, "Medium", "Call Flow");
    }
    else if(!empty($text_to_speech_message) && !empty($new_audio_file)){
        createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_id, $_SESSION["email"]??null, $_SESSION['property'], $text_to_speech_message, $new_audio_file, $text_to_speech_more_info, "Medium", "Call Flow");   
    }
}

function uploadCallFlowData($pdo, $userId, $property_id, $userLayer, $is_first_default_message, $is_first_upload_audio, $is_first_record_audio, $is_first_textto_speech, $first_audio_file, $first_text, $is_no_response_default_message, $is_no_response_upload_audio, $is_no_response_record_audio, $is_no_response_textto_speech, $no_response_audio_file, $no_response_text, $is_hang_up_message, $press2_default_message, $press2_upload_audio, $press2_record_audio, $press2_textto_speech, $press2_audio_file, $press2_text, $press2_auth_code_default_message, $press2_auth_code_upload_audio, $press2_auth_code_record_audio, $press2_auth_code_textto_speech, $press2_auth_code_audio_file, $press2_auth_code_text, $press2_auth_code_ack_default_message, $press2_auth_code_ack_upload_audio, $press2_auth_code_ack_record_audio, $press2_auth_code_ack_textto_speech, $press2_auth_code_ack_audio_file, $press2_auth_code_ack_text, $press2_auth_code_access_default_message, $press2_auth_code_access_upload_audio, $press2_auth_code_access_record_audio, $press2_auth_code_access_textto_speech, $press2_auth_code_access_audio_file, $press2_auth_code_access_text, $press2_auth_code_denied_default_message, $press2_auth_code_denied_upload_audio, $press2_auth_code_denied_record_audio, $press2_auth_code_denied_textto_speech, $press2_auth_code_denied_audio_file, $press2_auth_code_denied_text, $is_authorized_message, $is_pre_notify_message, $is_advertisement_default_message, $is_advertisement_upload_audio, $is_advertisement_record_audio, $is_advertisement_textto_speech, $advertisement_audio_file, $advertisement_text, $is_connected_no_answer_default_message, $is_connected_no_answer_upload_audio, $is_connected_no_answer_record_audio, $is_connected_no_answer_textto_speech, $connected_no_answer_audio_file, $connected_no_answer_text, $is_connected_hangeup_message, $is_connected_hangeup_default_message, $is_connected_hangeup_upload_audio, $is_connected_hangeup_record_audio, $is_connected_hangeup_textto_speech, $connected_hangeup_audio_file, $connected_hangeup_text, $door_key_option, $is_beep_default_message, $is_beep_upload_audio, $is_beep_record_audio, $is_beep_textto_speech, $beep_audio_file, $beep_text, $is_access_default_message, $is_access_upload_audio, $is_access_record_audio, $is_access_textto_speech, $access_audio_file, $access_text, $is_grant_access_detail_message, $is_hang_up_call_terminate, $end_call_time, $call_duration_after_user_connect, $update_call_flow, $call_flow_id, $first_number, $second_number, $third_number, $first_number_disturb, $second_number_disturb, $third_number_disturb, $first_message_vocie_select, $no_response_vocie_select, $press2_vocie_select, $press2_auth_vocie_select, $press2_auth_ack_vocie_select, $press2_auth_access_vocie_select, $press2_auth_denied_vocie_select, $advertisement_vocie_select, $connected_no_answer_vocie_select, $connected_hangup_vocie_select, $is_beep_vocie_select, $is_access_vocie_select){

    $my_call_flow_data = fetchDataSingle('my_call_flow', ['property_id' => $property_id]);
    if(isset($my_call_flow_data['id']) && !empty($my_call_flow_data['id']))
    {
        if((isset($my_call_flow_data['first_audio_file'])) && ($first_audio_file != $my_call_flow_data['first_audio_file'])){
            if(!empty($my_call_flow_data['first_audio_file']) && $my_call_flow_data['first_audio_file'] != 'Welcome-to-Our-Home.wav'){
                delete_audio_file($my_call_flow_data['first_audio_file']);
            }
            if(!empty($my_call_flow_data['first_audio_file']) && !empty($first_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['first_audio_file'], $first_audio_file, "Updated welcome voice", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['first_text']) && !empty($first_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['first_text'], $first_audio_file, "Updated welcome voice from text to speech", "Medium", "Call Flow");   
            }
        }

        if((isset($my_call_flow_data['first_text'])) && ($my_call_flow_data['first_text'] != $first_text)){
            if(!empty($my_call_flow_data['first_text']) && !empty($first_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['first_text'], $first_text, "Updated welcome text to speech", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['first_audio_file']) && !empty($first_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['first_audio_file'], $first_text, "Updated welcome text to speech from voice", "Medium", "Call Flow");
            }
        }

        if((isset($my_call_flow_data['no_response_audio_file'])) && ($no_response_audio_file != $my_call_flow_data['no_response_audio_file'])){
            
            if(!empty($my_call_flow_data['no_response_audio_file']) && $my_call_flow_data['no_response_audio_file'] != 'good_bye.wav'){
                delete_audio_file($my_call_flow_data['no_response_audio_file']);
            }

            if(!empty($my_call_flow_data['no_response_audio_file']) && !empty($no_response_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['no_response_audio_file'], $no_response_audio_file, "Updated no response voice", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['no_response_audio_file']) && !empty($no_response_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $no_response_text, $no_response_audio_file, "Updated no response voice from text to speech", "Medium", "Call Flow");
            }

        }
        if((isset($my_call_flow_data['no_response_text'])) && ($my_call_flow_data['no_response_text'] != $no_response_text)){
            if(!empty($my_call_flow_data['no_response_text']) && !empty($no_response_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['no_response_text'], $no_response_text, "Updated no response text to speech", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['no_response_audio_file']) && !empty($no_response_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['no_response_audio_file'], $no_response_text, "Updated no response text to speech from voice", "Medium", "Call Flow");
            }
        }
        if((isset($my_call_flow_data['press2_audio_file'])) && ($press2_audio_file != $my_call_flow_data['press2_audio_file'])){
            if(!empty($my_call_flow_data['press2_audio_file']) && $my_call_flow_data['press2_audio_file'] != 'enter_your_code_now.wav'){
                delete_audio_file($my_call_flow_data['press2_audio_file']);
            }

            if(!empty($my_call_flow_data['press2_audio_file']) && !empty($press2_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_audio_file'], $press2_audio_file, "Updated press 2 voice", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['press2_text']) && !empty($press2_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_text'], $press2_audio_file, "Updated press 2 voice  from text to speech", "Medium", "Call Flow");
            }
        }

        if((isset($my_call_flow_data['press2_text'])) && ($my_call_flow_data['press2_text'] != $press2_text)){
            if(!empty($my_call_flow_data['press2_text']) && !empty($press2_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_text'], $press2_text, "Updated press 2 text to speech", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['press2_audio_file']) && !empty($press2_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_audio_file'], $press2_text, "Updated press 2 text to speech from voice", "Medium", "Call Flow");
            }
        }

        if((isset($my_call_flow_data['press2_auth_code_audio_file'])) && ($press2_auth_code_audio_file != $my_call_flow_data['press2_auth_code_audio_file'])){
            if(!empty($my_call_flow_data['press2_auth_code_audio_file']) && $my_call_flow_data['press2_auth_code_audio_file'] != 'please_hold.wav'){
                delete_audio_file($my_call_flow_data['press2_auth_code_audio_file']);
            }
            if(!empty($my_call_flow_data['press2_auth_code_audio_file']) && !empty($press2_auth_code_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_auth_code_audio_file'], $press2_auth_code_audio_file, "Updated Use authorized code voice", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['press2_auth_code_text']) && !empty($press2_auth_code_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_auth_code_text'], $press2_auth_code_audio_file, "Updated Use authorized code voice from text to speech", "Medium", "Call Flow");
            }

        }
        
        if((isset($my_call_flow_data['press2_auth_code_text'])) && ($my_call_flow_data['press2_auth_code_text'] != $press2_auth_code_text)){
            if(!empty($my_call_flow_data['press2_auth_code_text']) && !empty($press2_auth_code_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_auth_code_text'], $press2_auth_code_text, "Updated Use authorized code text to speech", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['press2_auth_code_audio_file']) && !empty($press2_auth_code_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_auth_code_audio_file'], $press2_auth_code_text, "Updated Use authorized code text to speech from voice", "Medium", "Call Flow");
            }
        }

        if((isset($my_call_flow_data['press2_auth_code_ack_audio_file'])) && ($press2_auth_code_ack_audio_file != $my_call_flow_data['press2_auth_code_ack_audio_file'])){
            if(!empty($my_call_flow_data['press2_auth_code_ack_audio_file']) && $my_call_flow_data['press2_auth_code_ack_audio_file'] != 'open_command_sent.wav'){
                delete_audio_file($my_call_flow_data['press2_auth_code_ack_audio_file']);
            }
            if(!empty($my_call_flow_data['press2_auth_code_ack_audio_file']) && !empty($press2_auth_code_ack_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_auth_code_ack_audio_file'], $press2_auth_code_ack_audio_file, "Updated acknowledge authorized code voice", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['press2_auth_code_ack_text']) && !empty($press2_auth_code_ack_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_auth_code_ack_text'], $press2_auth_code_ack_audio_file, "Updated acknowledge authorized code voice from text to speech", "Medium", "Call Flow");
            }
        }

        if((isset($my_call_flow_data['press2_auth_code_ack_text'])) && ($my_call_flow_data['press2_auth_code_ack_text'] != $press2_auth_code_ack_text)){
            if(!empty($my_call_flow_data['press2_auth_code_ack_text']) && !empty($press2_auth_code_ack_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_auth_code_ack_text'], $press2_auth_code_ack_text, "Updated acknowledge authorized code text to speech", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['press2_auth_code_ack_audio_file']) && !empty($press2_auth_code_ack_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_auth_code_ack_audio_file'], $press2_auth_code_ack_text, "Updated acknowledge authorized code text to speech from voice", "Medium", "Call Flow");
            }
        }
        
        if((isset($my_call_flow_data['press2_auth_code_access_audio_file'])) && ($press2_auth_code_access_audio_file != $my_call_flow_data['press2_auth_code_access_audio_file'])){
            if(!empty($my_call_flow_data['press2_auth_code_access_audio_file']) && $my_call_flow_data['press2_auth_code_access_audio_file'] != 'access_granted.wav'){
                delete_audio_file($my_call_flow_data['press2_auth_code_access_audio_file']);
            }

            if(!empty($my_call_flow_data['press2_auth_code_access_audio_file']) && !empty($press2_auth_code_access_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_auth_code_access_audio_file'], $press2_auth_code_access_audio_file, "Updated use code access granted voice", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['press2_auth_code_access_text']) && !empty($press2_auth_code_access_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_auth_code_access_text'], $press2_auth_code_access_audio_file, "Updated use code access granted voice from text to speech", "Medium", "Call Flow");
            }
            
        }

        if((isset($my_call_flow_data['press2_auth_code_access_text'])) && ($my_call_flow_data['press2_auth_code_access_text'] != $press2_auth_code_access_text)){
            if(!empty($my_call_flow_data['press2_auth_code_access_text']) && !empty($press2_auth_code_access_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_auth_code_access_text'], $press2_auth_code_access_text, "Updated use code access granted text to speech", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['press2_auth_code_access_audio_file']) && !empty($press2_auth_code_access_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_auth_code_access_audio_file'], $press2_auth_code_access_text, "Updated use code access granted text to speech from voice", "Medium", "Call Flow");
            }
        }
        
        if((isset($my_call_flow_data['press2_auth_code_denied_audio_file'])) && ($press2_auth_code_denied_audio_file != $my_call_flow_data['press2_auth_code_denied_audio_file'])){
            if(!empty($my_call_flow_data['press2_auth_code_denied_audio_file']) && $my_call_flow_data['press2_auth_code_denied_audio_file'] != 'access_denied.wav'){
                delete_audio_file($my_call_flow_data['press2_auth_code_denied_audio_file']);
            }

            if(!empty($my_call_flow_data['press2_auth_code_denied_audio_file']) && !empty($press2_auth_code_denied_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_auth_code_denied_audio_file'], $press2_auth_code_denied_audio_file, "Updated use code access denied voice", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['press2_auth_code_denied_text']) && !empty($press2_auth_code_denied_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_auth_code_denied_text'], $press2_auth_code_denied_audio_file, "Updated use code access denied voice from text to speech", "Medium", "Call Flow");
            }
            
        }
        
        if((isset($my_call_flow_data['press2_auth_code_denied_text'])) && ($my_call_flow_data['press2_auth_code_denied_text'] != $press2_auth_code_denied_text)){
            if(!empty($my_call_flow_data['press2_auth_code_denied_text']) && !empty($press2_auth_code_denied_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_auth_code_denied_text'], $press2_auth_code_denied_text, "Updated use code access denied text to speech", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['press2_auth_code_denied_audio_file']) && !empty($press2_auth_code_denied_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['press2_auth_code_denied_audio_file'], $press2_auth_code_denied_text, "Updated use code access denied text to speech from voice", "Medium", "Call Flow");
            }
        }

        if((isset($my_call_flow_data['advertisement_audio_file'])) && ($advertisement_audio_file != $my_call_flow_data['advertisement_audio_file'])){
            if(!empty($my_call_flow_data['advertisement_audio_file']) && $my_call_flow_data['advertisement_audio_file'] != 'You-are-using-invisible-intercom-ADVERTSING.wav'){
                delete_audio_file($my_call_flow_data['advertisement_audio_file']);
            }
            if(!empty($my_call_flow_data['advertisement_audio_file']) && !empty($advertisement_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['advertisement_audio_file'], $advertisement_audio_file, "Updated press 1 advertisement voice", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['advertisement_text']) && !empty($advertisement_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['advertisement_text'], $advertisement_audio_file, "Updated press 1 advertisement voice from text to speech", "Medium", "Call Flow");
            }
        }
        
        if((isset($my_call_flow_data['advertisement_text'])) && ($my_call_flow_data['advertisement_text'] != $advertisement_text)){
            if(!empty($my_call_flow_data['advertisement_text']) && !empty($advertisement_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['advertisement_text'], $advertisement_text, "Updated press 1 advertisement text to speech", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['advertisement_audio_file']) && !empty($advertisement_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['advertisement_audio_file'], $advertisement_text, "Updated press 1 advertisement text to speech from voice", "Medium", "Call Flow");
            }
        }

        if((isset($my_call_flow_data['connected_no_answer_audio_file'])) && ($connected_no_answer_audio_file != $my_call_flow_data['connected_no_answer_audio_file'])){
            if(!empty($my_call_flow_data['connected_no_answer_audio_file']) && $my_call_flow_data['connected_no_answer_audio_file'] != 'no_one_available.wav'){
                delete_audio_file($my_call_flow_data['connected_no_answer_audio_file']);
            }
            if(!empty($my_call_flow_data['connected_no_answer_audio_file']) && !empty($connected_no_answer_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['connected_no_answer_audio_file'], $connected_no_answer_audio_file, "Updated When call is connected to me but I don't answer voice", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['connected_no_answer_text']) && !empty($connected_no_answer_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['connected_no_answer_text'], $connected_no_answer_audio_file, "Updated When call is connected to me but I don't answer voice from text to speech", "Medium", "Call Flow");
            }
            
        }
        
        if((isset($my_call_flow_data['connected_no_answer_text'])) && ($my_call_flow_data['connected_no_answer_text'] != $connected_no_answer_text)){
            if(!empty($my_call_flow_data['connected_no_answer_text']) && !empty($connected_no_answer_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['connected_no_answer_text'], $connected_no_answer_text, "Updated When call is connected to me but I don't answer text to speech", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['connected_no_answer_audio_file']) && !empty($connected_no_answer_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['connected_no_answer_audio_file'], $connected_no_answer_text, "Updated When call is connected to me but I don't answer text to speech from voice", "Medium", "Call Flow");
            }
        }

        if((isset($my_call_flow_data['connected_hangeup_audio_file'])) && ($connected_hangeup_audio_file != $my_call_flow_data['connected_hangeup_audio_file'])){
            if(!empty($my_call_flow_data['connected_hangeup_audio_file']) && $my_call_flow_data['connected_hangeup_audio_file'] != 'access_denied.wav'){
                delete_audio_file($my_call_flow_data['connected_hangeup_audio_file']);
            }
            if(!empty($my_call_flow_data['connected_hangeup_audio_file']) && !empty($connected_hangeup_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['connected_hangeup_audio_file'], $connected_hangeup_audio_file, "Updated access denied voice", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['connected_hangeup_text']) && !empty($connected_hangeup_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['connected_hangeup_text'], $connected_hangeup_audio_file, "Updated access denied voice from text to speech", "Medium", "Call Flow");
            }
        }
        
        if((isset($my_call_flow_data['connected_hangeup_text'])) && ($my_call_flow_data['connected_hangeup_text'] != $connected_hangeup_text)){
            if(!empty($my_call_flow_data['connected_hangeup_text']) && !empty($connected_hangeup_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['connected_hangeup_text'], $connected_hangeup_text, "Updated access denied text to speech", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['connected_hangeup_audio_file']) && !empty($connected_hangeup_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['connected_hangeup_audio_file'], $connected_hangeup_text, "Updated access denied text to speech from voice", "Medium", "Call Flow");
            }
        }

        if((isset($my_call_flow_data['beep_audio_file'])) && ($beep_audio_file != $my_call_flow_data['beep_audio_file'])){
            if(!empty($my_call_flow_data['beep_audio_file']) && $my_call_flow_data['beep_audio_file'] != 'open_command_sent.wav'){
                delete_audio_file($my_call_flow_data['beep_audio_file']);
            }
            if(!empty($my_call_flow_data['beep_audio_file']) && !empty($beep_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['beep_audio_file'], $beep_audio_file, "Updated open command sent voice", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['beep_text']) && !empty($beep_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['beep_text'], $beep_audio_file, "Updated open command sent voice from text to speech", "Medium", "Call Flow");
            }
            
        }
        
        if((isset($my_call_flow_data['beep_text'])) && ($my_call_flow_data['beep_text'] != $beep_text)){
            if(!empty($my_call_flow_data['beep_text']) && !empty($beep_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['beep_text'], $beep_text, "Updated open command sent text to speech", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['beep_audio_file']) && !empty($beep_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['beep_audio_file'], $beep_text, "Updated open command sent text to speech from voice", "Medium", "Call Flow");
            }
        }

        if((isset($my_call_flow_data['access_audio_file'])) && ($access_audio_file != $my_call_flow_data['access_audio_file'])){
            if(!empty($my_call_flow_data['access_audio_file']) && $my_call_flow_data['access_audio_file'] != 'You-may-now-access-the-property.wav'){
                delete_audio_file($my_call_flow_data['access_audio_file']);
            }
            if(!empty($my_call_flow_data['access_audio_file']) && !empty($access_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['access_audio_file'], $access_audio_file, "Updated access granted voice", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['access_text']) && !empty($access_audio_file)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['access_text'], $access_audio_file, "Updated access granted voice from text to speech", "Medium", "Call Flow");
            }
        }
        
        if((isset($my_call_flow_data['access_text'])) && ($my_call_flow_data['access_text'] != $access_text)){
            if(!empty($my_call_flow_data['access_text']) && !empty($access_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['access_text'], $access_text, "Updated access granted text to speech", "Medium", "Call Flow");
            }
            else if(!empty($my_call_flow_data['access_audio_file']) && !empty($access_text)){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['access_audio_file'], $access_text, "Updated access granted text to speech from voice", "Medium", "Call Flow");
            }
        }

        if($my_call_flow_data['is_hang_up_message'] != $is_hang_up_message){
            createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['is_hang_up_message'], $is_hang_up_message, "Updated hang up message", "Medium", "Call Flow");
        }
        if($my_call_flow_data['is_authorized_message'] != $is_authorized_message){
            createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['is_authorized_message'], $is_authorized_message, "Updated authorized message", "Medium", "Call Flow");
        }
        if($my_call_flow_data['is_pre_notify_message'] != $is_pre_notify_message){
            createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['is_pre_notify_message'], $is_pre_notify_message, "Updated press 1 pre notify message", "Medium", "Call Flow");
        }
        if($my_call_flow_data['first_number'] != $first_number){
            createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['first_number'], $first_number, "Updated call forwaded first number", "Medium", "Call Flow");
        }
        if($my_call_flow_data['second_number'] != $second_number){
            createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['second_number'], $second_number, "Updated call forwaded second number", "Medium", "Call Flow");
        }
        if($my_call_flow_data['third_number'] != $third_number){
            createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['third_number'], $third_number, "Updated call forwaded third number", "Medium", "Call Flow");
        }
        if($my_call_flow_data['first_number_disturb'] != $first_number_disturb){
            createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['first_number_disturb'], $first_number_disturb, "Updated call forwaded first number do not disturb", "Medium", "Call Flow");
        }
        if($my_call_flow_data['second_number_disturb'] != $second_number_disturb){
            createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['second_number_disturb'], $second_number_disturb, "Updated call forwaded second number do not disturb", "Medium", "Call Flow");
        }
        if($my_call_flow_data['third_number_disturb'] != $third_number_disturb){
            createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['third_number_disturb'], $third_number_disturb, "Updated call forwaded third number do not disturb", "Medium", "Call Flow");
        }
        if($my_call_flow_data['call_duration_after_user_connect'] != $call_duration_after_user_connect){
            createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['call_duration_after_user_connect'], $call_duration_after_user_connect, "Updated If I answer I can communicate with them call will end after updated time", "Medium", "Call Flow");
        }
        if($my_call_flow_data['is_connected_hangeup_message'] != $is_connected_hangeup_message){
            createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['is_connected_hangeup_message'], $is_connected_hangeup_message, "Updated If I hang up message will play or call will just terminate", "Medium", "Call Flow");
        }
        if($my_call_flow_data['is_grant_access_detail_message'] != $is_grant_access_detail_message){
            createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['is_grant_access_detail_message'], $is_grant_access_detail_message, "Send an SMS to me for granted access detail", "Medium", "Call Flow");
        }
        if($my_call_flow_data['is_hang_up_call_terminate'] != $is_hang_up_call_terminate){
            createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['is_hang_up_call_terminate'], $is_hang_up_call_terminate, "Call will terminate after grant access", "Medium", "Call Flow");
        }
        if($my_call_flow_data['is_hang_up_call_terminate'] == 1){
            if($my_call_flow_data['end_call_time'] != $end_call_time){
                createAuditLog($_SESSION["userid"], "Update Call FLow", "my_call_flow", $my_call_flow_data['id'], $_SESSION["email"]??null, $_SESSION['property'], $my_call_flow_data['end_call_time'], $end_call_time, "I can stay on the call for up to " . $end_call_time . " seconds to navigate my visitor", "Medium", "Call Flow");
            }
        }
        $update_data = [
            'is_first_default_message' => $is_first_default_message,
            'is_first_upload_audio' => $is_first_upload_audio,
            'is_first_record_audio' => $is_first_record_audio,
            'is_first_textto_speech' => $is_first_textto_speech,
            'first_audio_file' => $first_audio_file,
            'first_text' => $first_text,
            'first_message_vocie_select' => $first_message_vocie_select,
            'is_no_response_default_message' => $is_no_response_default_message,
            'is_no_response_upload_audio' => $is_no_response_upload_audio,
            'is_no_response_record_audio' => $is_no_response_record_audio,
            'is_no_response_textto_speech' => $is_no_response_textto_speech,
            'no_response_audio_file' => $no_response_audio_file,
            'no_response_text' => $no_response_text,
            'no_response_vocie_select' => $no_response_vocie_select,
            'is_hang_up_message' => $is_hang_up_message,
            'press2_default_message' => $press2_default_message,
            'press2_upload_audio' => $press2_upload_audio,
            'press2_record_audio' => $press2_record_audio,
            'press2_textto_speech' => $press2_textto_speech,
            'press2_audio_file' => $press2_audio_file,
            'press2_text' => $press2_text,
            'press2_vocie_select' => $press2_vocie_select,
            'press2_auth_code_default_message' => $press2_auth_code_default_message,
            'press2_auth_code_upload_audio' => $press2_auth_code_upload_audio,
            'press2_auth_code_record_audio' => $press2_auth_code_record_audio,
            'press2_auth_code_textto_speech' => $press2_auth_code_textto_speech,
            'press2_auth_code_audio_file' => $press2_auth_code_audio_file,
            'press2_auth_code_text' => $press2_auth_code_text,
            'press2_auth_vocie_select' => $press2_auth_vocie_select,
            'press2_auth_code_ack_default_message' => $press2_auth_code_ack_default_message,
            'press2_auth_code_ack_upload_audio' => $press2_auth_code_ack_upload_audio,
            'press2_auth_code_ack_record_audio' => $press2_auth_code_ack_record_audio,
            'press2_auth_code_ack_textto_speech' => $press2_auth_code_ack_textto_speech,
            'press2_auth_code_ack_audio_file' => $press2_auth_code_ack_audio_file,
            'press2_auth_code_ack_text' => $press2_auth_code_ack_text,
            'press2_auth_ack_vocie_select' => $press2_auth_ack_vocie_select,
            'press2_auth_code_access_default_message' => $press2_auth_code_access_default_message,
            'press2_auth_code_access_upload_audio' => $press2_auth_code_access_upload_audio,
            'press2_auth_code_access_record_audio' => $press2_auth_code_access_record_audio,
            'press2_auth_code_access_textto_speech' => $press2_auth_code_access_textto_speech,
            'press2_auth_code_access_audio_file' => $press2_auth_code_access_audio_file,
            'press2_auth_code_access_text' => $press2_auth_code_access_text,
            'press2_auth_access_vocie_select' => $press2_auth_access_vocie_select,
            'press2_auth_code_denied_default_message' => $press2_auth_code_denied_default_message,
            'press2_auth_code_denied_upload_audio' => $press2_auth_code_denied_upload_audio,
            'press2_auth_code_denied_record_audio' => $press2_auth_code_denied_record_audio,
            'press2_auth_code_denied_textto_speech' => $press2_auth_code_denied_textto_speech,
            'press2_auth_code_denied_audio_file' => $press2_auth_code_denied_audio_file,
            'press2_auth_code_denied_text' => $press2_auth_code_denied_text,
            'press2_auth_denied_vocie_select' => $press2_auth_denied_vocie_select,
            'is_authorized_message' => $is_authorized_message,
            'is_pre_notify_message' => $is_pre_notify_message,
            'is_advertisement_default_message' => $is_advertisement_default_message,
            'is_advertisement_upload_audio' => $is_advertisement_upload_audio,
            'is_advertisement_record_audio' => $is_advertisement_record_audio,
            'is_advertisement_textto_speech' => $is_advertisement_textto_speech,
            'advertisement_audio_file' => $advertisement_audio_file,
            'advertisement_text' => $advertisement_text,
            'advertisement_vocie_select' => $advertisement_vocie_select,
            'is_connected_no_answer_default_message' => $is_connected_no_answer_default_message,
            'is_connected_no_answer_upload_audio' => $is_connected_no_answer_upload_audio,
            'is_connected_no_answer_record_audio' => $is_connected_no_answer_record_audio,
            'is_connected_no_answer_textto_speech' => $is_connected_no_answer_textto_speech,
            'connected_no_answer_audio_file' => $connected_no_answer_audio_file,
            'connected_no_answer_text' => $connected_no_answer_text,
            'connected_no_answer_vocie_select' => $connected_no_answer_vocie_select,
            'is_connected_hangeup_message' => $is_connected_hangeup_message,
            'is_connected_hangeup_default_message' => $is_connected_hangeup_default_message,
            'is_connected_hangeup_upload_audio' => $is_connected_hangeup_upload_audio,
            'is_connected_hangeup_record_audio' => $is_connected_hangeup_record_audio,
            'is_connected_hangeup_textto_speech' => $is_connected_hangeup_textto_speech,
            'connected_hangeup_audio_file' => $connected_hangeup_audio_file,
            'connected_hangeup_text' => $connected_hangeup_text,
            'connected_hangup_vocie_select' => $connected_hangup_vocie_select,
            'is_beep_default_message' => $is_beep_default_message,
            'is_beep_upload_audio' => $is_beep_upload_audio,
            'is_beep_record_audio' => $is_beep_record_audio,
            'is_beep_textto_speech' => $is_beep_textto_speech,
            'beep_audio_file' => $beep_audio_file,
            'beep_text' => $beep_text,
            'is_beep_vocie_select' => $is_beep_vocie_select,
            'is_access_default_message' => $is_access_default_message,
            'is_access_upload_audio' => $is_access_upload_audio,
            'is_access_record_audio' => $is_access_record_audio,
            'is_access_textto_speech' => $is_access_textto_speech,
            'access_audio_file' => $access_audio_file,
            'access_text' => $access_text,
            'is_access_vocie_select' => $is_access_vocie_select,
            'is_grant_access_detail_message' => $is_grant_access_detail_message,
            'is_hang_up_call_terminate' => $is_hang_up_call_terminate,
            'end_call_time' => $end_call_time,
            'call_duration_after_user_connect' => $call_duration_after_user_connect,
            'first_number' => $first_number,
            'second_number' => $second_number,
            'third_number' => $third_number,
            'first_number_disturb' => $first_number_disturb,
            'second_number_disturb' => $second_number_disturb,
            'third_number_disturb' => $third_number_disturb,
            'door_key_option' => $door_key_option,
        ];
        $where = 'id = :id';
        $params = ['id' => $call_flow_id];
        $updateSuccess = updateTable('my_call_flow', $update_data, $where, $params);
    }
    else{
        $tab_name = "my_call_flow";
        $tab_data = [
            'user_id' => $userId,
            'property_id' => $property_id,
            'is_first_default_message' => $is_first_default_message,
            'is_first_upload_audio' => $is_first_upload_audio,
            'is_first_record_audio' => $is_first_record_audio,
            'is_first_textto_speech' => $is_first_textto_speech,
            'first_audio_file' => $first_audio_file,
            'first_text' => $first_text,
            'first_message_vocie_select' => $first_message_vocie_select,
            'is_no_response_default_message' => $is_no_response_default_message,
            'is_no_response_upload_audio' => $is_no_response_upload_audio,
            'is_no_response_record_audio' => $is_no_response_record_audio,
            'is_no_response_textto_speech' => $is_no_response_textto_speech,
            'no_response_audio_file' => $no_response_audio_file,
            'no_response_text' => $no_response_text,
            'no_response_vocie_select' => $no_response_vocie_select,
            'is_hang_up_message' => $is_hang_up_message,
            'press2_default_message' => $press2_default_message,
            'press2_upload_audio' => $press2_upload_audio,
            'press2_record_audio' => $press2_record_audio,
            'press2_textto_speech' => $press2_textto_speech,
            'press2_audio_file' => $press2_audio_file,
            'press2_text' => $press2_text,
            'press2_vocie_select' => $press2_vocie_select,
            'press2_auth_code_default_message' => $press2_auth_code_default_message,
            'press2_auth_code_upload_audio' => $press2_auth_code_upload_audio,
            'press2_auth_code_record_audio' => $press2_auth_code_record_audio,
            'press2_auth_code_textto_speech' => $press2_auth_code_textto_speech,
            'press2_auth_code_audio_file' => $press2_auth_code_audio_file,
            'press2_auth_code_text' => $press2_auth_code_text,
            'press2_auth_vocie_select' => $press2_auth_vocie_select,
            'press2_auth_code_ack_default_message' => $press2_auth_code_ack_default_message,
            'press2_auth_code_ack_upload_audio' => $press2_auth_code_ack_upload_audio,
            'press2_auth_code_ack_record_audio' => $press2_auth_code_ack_record_audio,
            'press2_auth_code_ack_textto_speech' => $press2_auth_code_ack_textto_speech,
            'press2_auth_code_ack_audio_file' => $press2_auth_code_ack_audio_file,
            'press2_auth_code_ack_text' => $press2_auth_code_ack_text,
            'press2_auth_ack_vocie_select' => $press2_auth_ack_vocie_select,
            'press2_auth_code_access_default_message' => $press2_auth_code_access_default_message,
            'press2_auth_code_access_upload_audio' => $press2_auth_code_access_upload_audio,
            'press2_auth_code_access_record_audio' => $press2_auth_code_access_record_audio,
            'press2_auth_code_access_textto_speech' => $press2_auth_code_access_textto_speech,
            'press2_auth_code_access_audio_file' => $press2_auth_code_access_audio_file,
            'press2_auth_code_access_text' => $press2_auth_code_access_text,
            'press2_auth_access_vocie_select' => $press2_auth_access_vocie_select,
            'press2_auth_code_denied_default_message' => $press2_auth_code_denied_default_message,
            'press2_auth_code_denied_upload_audio' => $press2_auth_code_denied_upload_audio,
            'press2_auth_code_denied_record_audio' => $press2_auth_code_denied_record_audio,
            'press2_auth_code_denied_textto_speech' => $press2_auth_code_denied_textto_speech,
            'press2_auth_code_denied_audio_file' => $press2_auth_code_denied_audio_file,
            'press2_auth_code_denied_text' => $press2_auth_code_denied_text,
            'press2_auth_denied_vocie_select' => $press2_auth_denied_vocie_select,
            'is_authorized_message' => $is_authorized_message,
            'is_pre_notify_message' => $is_pre_notify_message,
            'is_advertisement_default_message' => $is_advertisement_default_message,
            'is_advertisement_upload_audio' => $is_advertisement_upload_audio,
            'is_advertisement_record_audio' => $is_advertisement_record_audio,
            'is_advertisement_textto_speech' => $is_advertisement_textto_speech,
            'advertisement_audio_file' => $advertisement_audio_file,
            'advertisement_text' => $advertisement_text,
            'advertisement_vocie_select' => $advertisement_vocie_select,
            'is_connected_no_answer_default_message' => $is_connected_no_answer_default_message,
            'is_connected_no_answer_upload_audio' => $is_connected_no_answer_upload_audio,
            'is_connected_no_answer_record_audio' => $is_connected_no_answer_record_audio,
            'is_connected_no_answer_textto_speech' => $is_connected_no_answer_textto_speech,
            'connected_no_answer_audio_file' => $connected_no_answer_audio_file,
            'connected_no_answer_text' => $connected_no_answer_text,
            'connected_no_answer_vocie_select' => $connected_no_answer_vocie_select,
            'is_connected_hangeup_message' => $is_connected_hangeup_message,
            'is_connected_hangeup_default_message' => $is_connected_hangeup_default_message,
            'is_connected_hangeup_upload_audio' => $is_connected_hangeup_upload_audio,
            'is_connected_hangeup_record_audio' => $is_connected_hangeup_record_audio,
            'is_connected_hangeup_textto_speech' => $is_connected_hangeup_textto_speech,
            'connected_hangeup_audio_file' => $connected_hangeup_audio_file,
            'connected_hangeup_text' => $connected_hangeup_text,
            'connected_hangup_vocie_select' => $connected_hangup_vocie_select,
            'is_beep_default_message' => $is_beep_default_message,
            'is_beep_upload_audio' => $is_beep_upload_audio,
            'is_beep_record_audio' => $is_beep_record_audio,
            'is_beep_textto_speech' => $is_beep_textto_speech,
            'beep_audio_file' => $beep_audio_file,
            'beep_text' => $beep_text,
            'is_beep_vocie_select' => $is_beep_vocie_select,
            'is_access_default_message' => $is_access_default_message,
            'is_access_upload_audio' => $is_access_upload_audio,
            'is_access_record_audio' => $is_access_record_audio,
            'is_access_textto_speech' => $is_access_textto_speech,
            'access_audio_file' => $access_audio_file,
            'access_text' => $access_text,
            'is_access_vocie_select' => $is_access_vocie_select,
            'is_grant_access_detail_message' => $is_grant_access_detail_message,
            'is_hang_up_call_terminate' => $is_hang_up_call_terminate,
            'end_call_time' => $end_call_time,
            'call_duration_after_user_connect' => $call_duration_after_user_connect,
            'first_number' => $first_number,
            'second_number' => $second_number,
            'third_number' => $third_number,
            'first_number_disturb' => $first_number_disturb,
            'second_number_disturb' => $second_number_disturb,
            'third_number_disturb' => $third_number_disturb,
            'door_key_option' => $door_key_option,
        ];
        insertData($tab_name, $tab_data);
        $insert_id = getLastInsertId();
        createAuditLog($_SESSION["userid"], "Create Call FLow", "my_call_flow", $insert_id, $_SESSION["email"]??null, $_SESSION['property'], null, json_encode($tab_data), "New Call Flow Added", "Medium","Call Flow");
    }
}

function getPropertyImage($prop) {

    try {
    
        if ($prop) {
            $propertyData = fetchData('properties', ['id' => $prop]);
        }else {
            $propertyData = fetchData('properties', ['id' => $_SESSION['property']]);
        }

        if ($propertyData && !empty($propertyData[0]['image_path'])) {
            return $propertyData[0]['image_path'];
        } else {
            return "real-estate-property.jpg";

        }
    } catch (\Throwable $th) {
        return "real-estate-property.jpg";

    }
}

function getPropertyLink($prop) {

    try {
    
        if ($prop) {
            $propertyData = fetchDataSingle('properties', ['id' => $prop]);
        }else {
            $propertyData = fetchDataSingle('properties', ['id' => $_SESSION['property']]);
        }

        if ($propertyData && !empty($propertyData['property_link'])) {
            return $propertyData['property_link'];
        } else {
            return null;
        }
    } catch (\Throwable $th) {
        return null;

    }
}

function getPropName($currentProp) {

    $currentPropertyId = $currentProp;

    if (isset($_SESSION['properties'])) {
        foreach ($_SESSION['properties'] as $property) {
            if ($property['id'] == $currentPropertyId) {

                $propName = $property['name'];
                break;
            }
        }
    }else {
        $getPropDetails = getProperty($_SESSION['userid'], $_SESSION['layer']);

        foreach ($getPropDetails as $property) {
            if ($property['id'] == $currentPropertyId) {

                $propName = $property['name'];
                break;
            }
        }

    }

    return $propName;
}

function get_my_referral_code($pdo, $userId, $userLayer, $property_id){
    $referral = fetchDataSingle("referral_codes",["property_id" => $property_id]);
    $property_data = fetchDataSingle("properties",["id" => $property_id]);
    if(isset($referral['id']) && !empty($referral['id'])){
        $referral['invite_link'] = base_url() . "/register?ref=" . $referral['invite_code'];
        $referral['property_name'] = $property_data['name'];
        return $referral;
    }
    else{
        $generate_Code = generateRandomCode();
        $random_num = bin2hex(random_bytes(16));
        insertData('referral_codes', [
            'user_id' => $userId,
            'property_id' => $property_id,
            'code' => $generate_Code,
            'invite_code' => $random_num,
        ]);
        $referral = fetchDataSingle("referral_codes",["property_id" => $property_id]);
        $referral['invite_link'] = base_url() . "register?ref=" . $random_num;
        $referral['property_name'] = $property_data['name'];
        return $referral;
    }
}

function get_my_referrals($pdo, $userId, $userLayer, $property_id){
    $data = [];
    $referral = fetchDataSingle("referral_codes",["property_id" => $property_id]);
    if(isset($referral['id']) && !empty($referral['id'])){
        $referral_property = fetchDataSingle("properties",["id" => $property_id]);
        $sql = "SELECT p.name, r.* FROM referrals r  LEFT JOIN properties p ON r.property_id = p.id WHERE r.referral_code = :referral_code";
        $params = [':referral_code' => $referral['code']];
        $properties = fetchDataWithJoins($sql, $params);
        $data['properties'] = $properties;
        $data['referral_property'] = $referral_property;
    }
    return $data;
}

function generateRandomCode($length = 6) {
    return substr(str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'), 0, $length);
}

function getBaseSubscription($pdo, $userId, $userLayer, $invoice_date=""){
    $base_cost_array = [];
    $property_sub = 0;
    $base_sub = 0;
    
    $first_day = "";
    $base_sub = fetchDataSingle("subscription_pricings");  
    $total_cellular_sim = 0;
    if(!empty($invoice_date)){
        $first_day = date("Y-m-01 00:00:00", strtotime($invoice_date));
        $last_day = date("Y-m-t 23:59:59", strtotime($invoice_date));
        $formatted_date = date("F Y", strtotime($invoice_date));
        
        $property_sub_all = fetchDataByOperatorAll("dynamic_base_costs", ['property_id' => $_SESSION["property"], 'created_at >=' => $first_day, 'created_at <=' => $last_day]);
        $property_sub_all_second = fetchDataByOperatorAll("dynamic_base_costs", ['property_id' => $_SESSION["property"], 'created_at <=' => $first_day]);
        if(isset($property_sub_all[0]['id']) && !empty($property_sub_all[0]['id'])){
            $property_sub = $property_sub_all[0];
        }
        else if(isset($property_sub_all_second[0]['id']) && !empty($property_sub_all_second[0]['id'])){
            $property_sub = $property_sub_all_second[0];
        }

        $first_property_cameras_raw = fetchDataByOperatorAll("live_camera_streaming_data", ['property_id' => $_SESSION["property"], 'created_at <=' => $last_day]);
        $second_property_cameras = fetchDataByOperatorAll("delete_live_camera_streaming_data", ['property_id' => $_SESSION["property"],  'created_at <=' => $last_day, 'deleted_at >=' => $last_day]);
        $third_property_cameras = fetchDataByOperatorAll("delete_live_camera_streaming_data", ['property_id' => $_SESSION["property"],  'created_at <=' => $last_day, 'deleted_at >=' => $first_day, 'deleted_at <=' => $last_day]);

        $first_property_doors_raw = fetchDataByOperatorAll('gate_doors', ['property_id' => $_SESSION["property"], 'created_at <' => $last_day]);
        $second_property_doors = fetchDataByOperatorAll("delete_gate_doors", ['property_id' => $_SESSION["property"],  'created_at <=' => $last_day, 'deleted_at >=' => $last_day]);
        $third_property_doors = fetchDataByOperatorAll("delete_gate_doors", ['property_id' => $_SESSION["property"],  'created_at <=' => $last_day, 'deleted_at >=' => $first_day, 'deleted_at <=' => $last_day]);

        $first_property_cameras = [];
        foreach ($first_property_cameras_raw as $row) {
            $trial_end = date('Y-m-d H:i:s', strtotime($row['created_at'] . ' +30 days'));

            // only include if last_day is AFTER trial_end
            if ($last_day >= $trial_end) {
                $first_property_cameras[] = $row;
            }
        }

        $first_property_doors = [];
        foreach ($first_property_doors_raw as $row1) {
            $trial_end = date('Y-m-d H:i:s', strtotime($row1['created_at'] . ' +30 days'));

            // only include if last_day is AFTER trial_end
            if ($last_day >= $trial_end) {
                $first_property_doors[] = $row1;
            }
        }

        $one_property_numbers = fetchDataByOperatorAll("my_numbers", ['property_id' => $_SESSION["property"],  'created_at <=' => $last_day, 'deleted_at' => null]);
        $second_property_numbers = fetchDataByOperatorAll("my_numbers", ['property_id' => $_SESSION["property"],  'created_at <=' => $last_day, 'deleted_at >=' => $last_day]);
        $third_property_numbers = fetchDataByOperatorAll("my_numbers", ['property_id' => $_SESSION["property"],  'created_at <=' => $last_day, 'deleted_at >=' => $first_day, 'deleted_at <=' => $last_day]);
        $property_numbers = array_merge($one_property_numbers, $second_property_numbers, $third_property_numbers);
        

        $usersDataone = fetchDataByOperatorAll('property_users', ['status' => 'registered', 'property_id' => $_SESSION["property"], 'status' => 'registered', 'created_at <=' => $last_day, 'deleted_at' => null]);
        $multiPropUsersone = fetchDataByOperatorAll('multi_prop_users', ['property_id' => $_SESSION["property"], 'status' => 'Active', 'created_at <=' => $last_day, 'deleted_at' => null]);

        $usersDatatwo = fetchDataByOperatorAll('property_users', ['status' => 'registered', 'property_id' => $_SESSION["property"], 'status' => 'registered', 'created_at <=' => $last_day, 'deleted_at >=' => $last_day]);
        $multiPropUserstwo = fetchDataByOperatorAll('multi_prop_users', ['property_id' => $_SESSION["property"], 'status' => 'Active', 'created_at <=' => $last_day, 'deleted_at >=' => $last_day]);

        $usersDatathree = fetchDataByOperatorAll('property_users', ['status' => 'registered', 'property_id' => $_SESSION["property"], 'status' => 'registered', 'created_at <=' => $last_day, 'deleted_at >=' => $first_day, 'deleted_at <=' => $last_day]);
        $multiPropUsersthree = fetchDataByOperatorAll('multi_prop_users', ['property_id' => $_SESSION["property"], 'status' => 'Active', 'created_at <=' => $last_day, 'deleted_at >=' => $first_day, 'deleted_at <=' => $last_day]);


        $usersData = array_merge($usersDataone, $usersDatatwo, $usersDatathree);
        $multiPropUsers = array_merge($multiPropUsersone, $multiPropUserstwo, $multiPropUsersthree);
        $property_doors = array_merge($first_property_doors, $second_property_doors, $third_property_doors);

        $property_cameras = array_merge($first_property_cameras, $second_property_cameras, $third_property_cameras);

        $cellular_sim = fetchDataByOperatorSingle('cellular_sims', ['property_id' => $_SESSION["property"], 'created_at <=' => $last_day]);
        if(isset($cellular_sim['id']) && !empty($cellular_sim)){
            $total_cellular_sim = $cellular_sim['qty'];
        }

    }
    else{
        $property_sub = fetchDataSingle("dynamic_base_costs", ['property_id' => $_SESSION["property"], 'is_active' => 1]);
        $property_cameras = fetchData("live_camera_streaming_data", ['property_id' => $_SESSION["property"]]);
        $property_numbers = fetchData("my_numbers", ['property_id' => $_SESSION["property"],  'deleted_at' => null]);
        $property_doors = fetchData('gate_doors', ['property_id' => $_SESSION["property"]]);
        $usersData = fetchData('property_users', ['status' => 'registered', 'property_id' => $_SESSION["property"], 'status' => 'registered', 'deleted_at' => null]);
        $multiPropUsers = fetchData('multi_prop_users', ['property_id' => $_SESSION["property"], 'status' => 'Active', 'deleted_at' => null]);
        $formatted_date = date('F Y');
        $cellular_sim = fetchDataSingleDesc('cellular_sims', ['property_id' => $_SESSION["property"], 'is_active' => 1]);
        if(isset($cellular_sim['id']) && !empty($cellular_sim)){
            $total_cellular_sim = $cellular_sim['qty'];
        }
    
    }

    $total_cameras = count($property_cameras);
    $total_numbers = count($property_numbers);
    $total_doors = count($property_doors); 
    if(!isset($property_sub['id']) && empty($property_sub['id'])){
        $property_sub = 0;
    }
    if(!isset($base_sub['id']) && empty($base_sub['id'])){
       $base_sub = 0;
    }

    $property_balance = fetchDataSingle("property_balances", ['property_id' => $_SESSION["property"], 'is_active' => 1]);
    if(!isset($property_balance['id'])){
        $property_balance = 0;
    }

    $property_users = count($usersData) + count($multiPropUsers);
    
    $property = fetchDataSingle('properties', ['id' => $_SESSION['property']]);
    $base_cost_array['property'] = $property;
    $base_cost_array['property_sub'] = $property_sub;
    $base_cost_array['base_sub'] = $base_sub;
    $base_cost_array['user_layer'] = $_SESSION["layer"];
    $base_cost_array['property_cameras'] = $total_cameras;
    $base_cost_array['property_numbers'] = $total_numbers;
    $base_cost_array['property_doors'] = $total_doors;
    $base_cost_array['property_balance'] = $property_balance;
    $base_cost_array['property_users'] = $property_users;
    $base_cost_array['property_cellular_sim'] = $total_cellular_sim;
    $base_cost_array['formatted_date'] = $formatted_date;
    return $base_cost_array;
    
}

function SaveBaseSubscription($pdo, $userId, $userLayer, $sub_fee, $camera_add, $number_add, $door_add, $msrp_sub_fee, $msrp_camera_add, $msrp_number_add, $msrp_door_add, $cellular_sim, $msrp_cellular_sim, $subscription_type, $edited_by){
    if(($edited_by == "admin") || ($edited_by == "super_admin")){
        
        updateTable('dynamic_base_costs', 
            [
                'is_active' => 0,
            ], 
            'property_id = :property_id', 
            ['property_id' => $_SESSION["property"]]
        );
        $save = insertData('dynamic_base_costs', ['property_id' => $_SESSION["property"], 'sub_fee' => $sub_fee, 'camera_add' => $camera_add, 'number_add' => $number_add, 'door_add' => $door_add, 'msrp_sub_fee' => $msrp_sub_fee, 'msrp_camera_add' => $msrp_camera_add, 'msrp_number_add' => $msrp_number_add, 'msrp_door_add' => $msrp_door_add,'cellular_sim' => $cellular_sim, 'msrp_cellular_sim' => $msrp_cellular_sim]); 
    }
    else{
        updateTable('dynamic_base_costs', 
            [
                'is_active' => 0,
            ], 
            'property_id = :property_id', 
            ['property_id' => $_SESSION["property"]]
        );

        $save = insertData('dynamic_base_costs', ['property_id' => $_SESSION["property"], 'msrp_sub_fee' => $msrp_sub_fee, 'msrp_camera_add' => $msrp_camera_add, 'msrp_number_add' => $msrp_number_add, 'msrp_door_add' => $msrp_door_add, 'msrp_cellular_sim' => $msrp_cellular_sim]);
        
    }
    if(isset($save) && !empty($save)){
        return 1;
    }
    else{
        return 0;
    }
}

function SaveMinimumBalance($pdo, $userId, $userLayer, $minimum_balance){
    $property_id = $_SESSION["property"];
    $property_balance = fetchDataSingle("property_balances", ['property_id' => $_SESSION["property"], 'is_active' => 1]);
    if(isset($property_balance['id'])){
        $save = updateTable('property_balances', 
                [
                    'minimum_balance' => $minimum_balance,
                ], 
                'property_id = :property_id', 
                ['property_id' => $property_id]
            );
    }
    else{
        $save = insertData('property_balances', ['property_id' => $_SESSION["property"], 'minimum_balance' => $minimum_balance]);
    }
    if(isset($save) && !empty($save)){
        return 1;
    }
    else{
        return 0;
    }
}

function savePyamentProof($pdo, $userId, $userLayer, $payment_image, $amount){
    $propertyId = $_SESSION["property"];
    $targetDirBase = "../../../../data/all_images/";
    $isUploaded = uploadToAllImages($payment_image, $propertyId, $targetDirBase);
    if ($isUploaded['success']) {
        $imagePath = $isUploaded['image_path'];
        $save = insertData('payment_proofs', ['property_id' => $propertyId, 'user_id' => $userId, 'user_role' => $userLayer, 'payment_image' => $imagePath, 'amount' => $amount]);
        if($save){
            return 1;
        }
        else{
            return 0;
        }
    } else {
        return 0;
       
    }     
}

function getInvoiceHistory($pdo, $userId, $userLayer, $property_id){
    $property = fetchDataSingle('properties', ['id' => $property_id]);

    if(isset($property['id']) && !empty($property['id'])){
        $start = new DateTime($property['created_at']);
        $end   = new DateTime();
        $interval = new DateInterval('P1M');
        $period   = new DatePeriod($start, $interval, $end);

        $months = [];
        foreach ($period as $date) {
            $monthStart = $date->format('Y-m-01'); // first day of month
            $monthEnd   = $date->format('Y-m-t');  // last day of month
            $label      = $date->format('F Y');

            $months[] = [
                'first_date' => $monthStart,
                'last_date'  => $monthEnd,
                'label'      => $label
            ];
        }

        // ✅ Manually add current month
        $currentMonthStart = $end->format('Y-m-01');
        $currentMonthEnd   = $end->format('Y-m-d'); // today
        $currentLabel      = $end->format('F Y');

        $months[] = [
            'first_date' => $currentMonthStart,
            'last_date'  => $currentMonthEnd,
            'label'      => $currentLabel
        ];

        // Reverse order (newest first)
        $months = array_reverse($months);

        $data['invoice_dates'] = $months;
        $data['property_id']   = $property_id;
        return $data;
    }
}



function getPaymentHistory($pdo, $userId, $userLayer, $property_id){
    $data = [];
    $sql = "SELECT p.*, u.firstname, u.lastname FROM payment_proofs p  LEFT JOIN users u ON u.id = p.approved_by WHERE p.property_id = :property_id And p.is_pending = :is_pending";
    $params = [':property_id' => $property_id, ':is_pending' => 0];
    $histories = fetchDataWithJoins($sql, $params);
    $data['histories'] = $histories;
    $data['user_type'] = $userLayer;
    return $data;
}

function getPendingPayment($pdo, $userId, $userLayer){
    $sql = "SELECT pe.*, p.name FROM payment_proofs pe  LEFT JOIN properties p ON p.id = pe.property_id WHERE pe.is_pending = :is_pending";
    $params = [':is_pending' => 1];
    $payments = fetchDataWithJoins($sql, $params);
    return $payments;
}

function approvePendingPayment($pdo, $userId, $userLayer, $payment_id, $amount){
    
    $update_payment = updateTable('payment_proofs', 
            [
                'approved_by' => $userId,
                'amount' => $amount,
                'is_pending' => 0
            ], 
            'id = :id', 
            ['id' => $payment_id]
        );

    if($update_payment){
        $get_penment_data = fetchDataSingle('payment_proofs', ['id' => $payment_id]);
        $property_id = $get_penment_data['property_id'];
        $property_balance_data = fetchDataSingle('property_balances', ['property_id' => $property_id]);

        if(isset($property_balance_data['id']) && !empty($property_balance_data['id'])){
            $total_balance = $property_balance_data['balance'] + $amount;
            $update_property_balance = updateTable('property_balances', 
                                            [
                                                'balance' => $total_balance
                                            ], 
                                            'id = :id', 
                                            ['id' => $property_balance_data['id']]
                                        );
            
        }
        else{
            $save = insertData('property_balances', ['property_id' => $property_id, 'balance' => $amount]);
        }
        return 1;
    }
}

function addCellularSim($pdo, $userId, $userLayer, $qty){
    updateTable('cellular_sims', 
        [
            'is_active' => 0
        ], 
        'property_id = :property_id', 
        ['property_id' => $_SESSION['property']]
    );
    $save = insertData('cellular_sims', ['property_id' => $_SESSION['property'], 'user_id' => $userId, 'qty' => $qty]);
    if($save){
        return 1;
    }
    else{
        return $save;
    }

}