<?php
/**
 * Chat repository for member communication.
 *
 * @package KGV\VereinManager
 */

namespace KGV\VereinManager\Repositories;

use KGV\VereinManager\Schema;

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

class ChatRepository extends AbstractRepository {

	/**
	 * Resolve table name.
	 *
	 * @return string
	 */
	protected function resolve_table() {
		return Schema::table( 'chat_messages' );
	}

	/**
	 * Get recent chat messages for one room.
	 *
	 * @param string $room_key Room key.
	 * @param int    $limit    Maximum result count.
	 * @param int    $after_id Optional lower ID boundary for polling.
	 * @return array
	 */
	public function get_recent_messages( $room_key, $limit = 60, $after_id = 0 ) {
		$users    = $this->wpdb->users;
		$room_key = sanitize_key( $room_key );
		$limit    = max( 1, min( 200, absint( $limit ) ) );
		$after_id = absint( $after_id );

		if ( $after_id > 0 ) {
			$sql = "SELECT m.*, u.display_name
				FROM {$this->table} m
				LEFT JOIN {$users} u ON u.ID = m.user_id
				WHERE m.room_key = %s AND m.id > %d
				ORDER BY m.id ASC
				LIMIT %d";

			return $this->wpdb->get_results( $this->wpdb->prepare( $sql, $room_key, $after_id, $limit ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
		}

		$sql = "SELECT *
			FROM (
				SELECT m.*, u.display_name
				FROM {$this->table} m
				LEFT JOIN {$users} u ON u.ID = m.user_id
				WHERE m.room_key = %s
				ORDER BY m.id DESC
				LIMIT %d
			) recent_messages
			ORDER BY id ASC";

		return $this->wpdb->get_results( $this->wpdb->prepare( $sql, $room_key, $limit ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
	}

	/**
	 * Store one new message.
	 *
	 * @param string $room_key Room key.
	 * @param int    $user_id  Sender user ID.
	 * @param string $message  Message body.
	 * @return object|null
	 */
	public function save_message( $room_key, $user_id, $message ) {
		$room_key = sanitize_key( $room_key );
		$user_id  = absint( $user_id );
		$message  = trim( sanitize_textarea_field( $message ) );

		if ( '' === $room_key || $user_id < 1 || '' === $message ) {
			return null;
		}

		$result = $this->wpdb->insert(
			$this->table,
			array(
				'room_key'   => $room_key,
				'user_id'    => $user_id,
				'message'    => $message,
				'created_at' => $this->now(),
			),
			array( '%s', '%d', '%s', '%s' )
		);

		if ( false === $result ) {
			return null;
		}

		return $this->find_with_author( (int) $this->wpdb->insert_id );
	}

	/**
	 * Find one message together with the author's display name.
	 *
	 * @param int $id Message ID.
	 * @return object|null
	 */
	private function find_with_author( $id ) {
		$users = $this->wpdb->users;
		$sql   = "SELECT m.*, u.display_name
			FROM {$this->table} m
			LEFT JOIN {$users} u ON u.ID = m.user_id
			WHERE m.id = %d
			LIMIT 1";

		return $this->wpdb->get_row( $this->wpdb->prepare( $sql, absint( $id ) ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
	}
}
