<?php
namespace Smart_Media_Cleanup;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class Logger {

	const TABLE_VERSION_KEY = 'smc_db_version';
	const TABLE_VERSION     = '1.0';

	public function __construct() {
		add_action( 'smc_daily_purge', array( $this, 'purge_old' ) );

		if ( ! wp_next_scheduled( 'smc_daily_purge' ) ) {
			wp_schedule_event( time(), 'daily', 'smc_daily_purge' );
		}
	}

	public static function install_table() {
		global $wpdb;

		$table      = $wpdb->prefix . 'smc_log';
		$charset    = $wpdb->get_charset_collate();

		$sql = "CREATE TABLE IF NOT EXISTS {$table} (
			id            BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
			created_at    DATETIME        NOT NULL,
			event_type    VARCHAR(50)     NOT NULL,
			post_id       BIGINT UNSIGNED NULL,
			attachment_id BIGINT UNSIGNED NOT NULL,
			attachment_url TEXT           NULL,
			message       TEXT           NULL,
			PRIMARY KEY (id),
			KEY created_at (created_at),
			KEY event_type (event_type)
		) {$charset};";

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

		update_option( self::TABLE_VERSION_KEY, self::TABLE_VERSION );
	}

	public function log( $event_type, $attachment_id, $post_id = null, $message = '' ) {
		$settings = Plugin::instance()->get_settings()->get();
		if ( empty( $settings['enable_log'] ) ) {
			return;
		}

		global $wpdb;
		$table = esc_sql( $wpdb->prefix . 'smc_log' );

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
		$wpdb->insert(
			$table,
			array(
				'created_at'    => current_time( 'mysql' ),
				'event_type'    => sanitize_key( $event_type ),
				'post_id'       => $post_id ? absint( $post_id ) : null,
				'attachment_id' => absint( $attachment_id ),
				'attachment_url'=> wp_get_attachment_url( $attachment_id ) ?: '',
				'message'       => sanitize_text_field( $message ),
			),
			array( '%s', '%s', '%d', '%d', '%s', '%s' )
		);
	}

	public function get_entries( $args = array() ) {
		global $wpdb;
		$table = esc_sql( $wpdb->prefix . 'smc_log' );

		$defaults = array(
			'per_page'   => 50,
			'page'       => 1,
			'event_type' => '',
			'date_from'  => '',
			'date_to'    => '',
		);
		$args = wp_parse_args( $args, $defaults );

		$where  = array( '1=1' );
		$values = array();

		if ( ! empty( $args['event_type'] ) ) {
			$where[]  = 'event_type = %s';
			$values[] = $args['event_type'];
		}

		if ( ! empty( $args['date_from'] ) ) {
			$where[]  = 'created_at >= %s';
			$values[] = $args['date_from'] . ' 00:00:00';
		}

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

		$where_clause = implode( ' AND ', $where );
		$offset       = ( absint( $args['page'] ) - 1 ) * absint( $args['per_page'] );
		$limit        = absint( $args['per_page'] );

		if ( ! empty( $values ) ) {
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery,WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber,PluginCheck.Security.DirectDB.UnescapedDBParameter
			$results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE {$where_clause} ORDER BY created_at DESC LIMIT %d OFFSET %d", array_merge( $values, array( $limit, $offset ) ) ) );
		} else {
			// phpcs:ignore WordPress.DB.DirectDatabaseQuery,WordPress.DB.PreparedSQL.InterpolatedNotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter
			$results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$table} WHERE {$where_clause} ORDER BY created_at DESC LIMIT %d OFFSET %d", $limit, $offset ) );
		}

		return $results ?: array();
	}

	public function purge_old() {
		$settings = Plugin::instance()->get_settings()->get();
		$days     = absint( $settings['log_retention_days'] ?? 30 );

		global $wpdb;
		$table = esc_sql( $wpdb->prefix . 'smc_log' );
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		$wpdb->query( $wpdb->prepare( "DELETE FROM {$table} WHERE created_at < DATE_SUB(NOW(), INTERVAL %d DAY)", $days ) );
	}

	public function clear() {
		global $wpdb;
		$table = esc_sql( $wpdb->prefix . 'smc_log' );
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		$wpdb->query( "TRUNCATE TABLE `{$table}`" );
	}

	public function count_entries( $args = array() ) {
		global $wpdb;
		$table = esc_sql( $wpdb->prefix . 'smc_log' );
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
		return (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$table}" );
	}
}
