<?php
if (!defined('ABSPATH')) exit;

class ASSI_Heartbeat {

    private static $instance = null;

    public static function getInstance() {
        if (null === self::$instance) {
            self::$instance = new self;
        }
        return self::$instance;
    }

    public function init($response, $data) {
        if (isset($data['ass_heartbeat_actions']) && is_array($data['ass_heartbeat_actions']) && !empty($data['ass_heartbeat_actions'])) {
            foreach ($data['ass_heartbeat_actions'] as $action) {
                if (method_exists($this, $action)) {
                    $actionResult = $this->$action();
                    if (is_array($actionResult) && !empty($actionResult)) {
                        $response = array_merge($response, $actionResult);
                    }
                }
            }
        }
        return $response;
    }

    private function ass_notifications() {
        global $wpdb;
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
        $dbResult = $wpdb->get_results($wpdb->prepare("SELECT * FROM `{$wpdb->prefix}assi_user_notifications` WHERE `blog_user_id` = %d AND `type` NOT LIKE %s", (defined('ASSI_PLUGIN_BLOG_USER_ID') ? (int) ASSI_PLUGIN_BLOG_USER_ID : 0), 'editor'));
        $existingIds = array();
        if (is_array($dbResult) && !empty($dbResult)) {
            $existingIds = array_column($dbResult, 'notification_id');
        }
        $data = array(
            'blog_user_token' => ASSI_PLUGIN_BLOG_USER_TOKEN
        );
        $result = ASSI_Request::post(ASSI_PLUGIN_API_WP_ENDPOINT . 'notification/get', $data);
        $newNotificationsInsert = array();
        if (isset($result->status) && $result->status == 'success' && isset($result->notifications) && !empty($result->notifications)) {
            $wpDateFormat = get_option('date_format');
            $wpTimeFormat = get_option('time_format');

            $returnResult = array();
            foreach ($result->notifications as $index => $notification) {
                $insertDate = $notification->create_date;
                $wpDate = wp_date($wpDateFormat . ' ' . $wpTimeFormat, strtotime($notification->create_date));
                if ($wpDate != false) {
                    $result->notifications[$index]->create_date = $wpDate;
                }
                if (in_array($notification->notification_id, $existingIds)) {
                    $unset = true;
                    $searchId = (int) $notification->notification_id;
                    $item = array_filter($dbResult, function ($entry) use ($searchId) {
                        return $entry->notification_id == $searchId;
                    });
                    $item = reset($item) ?: null;
                    if (isset($item) && !empty($item) && isset($item->status)) {
                        if ((int) $notification->status != (int) $item->status) {
                            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
                            $wpdb->query($wpdb->prepare("UPDATE `{$wpdb->prefix}assi_user_notifications` SET `status` = %d WHERE `notification_id` = %d", (int) $notification->status, (int) $notification->notification_id));
                            $unset = false;
                        }
                    }
                    if ($unset) {
                        unset($result->notifications[$index]);
                    } else {
                        $returnResult[] = $result->notifications[$index];
                    }
                } else {
                    $returnResult[] = $result->notifications[$index];
                    $newNotificationsInsert[] = array(
                        'notification_id' => (int) $notification->notification_id,
                        'blog_user_id' => defined('ASSI_PLUGIN_BLOG_USER_ID') ? (int) ASSI_PLUGIN_BLOG_USER_ID : 0,
                        'type' => sanitize_text_field($notification->type),
                        'request_id' => sanitize_text_field($notification->request_id),
                        'status' => (int) $notification->status,
                        'create_date' => sanitize_text_field($insertDate),
                        'notification_data' => json_encode($notification->notification_data)
                    );
                }
            }
            if (!empty($newNotificationsInsert)) {
                foreach ($newNotificationsInsert as $entry) {
                    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
                    $wpdb->query($wpdb->prepare("INSERT INTO `{$wpdb->prefix}assi_user_notifications` (`notification_id`, `blog_user_id`, `type`, `request_id`, `status`, `create_date`, `notification_data`) VALUES (%d, %d, %s, %s, %d, %s, %s)", $entry['notification_id'], $entry['blog_user_id'], $entry['type'], $entry['request_id'], $entry['status'], $entry['create_date'], $entry['notification_data']));
                }
            }
            return array('ass_notifications' => $returnResult);
        }
        return array();
    }
    
    private function ass_editor_notifications() {
        global $wpdb;
        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
        $dbResult = $wpdb->get_results($wpdb->prepare("SELECT * FROM `{$wpdb->prefix}assi_user_notifications` WHERE `blog_user_id` = %d AND `type` = %s AND `status` = %d", (defined('ASSI_PLUGIN_BLOG_USER_ID') ? (int) ASSI_PLUGIN_BLOG_USER_ID : 0), 'editor', 0));
        $existingIds = array();
        if (is_array($dbResult) && !empty($dbResult)) {
            $existingIds = array_column($dbResult, 'notification_id');
        }
        if (!is_array($existingIds) || empty($existingIds)) {
            return array('ass_heartbeat_stop' => true);
        }
        foreach ($existingIds as $i => $id) {
            $existingIds[$i] = (int) $id;
        }
        $data = array(
            'blog_user_token' => ASSI_PLUGIN_BLOG_USER_TOKEN,
            'notification_id' => $existingIds
        );
        $result = ASSI_Request::post(ASSI_PLUGIN_API_WP_ENDPOINT . 'notification/status', $data);
        $update = false;
        if (isset($result->status) && $result->status == 'success' && isset($result->notifications) && !empty($result->notifications)) {
            foreach ($result->notifications as $index => $notification) {
                if (in_array((int) $index, $existingIds) && isset($notification->status) && (int) $notification->status > 0 && isset($notification->notification_data)) {
                    $dbNotificationData = json_decode(array_values(array_filter($dbResult, function ($entry) use ($index) {return $entry->notification_id == $index;}))[0]->notification_data, true);
                    $itemNotificationData = (array) $notification->notification_data;
                    $finalNotificationData = array_merge($dbNotificationData, $itemNotificationData);
                    // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
                    $wpdb->query(
                        $wpdb->prepare(
                            "UPDATE `{$wpdb->prefix}assi_user_notifications` SET `status` = %d, `notification_data` = %s, `create_date` = %s WHERE `notification_id` = %d",
                            (int) $notification->status,
                            wp_json_encode($finalNotificationData),
                            gmdate('Y-m-d H:i:s', time()),
                            (int) $index
                        )
                    );
                    if ((int) $notification->status == 1 && defined('ASSI_ACCOUNT_PLAN_ID') && (int) ASSI_ACCOUNT_PLAN_ID > 1) {
                        ASSI_History::convertNotificationToEntry($notification->request_id);
                    }
                    $update = true;
                }
            }
        }
        return array('ass_notification_update' => $update);
    }
}
