<?php
/**
 * Handles the creation, reading, and writing of Work Log events.
 *
 * @package MediaTasker
 */

// Prevent direct file access.
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Class Mediat_Work_Log
 */
class Mediat_Work_Log
{
    /**
     * Get the name of the custom table.
     *
     * @return string
     */
    public static function get_table_name()
    {
        global $wpdb;
        return $wpdb->prefix . 'mediat_work_logs';
    }

    /**
     * Create the custom database table for Work Logs.
     * Uses dbDelta to ensure table is created/updated safely.
     *
     * @return void
     */
    public static function create_table()
    {
        global $wpdb;

        $table_name = self::get_table_name();
        $charset_collate = $wpdb->get_charset_collate();

        $sql = "CREATE TABLE $table_name (
            id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
            task_id bigint(20) unsigned NOT NULL,
            user_id bigint(20) unsigned NOT NULL DEFAULT 0,
            action_type varchar(50) NOT NULL,
            details text,
            created_at datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
            PRIMARY KEY  (id),
            KEY task_id (task_id),
            KEY user_id (user_id),
            KEY action_type (action_type),
            KEY created_at (created_at)
        ) $charset_collate;";

        require_once ABSPATH . 'wp-admin/includes/upgrade.php';
        dbDelta($sql);
    }

    /**
     * Insert a new log entry.
     *
     * @param int    $task_id     The ID of the task post.
     * @param string $action_type The type of action (e.g., upload, status_change).
     * @param array  $details     Optional extra details to store as JSON.
     * @param int    $user_id     Optional user ID. Defaults to current user.
     * @return int|false The ID of the inserted row, or false on error.
     */
    public static function insert_log($task_id, $action_type, $details = array(), $user_id = null)
    {
        global $wpdb;

        if (null === $user_id) {
            $user_id = get_current_user_id();
        }

        $data = array(
            'task_id' => $task_id,
            'user_id' => $user_id,
            'action_type' => sanitize_text_field($action_type),
            'details' => wp_json_encode($details),
            'created_at' => current_time('mysql'),
        );

        $format = array('%d', '%d', '%s', '%s', '%s');

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
        $inserted = $wpdb->insert(self::get_table_name(), $data, $format);

        if ($inserted) {
            return $wpdb->insert_id;
        }

        return false;
    }

    /**
     * Retrieve logs with optional filtering and pagination.
     *
     * @param array $args Arguments for fetching logs (limit, offset, dates, user_id, action_type).
     * @return array Object array of logs.
     */
    public static function get_logs($args = array())
    {
        global $wpdb;
        $table = self::get_table_name();

        $query = "SELECT * FROM `{$table}` WHERE 1=1";
        $values = array();

        if (!empty($args['task_id'])) {
            $query .= " AND task_id = %d";
            $values[] = intval($args['task_id']);
        }

        if (!empty($args['user_id'])) {
            $query .= " AND user_id = %d";
            $values[] = intval($args['user_id']);
        }

        if (!empty($args['action_type'])) {
            $query .= " AND action_type = %s";
            $values[] = sanitize_text_field(wp_unslash($args['action_type']));
        }

        if (!empty($args['date_from'])) {
            $query .= " AND created_at >= %s";
            $values[] = sanitize_text_field(wp_unslash($args['date_from'])) . ' 00:00:00';
        }

        if (!empty($args['date_to'])) {
            $query .= " AND created_at <= %s";
            $values[] = sanitize_text_field(wp_unslash($args['date_to'])) . ' 23:59:59';
        }

        $limit = isset($args['limit']) ? absint($args['limit']) : 20;
        $offset = isset($args['offset']) ? absint($args['offset']) : 0;

        $query .= " ORDER BY created_at DESC LIMIT %d OFFSET %d";
        $values[] = $limit;
        $values[] = $offset;

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
        return $wpdb->get_results($wpdb->prepare($query, $values));
    }

    /**
     * Get the total count of logs matching parameters.
     *
     * @param array $args Same filter arguments as get_logs.
     * @return int Count of logs.
     */
    public static function get_total_logs($args = array())
    {
        global $wpdb;
        $table = self::get_table_name();

        $query = "SELECT COUNT(id) FROM `{$table}` WHERE 1=1";
        $values = array();

        if (!empty($args['task_id'])) {
            $query .= " AND task_id = %d";
            $values[] = intval($args['task_id']);
        }

        if (!empty($args['user_id'])) {
            $query .= " AND user_id = %d";
            $values[] = intval($args['user_id']);
        }

        if (!empty($args['action_type'])) {
            $query .= " AND action_type = %s";
            $values[] = sanitize_text_field(wp_unslash($args['action_type']));
        }

        if (!empty($args['date_from'])) {
            $query .= " AND created_at >= %s";
            $values[] = sanitize_text_field(wp_unslash($args['date_from'])) . ' 00:00:00';
        }

        if (!empty($args['date_to'])) {
            $query .= " AND created_at <= %s";
            $values[] = sanitize_text_field(wp_unslash($args['date_to'])) . ' 23:59:59';
        }

        if (empty($values)) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
            return (int) $wpdb->get_var("SELECT COUNT(id) FROM `{$table}`");
        }

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter
        return (int) $wpdb->get_var($wpdb->prepare($query, $values));
    }
}
