<?php
/**
 * Nisje Reaction Class
 * Handles Reactions for objects.
 *
 * @TODO Add cache functionality for direct db calls.
 *
 * @package Nisje
 */

defined( 'ABSPATH' ) || die( 'Shame on you' );

// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery

/**
 * Reaction Class
 */
class Nisje_Reaction {
	/**
	 * The reaction ID.
	 *
	 * @var int
	 */
	public $id = 0;

	/**
	 * The object ID
	 *
	 * @var int
	 */
	public $object_id = 0;

	/**
	 * The user_id
	 *
	 * @var int
	 */
	public $user_id = 0;

	/**
	 * The object type
	 *
	 * @var string
	 */
	public $object_type = '';

	/**
	 * The reaction type id
	 *
	 * @var int
	 */
	public $reaction_type_id = 0;

	/**
	 * The date registered
	 *
	 * @var int
	 */
	public $date = '';

	/**
	 * Constructor
	 *
	 * @param int    $object_id        The object ID.
	 * @param int    $user_id          The user ID.
	 * @param string $object_type      Object Type.
	 * @param int    $reaction_type_id Reaction type ID.
	 */
	public function __construct( $object_id = 0, $user_id = 0, $object_type = '', $reaction_type_id ) {
		if ( ! empty( $object_id ) && ! empty( $user_id ) && ! empty( $object_type ) && ! empty( $reaction_type_id ) ) {
			$this->object_id        = (int) $object_id;
			$this->user_id          = (int) $user_id;
			$this->object_type      = sanitize_key( $object_type );
			$this->reaction_type_id = (int) $reaction_type_id;

			$this->populate();
		}
	}

	/**
	 * Populate method.
	 *
	 * Used in constructor.
	 */
	protected function populate() {
		global $wpdb;

		$reaction_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$wpdb->nisje_reactions} WHERE object_id = %d AND user_id = %d AND object_type = %s AND reaction_type_id = %d", $this->object_id, $this->user_id, $this->object_type, $this->reaction_type_id ) );
		if ( $reaction_id ) {
			$this->id = $reaction_id;
		}
	}

	/**
	 * Saves attending
	 */
	public function save() {
		global $wpdb;

		if ( empty( $this->object_id ) || empty( $this->user_id ) || empty( $this->object_type ) || empty( $this->reaction_type_id ) ) {
			return false;
		}

		// Update existing entry.
		if ( $this->id ) {
			$result = $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->nisje_reactions} SET object_id = %d, user_id = %d, object_type = %s, reaction_type_id = %d, date_modified = %s WHERE id = %d", $this->object_id, $this->user_id, $this->object_type, $this->reaction_type_id, current_time( 'mysql' ), $this->id ) );
		} else {
			$result   = $wpdb->query( $wpdb->prepare( "INSERT INTO {$wpdb->nisje_reactions} ( object_id, user_id, object_type, reaction_type_id, date_created ) VALUES ( %d, %d, %s, %d, %s )", $this->object_id, $this->user_id, $this->object_type, $this->reaction_type_id, current_time( 'mysql' ) ) );
			$this->id = $wpdb->insert_id;
		}

		return $result;
	}

	/**
	 * Deletes from database
	 */
	public function delete() {
		global $wpdb;

		return $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->nisje_reactions} WHERE id = %d", $this->id ) );
	}

	/**
	 * Get reactions for specific user
	 *
	 * @param int $user_id The user ID.
	 * @return array
	 */
	public static function get_reactions_connected_to_user( $user_id ) {
		global $wpdb;

		$reactions = $wpdb->get_results( $wpdb->prepare( "SELECT object_id, object_type, reaction_type_id FROM {$wpdb->nisje_reactions} WHERE user_id = %d", $user_id ) );

		return [
			'reactions' => $reactions,
			'total'     => count( $reactions ),
		];
	}

	/**
	 * Get reactions for a object
	 *
	 * @param int    $object_id   The object ID.
	 * @param string $object_type The object type.
	 * @return array
	 */
	public static function get_reactions_connected_to_object( $object_id, $object_type ) {
		global $wpdb;

		$reactions = $wpdb->get_results( $wpdb->prepare( "SELECT user_id FROM {$wpdb->nisje_reactions} WHERE object_id = %d AND object_type = %s", $object_id, $object_type ) );

		return [
			'total'   => count( $reactions ),
			'reacted' => nisje_user_has_reacted( strval( get_current_user_id() ), $reactions ),
		];
	}

	/**
	 * Deletes all reactions for a specific user
	 *
	 * @param int $user_id The user ID.
	 */
	public static function delete_all_for_user( $user_id ) {
		global $wpdb;

		$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->nisje_reactions} WHERE user_id = %d", $user_id ) );
	}
}
