<?php

namespace ARCHM\Features;

class ActivityLogDB {

    // phpcs:ignore PHPCompatibility.Classes.NewTypedProperties.Found
    protected \QM_DB|\wpdb $wpdb;
    // phpcs:ignore PHPCompatibility.Classes.NewTypedProperties.Found
    protected string $table_name;
    // phpcs:ignore PHPCompatibility.Classes.NewTypedProperties.Found
    protected string $users_table;

    public function __construct() {
        global $wpdb;
        $this->wpdb = $wpdb;
        $this->table_name = "{$wpdb->prefix}archm_activity_log";
        $this->users_table = "{$wpdb->prefix}users";
    }

    /**
     * Create the database table.
     *
     * @return void The user activity logs.
     * @since 1.0
     * @author Siam Maruf
     */
    // phpcs:ignore PHPCompatibility.FunctionDeclarations.NewReturnTypeDeclarations.voidFound
    public function create_table(): void {
        $charset_collate = $this->wpdb->get_charset_collate();

        $sql = "CREATE TABLE IF NOT EXISTS $this->table_name (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            user_id mediumint(9) NOT NULL,
            activity text NOT NULL,
            activity_time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
            PRIMARY KEY  (id)
        ) $charset_collate;";

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

    /**
     * Insert data into the database.
     *
     * @param array $data The data to be inserted.
     *
     * @since 1.0
     * @author Siam Maruf
     */
    // phpcs:ignore PHPCompatibility.FunctionDeclarations.NewReturnTypeDeclarations.arrayFound
    public function insert_log( $data ): array {
        $response = [
			'success' => true,
			'message' => 'Log inserted successfully.',
		];

        $activity = isset($data['activity']) ? sanitize_text_field($data['activity']) : '';
        if ( empty($activity) ) {
            $response['success'] = false;
            $response['message'] = 'Activity is required.';
            return $response;
        }

        $current_user = wp_get_current_user();
        $saved_user_id = get_option('_archm_archive_user');
        $user_id = is_user_logged_in() ? $current_user->ID : $saved_user_id;
        $activity_time = current_time('mysql');

        $data = array(
            'user_id' => (int) $user_id,
            'activity' => $data['activity'],
            'activity_time' => $activity_time,
        );

        $success = $this->wpdb->insert($this->table_name, $data);
        if ( false === $success ) {
            $response['success'] = false;
            $response['message'] = 'Failed to insert log inserted data';
        }
        return $response;
    }

    /**
     * Retrieve user activity logs from the database.
     *
     * @return array|object|null The user activity logs.
     * @since 1.0
     * @author Siam Maruf
     */
    // phpcs:ignore PHPCompatibility.FunctionDeclarations.NewReturnTypeDeclarations.objectFound
    public function get_logs(): array|object|null {

        $query = $this->wpdb->prepare('SELECT * FROM %i ORDER BY activity_time DESC', $this->table_name); // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder

        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
        return $this->wpdb->get_results($query);
    }

    /**
     * Get Orders By page
     *
     * @param int $page
     * @param int $per_page
     *
     * @return array|object|null
     * @since 1.0
     * @author Siam Maruf
     */
    // phpcs:ignore PHPCompatibility.FunctionDeclarations.NewReturnTypeDeclarations.objectFound
    public function get_logs_by_page( $page = 1, $per_page = 20 ): array|object|null {
        $offset = ( $page - 1 ) * $per_page;
        $users_table = $this->users_table;
        $response = [];

        // Get total length of logs
        $total_logs_query = $this->wpdb->prepare('SELECT COUNT(*) AS total_logs FROM %i WHERE %d', $this->table_name, 1); // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder
        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
        $total_logs_result = $this->wpdb->get_row($total_logs_query);
        $total_logs = $total_logs_result->total_logs;

        // Fetch logs with pagination
        $query = $this->wpdb->prepare("SELECT l.*, u.display_name,DATE_FORMAT(l.activity_time, '%%M %%e, %%Y') AS activity_date, DATE_FORMAT(CONVERT_TZ(l.activity_time, '+00:00', @@global.time_zone), '%%h:%%i %%p') AS activity_time FROM %i AS l LEFT JOIN %i AS u ON l.user_id = u.ID ORDER BY l.activity_time DESC LIMIT %d, %d", $this->table_name, $users_table, $offset, $per_page); // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder

        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
        $logs = $this->wpdb->get_results($query);

        if ( $logs ) {
            $logs = array_map(function ( $log ) {
                $log->user_image_url = get_avatar_url($log->user_id);
                return $log;
            }, $logs);

            $response['success'] = true;
            $response['logs'] = $logs;
            $response['length'] = $total_logs;
        } else {
            $response['success'] = false;
            $response['message'] = 'No logs found';
            $response['length'] = 0;
        }

        return $response;
    }

    /**
     * Delete activity logs by IDs.
     *
     * @param array $log_ids The IDs of the logs to be deleted.
     *
     * @return array Response message.
     * @since 1.0
     * @author Siam Maruf
     */
    // phpcs:ignore PHPCompatibility.FunctionDeclarations.NewReturnTypeDeclarations.arrayFound
    public function delete_logs( array $log_ids ): array {
        $response = [
			'success' => true,
			'message' => 'Logs deleted successfully.',
		];
        if ( empty($log_ids) ) {
            $response['success'] = false;
            $response['message'] = 'Log IDs are required for deletion.';
            return $response;
        }

        $placeholders = implode(',', array_map('intval', $log_ids));
        // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder
        $sql = $this->wpdb->prepare("DELETE FROM %i WHERE id IN ({$placeholders})", $this->table_name);
        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
        $success = $this->wpdb->query($sql);

        if ( false === $success ) {
            $response['success'] = false;
            $response['message'] = 'Failed to delete logs.';
        }

        return $response;
    }
}
