<?php
    // prevent direct file access
	if( !defined( 'ABSPATH' ) ) exit;
    
    function pixe_heartbeat_received($response, $data) {
        if( empty($data['pixe_type']) || empty($data['pixe_id']) ) return $response;

        $type = empty($data['pixe_type'])? '': $data['pixe_type'];
        $id = empty($data['pixe_id'])? '': intval($data['pixe_id']);

        // check status
        if( $type == 'post' ){
            $lock = wp_check_post_lock($id);
        }else{
            $lock = pixe_check_template_lock($id);
        }

        // check if locked by another user
        if( !empty($lock) ){
            $user = get_userdata($lock);

            $response['pixe_locked'] = true;
            $response['locked_by'] = $user->display_name;
            return $response;
        }

        // set lock for current user
        if( $type == 'post' ){
            wp_set_post_lock($id);
        }else{
            pixe_set_template_lock($id);
        }

        return $response;
    };
    add_filter('heartbeat_received', 'pixe_heartbeat_received', 10, 2); 

    // template lock function
    function pixe_set_template_lock($id){

        $user_id = get_current_user_id();
        $now  = time();
        $lock = "$now:$user_id";

        pixe_set_template_data(array(
            'id' => $id,
            'edit_lock' => $lock
        ));
    }
    function pixe_check_template_lock($id, $result = array()){
        global $wpdb;

        // get result from cache first
        if( empty($result) ){
            $cache_key = pixe_template_get_cache_key(array('select' => '', 'id' => $id));
            $result = wp_cache_get($cache_key, 'pixebuilder');
        }
        
        // get result from database
        if( empty($result) ){
            $result = $wpdb->get_row($wpdb->prepare("SELECT edit_lock FROM {$wpdb->prefix}pixetemplate WHERE id = %d", $id)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
            wp_cache_set($cache_key, $result, 'pixebuilder', DAY_IN_SECONDS);
        }

        // no user edit
        if( empty($result->edit_lock) ){
            return false;
        }
        
        $lock = explode(':', $result->edit_lock);
        $last_update = absint($lock[0]);
        $user_id = absint($lock[1]);
        
        // user away for a while
        if( $last_update < (time() - 150) ){
            return false;
        }

        // myself
        if( $user_id == get_current_user_id() ){
            return false;
        }

        return $user_id;
    }

    // take over function
    function pixe_ajax_heartbeat_take_over() {
        
        // security check
        if( !check_ajax_referer('pixe-editor', 'security', false) ){
            die(json_encode(array(
                'status' => 'failed',
                'head' => pixe_get_error_message('nonce-head'),
                'message' => pixe_get_error_message('nonce-message')
            )));
        }

        $type = empty($_POST['type'])? '': sanitize_text_field(wp_unslash($_POST['type']));
        $id = empty($_POST['id'])? '': absint(wp_unslash($_POST['id']));

        // check permission
        if( !current_user_can('edit_posts') ){
            die(json_encode(array(
                'status' => 'failed',
                'head' => pixe_get_error_message('permission-head'),
                'message' => pixe_get_error_message('permission-message')
            )));
        }

        // check data
        if( empty($type) ){
            die(json_encode(array(
                'status' => 'failed',
                'head' => pixe_get_error_message('invalid-format-head'),
                'message' => pixe_get_error_message('permission-message')
            )));
        }

        // lock post to current user
        if( $type == 'post' ){
            wp_set_post_lock($id);
        }else{
            pixe_set_template_lock($id);
        }

        die(json_encode(array(
            'status' => 'success'
        )));
    }
    add_action('wp_ajax_pixe_heartbeat_take_over', 'pixe_ajax_heartbeat_take_over');