<?php
    if (session_status() === PHP_SESSION_NONE) {
        session_start();
    }
    include '../../db.php';
    include '../../shared/functionsinc.php';
    include 'users_invitation.php';
    include '../helper_functions/data_request.php';
    include '../auth/auth_functions.php';

    function isNumberUnique($number, $currentId = null) {
        $currentpropid = $_SESSION['property'];
    
        try {
    
            $phoneQuery = "
                SELECT COUNT(*) AS count 
                FROM property_users_data 
                WHERE (mobile_number = :number OR home_number = :number) 
                AND property_id = :propertyId
                AND (id != :currentId OR :currentId IS NULL)
                AND deleted_at IS NULL
            ";
    
            $params = [
                'number' => $number,
                'propertyId' => $currentpropid,
                'currentId' => $currentId
            ];
    
            if ($currentId === null) {
                unset($params['currentId']);
            }
    
            $phoneCount = fetchSingleDataWithJoins($phoneQuery, $params)['count'];
    
            return $phoneCount === 0;
        } catch (Exception $e) {
            error_log("Error checking number uniqueness: " . $e->getMessage());
            return false;
        }
    }
    
    function isEmailUnique($email, $currentId = null) {
        $currentpropid = $_SESSION['property'];
    
        try {
    
            $opemailQuery = "
                SELECT COUNT(*) AS count 
                FROM users 
                WHERE (email = :email)
                AND property_id = :propertyId
                AND (id != :currentId OR :currentId IS NULL)
                AND deleted_at IS NULL
            ";
    
            $opuemailQuery = "
                SELECT COUNT(*) AS count 
                FROM property_users
                WHERE (email = :email)
                AND property_id = :propertyId
                AND (id != :currentId OR :currentId IS NULL)
                AND deleted_at IS NULL
            ";
    
            $params = [
                'email' => $email,
                'propertyId' => $currentpropid,
                'currentId' => $currentId
            ];
    
            if ($currentId === null) {
                unset($params['currentId']);
            }
    
            $opemailCount = fetchSingleDataWithJoins($opemailQuery, $params)['count'];
            $opuemailCount = fetchSingleDataWithJoins($opuemailQuery, $params)['count'];
    
            return $opemailCount + $opuemailCount === 0;
        } catch (Exception $e) {
            error_log("Error checking email uniqueness: " . $e->getMessage());
            return false;
        }
    }

    if (isset($_POST['getOperators'])) {

        if (!currentUserHasAccess($pdo, 'users', 'read') && ($_SESSION['layer'] === 'super_admin' || $_SESSION['layer'] === 'admin' || $_SESSION['layer'] === 'dealer' || $_SESSION['layer'] === 'sub_dealer' || $_SESSION['layer'] === 'organization admin' || $_SESSION['layer'] === 'property admin')) {
            echo json_encode(['error' => 'Access Denied']);
            exit();
        }
    
        $currentProperty = $_SESSION['property'];
    
        $primaryUsers = fetchData('property_users', ['property_id' => $currentProperty, 'deleted_at' => null]);
        $primaryUsersData = fetchData('property_users_data', ['property_id' => $currentProperty, 'deleted_at' => null]);

        $multiPropUsers = fetchData('multi_prop_users', ['property_id' => $currentProperty, 'deleted_at' => null]);

        $multiPropUserDetails = [];
        foreach ($multiPropUsers as $multiUser) {
            $propertyUser = fetchData('property_users', ['id' => $multiUser['user_assoc'], 'deleted_at' => null]);
            if (!empty($propertyUser)) {

                $propertyUserData = [
                    'id' => $propertyUser[0]['id'],
                    'email' => $propertyUser[0]['email'],
                ];

                $multiPropUserDetails[] = array_merge($multiUser, $propertyUserData);
            }
        }

        $uUsersData = [];
        foreach ($primaryUsers as $primaryUser) {
            foreach ($primaryUsersData as $primaryUserData) {
                if ($primaryUser['id'] === $primaryUserData['property_user']) {
                    $uUsersData[] = array_merge($primaryUser, $primaryUserData);
                }
            }
        }

        $uUsersData = array_merge($uUsersData, $multiPropUserDetails);

        $roles = fetchData('roles', []);
        $customRoles = fetchData('custom_roles', []);
    
        $rolesMapping = array_column($roles, 'name', 'id');
    
        $customRolesMapping = [];
        foreach ($customRoles as $customRole) {
            $layer = $customRole['layer'];
            $roleName = match ($layer) {
                'property' => 'property admin',
                'organization' => 'organization admin',
                'sub_dealer' => 'sub_dealer',
                'dealer' => 'dealer',
                'admin' => 'admin',
                'super_admin' => 'super_admin',
                default => $layer,
            };
            $customRolesMapping[$customRole['id']] = [
                'name' => $customRole['name'],
                'layer' => $roleName
            ];
        }

        $auditTrailData = fetchData('audit_trail_login', ['property_id' => $currentProperty]);
        $auditTrailMapping = [];
        foreach ($auditTrailData as $audit) {
            if ($audit['property_id'] == $currentProperty) {
                if ($audit['global_user_id']) {
                    $auditTrailMapping['users'][$audit['global_user_id']] = $audit['logged_time'];
                }
                if ($audit['property_user_id']) {
                    $auditTrailMapping['property_users'][$audit['property_user_id']] = $audit['logged_time'];
                }
            }
        }

        $filteredResults = array_map(function ($row) use ($rolesMapping, $customRolesMapping, $auditTrailMapping) {
            if (isset($row['role_type']) && $row['role_type'] == 0) {
                $roleName = $rolesMapping[$row['role']] ?? null;
                $layer = $roleName;
            } else {
                $roleName = $customRolesMapping[$row['role']]['name'] ?? null;
                $layer = $customRolesMapping[$row['role']]['layer'] ?? null;
            }
    
            $row['role_name'] = $roleName;
            $row['layer'] = $layer;

            if (isset($row['id'])) {
                $row['logged_time'] = $auditTrailMapping['property_users'][$row['id']] ?? 'Not yet Logged in';
            } elseif (isset($row['user_assoc'])) {
                $row['logged_time'] = $auditTrailMapping['users'][$row['user_assoc']] ?? 'Not yet Logged in';
            }
    
            return $row;
        }, $uUsersData);

        $filteredResults = array_filter($filteredResults, function ($row) {
            return !in_array($row['layer'], ['user', 'visitor']);
        });

        $streetData = fetchData('property_groups', ['property_id' => $currentProperty]);
        $streetMapping = [];
        foreach ($streetData as $street) {
            $streetMapping[$street['id']] = $street['name'];
        }
    
        foreach ($filteredResults as &$result) {
            if (isset($result['street']) && isset($streetMapping[$result['street']])) {
                $result['street'] = $streetMapping[$result['street']];
            }
            if (isset($result['photo_loc'])) {
                $photoData = fetchData('profile_photo', ['id' => $result['photo_loc']]);
                $result['photo_loc'] = !empty($photoData) ? $photoData[0]['location'] : null;
            }

            if (isset($result['created_by']) && isset($result['creator_type'])) {
                if($result['creator_type'] == "property_users"){
                    $created_by_data = fetchDataSingle('property_users_data', ['property_user' => $result['created_by']]);
                }
                else {
                    $created_by_data = fetchDataSingle($result['creator_type'], ['id' => $result['created_by']]);
                }
                $result['created_by_name'] = !empty($created_by_data) ? $created_by_data['firstname'] . " " . $created_by_data['lastname'] : null;
            }
        }

        echo json_encode(array_values($filteredResults));
        exit();
    } 

    if (isset($_POST['getDeleted'])) {

        if (!currentUserHasAccess($pdo, 'users', 'read') && ($_SESSION['layer'] === 'super_admin' || $_SESSION['layer'] === 'admin' || $_SESSION['layer'] === 'dealer' || $_SESSION['layer'] === 'sub_dealer' || $_SESSION['layer'] === 'organization admin' || $_SESSION['layer'] === 'property admin')) {
            echo json_encode(['error' => 'Access Denied']);
            exit();
        }
    
        $currentProperty = $_SESSION['property'];

        $deletedPropertyUsersData = fetchData('property_users_data', ['property_id' => $currentProperty, 'deleted_at' => ['IS NOT NULL']]);

        $deletedMultiPropUsers = fetchData('multi_prop_users', ['property_id' => $currentProperty, 'deleted_at' => ['IS NOT NULL']]);
    
        $allDeletedUsers = [];

        foreach ($deletedPropertyUsersData as $dataRow) {
            $propertyUser = fetchDataSingle('property_users', ['id' => $dataRow['property_user']]);
            if (!empty($propertyUser)) {
                $dataRow['email'] = $propertyUser['email'];
                $dataRow['status'] = $propertyUser['status'];
            }
            $allDeletedUsers[] = $dataRow;
        }
    
        foreach ($deletedMultiPropUsers as $multiUserRow) {
            $propertyUser = fetchDataSingle('property_users', ['id' => $multiUserRow['user_assoc']]);
            if (!empty($propertyUser)) {
                $multiUserRow['email'] = $propertyUser['email'];
                $multiUserRow['status'] = $propertyUser['status'];
            }
            $allDeletedUsers[] = $multiUserRow;
        }

        $roles = fetchData('roles', []);
        $customRoles = fetchData('custom_roles', []);
        $rolesMapping = array_column($roles, 'name', 'id');
    
        $customRolesMapping = [];
        foreach ($customRoles as $customRole) {
            $layer = $customRole['layer'];
            $roleName = match ($layer) {
                'property' => 'property admin',
                'organization' => 'organization admin',
                'sub_dealer' => 'sub_dealer',
                'dealer' => 'dealer',
                'admin' => 'admin',
                'super_admin' => 'super_admin',
                default => $layer,
            };
                $customRolesMapping[$customRole['id']] = [
                'name' => $customRole['name'],
                'layer' => $roleName
            ];
        }
    
        $finalResults = array_map(function ($row) use ($rolesMapping, $customRolesMapping) {
            if ($row['role_type'] == 0) {
                $row['role_name'] = $rolesMapping[$row['role']] ?? null;
            } else {
                $row['role_name'] = $customRolesMapping[$row['role']]['name'] ?? null;
                $row['layer'] = $customRolesMapping[$row['role']]['layer'] ?? null;
            }
    
            return $row;
        }, $allDeletedUsers);
    
        echo json_encode(array_values($finalResults));
        exit();
    }

    if (isset($_POST['editOperator'])) {

        if (!currentUserHasAccess($pdo, 'users', 'write')) {
            echo json_encode(['error' => 'Access Denied']);
            exit();
        }
    
        $userId = $_POST['userid'];
        $currentProperty = $_SESSION['property'];

        $multiPropEntry = fetchData('multi_prop_users', ['user_assoc' => $userId, 'property_id' => $currentProperty, 'status' => 'Active']);
    
        if (!empty($multiPropEntry)) {
            $editOperatorData = [
                'firstname' => $multiPropEntry[0]['firstname'],
                'lastname' => $multiPropEntry[0]['lastname'],
                'unit' => $multiPropEntry[0]['unit'],
                'street' => $multiPropEntry[0]['street'],
                'mobile_number' => $multiPropEntry[0]['mobile_number'],
                'home_number' => $multiPropEntry[0]['home_number'],
                'photo_loc' => $multiPropEntry[0]['photo_loc'],
                'role' => $multiPropEntry[0]['role'],
                'role_type' => $multiPropEntry[0]['role_type'],
                'status' => $multiPropEntry[0]['status'],
                'user_assoc' => $userId
            ];
        } else {

            $editOperatorData = fetchData('property_users_data', [
                'property_id' => $currentProperty,
                'property_user' => $userId,
                'deleted_at' => null
            ]);
    
            if (!empty($editOperatorData)) {
                $editOperatorData = [
                    'firstname' => $editOperatorData[0]['firstname'],
                    'lastname' => $editOperatorData[0]['lastname'],
                    'unit' => $editOperatorData[0]['unit'],
                    'street' => $editOperatorData[0]['street'],
                    'mobile_number' => $editOperatorData[0]['mobile_number'],
                    'home_number' => $editOperatorData[0]['home_number'],
                    'photo_loc' => $editOperatorData[0]['photo_loc'],
                    'role' => $editOperatorData[0]['role'],
                    'role_type' => $editOperatorData[0]['custom'],
                    'id' => $userId
                ];
            }
        }

        $editOperatorEmail = fetchData('property_users', ['id' => $userId]);
        if (!empty($editOperatorEmail)) {
            $editOperatorData['email'] = $editOperatorEmail[0]['email'];
            $editOperatorData['status'] = $editOperatorEmail[0]['status'];
        }
    
        echo json_encode($editOperatorData);
        exit();
    }

    if (isset($_POST['deleteOperator'])) {
        if (!currentUserHasAccess($pdo, 'users', 'delete')) {
            echo json_encode(['error' => 'Access Denied']);
            exit();
        }
    
        $operatorToDelete = $_POST['userid'];
        $propertyAssoc = $_POST['property'];

        if ($_SESSION['userid'] == $operatorToDelete) {
            echo "Current User";
            exit();
        }
    
        $conditions = [
            'id' => $operatorToDelete,
            'property_id' => $propertyAssoc,
            'deleted_at' => null
        ];
    
        $isPrimaryProperty = fetchDataSingle('property_users', $conditions);
    
        if ($isPrimaryProperty) {
            handlePrimaryPropertyDeletion($operatorToDelete, $propertyAssoc);
            $table_name = "property_users";
        } else {
            $isPrimaryProperty = fetchDataSingle('multi_prop_users', $conditions);
            softDeleteMultiPropertyUser($operatorToDelete, $propertyAssoc);
            $table_name = "multi_prop_users";
        }

        createAuditLog($_SESSION["userid"], "Deleted Operator", $table_name, $operatorToDelete, $_SESSION["email"]??null, $propertyAssoc, json_encode($isPrimaryProperty), null, "Deleted Operator", "high", $table_name);
    
        echo "Success";
        exit();
    
        // header("location: ../../dashboard.php?tab=users");
        // exit();
    }

    if (isset($_POST['updateOperatorsubmit'])) {

        if (!currentUserHasAccess($pdo, 'users', 'write')) {
            echo json_encode(['error' => 'Access Denied']);
            exit();
        }
    
        $oFName = $_POST['ofirstname'];
        $oLName = $_POST['olastname'];
        $oUnit = $_POST['ounit'];
        $oStreet = $_POST['ostreetList'];
        $oEmail = $_POST['oemail'];
        $oMobile = preg_replace('/\D/', '', $_POST['omobile']);
        $oHome = preg_replace('/\D/', '', $_POST['ohome']);
        $oId = $_POST['euidstore'];
        $currentProperty = $_SESSION['property'];

        $multiPropEntry = fetchData('multi_prop_users', ['user_assoc' => $oId, 'property_id' => $currentProperty, 'status' => 'Active']);
        $isMultiPropUser = !empty($multiPropEntry);
    
        // if (!isNumberUnique($oMobile, $oId)) {
        //     $_SESSION['alert']['message'] = "The Phone Number is already in use.";
        //     $_SESSION['alert']['type'] = "danger";
        //     header("Location: ../../dashboard.php?tab=users");
        //     exit();
        // }
    
        if (!isNumberUnique($oHome, $oId)) {
            $_SESSION['alert']['message'] = "The Phone Number is already in use.";
            $_SESSION['alert']['type'] = "danger";
            if (!headers_sent()) {
                header("Location: ../../dashboard.php?tab=users");
            }
            exit();
        }
    
        if (!isEmailUnique($oEmail, $oId)) {
            $_SESSION['alert']['message'] = "The Email Address is already in use.";
            $_SESSION['alert']['type'] = "danger";
            if (!headers_sent()) {
                header("Location: ../../dashboard.php?tab=users");
            }
            exit();
        }
    
        try {

            $updateData = [
                'firstname' => $oFName,
                'lastname' => $oLName,
                'unit' => $oUnit,
                'street' => $oStreet,
                'mobile_number' => $oMobile,
                'home_number' => $oHome
            ];

            if ($isMultiPropUser) {
                $user_data = fetchDataSingle('multi_prop_users', ['user_assoc' => $oId, 'property_id', $currentProperty]);
                $whereClause = 'user_assoc = :user_assoc AND property_id = :property_id';
                $whereParams = ['user_assoc' => $oId, 'property_id' => $currentProperty];
                updateTable('multi_prop_users', $updateData, $whereClause, $whereParams);

                $email_data_user = fetchDataSingle('property_users', ['id' => $oId]);
                $emailData = ['email' => $oEmail];
                updateTable('property_users', $emailData, 'id = :id', ['id' => $oId]);
                $table_name = "multi_prop_users";
            } else {
                $user_data = fetchDataSingle('property_users_data', ['property_user' => $oId]);
                $whereClause = 'property_user = :property_user';
                $whereParams = ['property_user' => $oId];
                updateTable('property_users_data', $updateData, $whereClause, $whereParams);
                $email_data_user = fetchDataSingle('property_users', ['id' => $oId]);
                $emailData = ['email' => $oEmail];
                updateTable('property_users', $emailData, 'id = :id', ['id' => $oId]);
                $table_name = "property_users_data";
            }

            if(isset($user_data['id']) && !empty($user_data['id'])){
                if($user_data['firstname'] != $oFName){
                    createAuditLog($_SESSION["userid"], "Udated Operator First Name", $table_name, $oId, $_SESSION["email"]??null, $currentProperty, $user_data['firstname'], $oFName, "Udated operator first name", "high", $table_name);
                }
                if($user_data['lastname'] != $oLName){
                    createAuditLog($_SESSION["userid"], "Udated Operator Last Name", $table_name, $oId, $_SESSION["email"]??null, $currentProperty, $user_data['lastname'], $oFName, "Udated operator last name", "high", $table_name);
                }
                if($user_data['unit'] != $oUnit){
                    createAuditLog($_SESSION["userid"], "Udated Operator Unit", $table_name, $oId, $_SESSION["email"]??null, $currentProperty, $user_data['unit'], $oUnit, "Udated operator unit", "high", $table_name);
                }
                if($user_data['street'] != $oStreet){
                    createAuditLog($_SESSION["userid"], "Udated Operator Street", $table_name, $oId, $_SESSION["email"]??null, $currentProperty, $user_data['street'], $oStreet, "Udated operator street", "high", $table_name);
                }
                if($user_data['mobile_number'] != $oMobile){
                    createAuditLog($_SESSION["userid"], "Udated Operator Mobile Number", $table_name, $oId, $_SESSION["email"]??null, $currentProperty, $user_data['mobile_number'], $oMobile, "Udated operator mobile number", "high", $table_name);
                }
                if($user_data['home_number'] != $oHome){
                    createAuditLog($_SESSION["userid"], "Udated Operator Home Number", $table_name, $oId, $_SESSION["email"]??null, $currentProperty, $user_data['home_number'], $oHome, "Udated operator home number", "high", $table_name);
                }
            }

            if(isset($email_data_user['id']) && !empty($email_data_user['id'])){
                if($email_data_user['email'] != $oEmail){
                    createAuditLog($_SESSION["userid"], "Udated Operator email", "property_users", $oId, $_SESSION["email"]??null, $currentProperty, $email_data_user['email'], $oEmail, "Udated operator email", "high", "property_users");
                }
            }

            $_SESSION['alert'] = [
                "message" => "The Operator has been updated successfully!",
                "type" => "success"
            ];
    
            if (!headers_sent()) {
                header("location: ../../dashboard.php?tab=users");
            }
            exit();
    
        } catch (Exception $e) {
            error_log("Error updating Operator: " . $e->getMessage());

            $_SESSION['alert'] = [
                "message" => "The Operator was not updated!",
                "type" => "danger"
            ];
            return false;
        }
    }