<?php
/**
 * Authentication Details Model
 *
 * @package    MOMCS_Sync
 * @subpackage MOMCS_Sync/includes/common/models
 * @author     miniOrange
 */

declare(strict_types=1);

namespace MOMCS_Sync\Includes\Common\Models;

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

/**
 * Class for handling authentication details data.
 *
 * This model manages the momcs_authentication_details table which stores
 * authentication credentials separate from the main channel data.
 */
class Authentication_Details_Model {

	/**
	 * DB table name with prefix.
	 *
	 * @var string
	 */
	private string $table_name;

	/**
	 * Constructor.
	 */
	public function __construct() {
		global $wpdb;
		$this->table_name = $wpdb->prefix . 'momcs_authentication_details';
	}

	/**
	 * Create the authentication details table if it doesn't exist.
	 *
	 * @return void
	 */
	public static function create_table(): void {
		global $wpdb;

		$wpdb->query( //phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange -- Custom table creation.
			"CREATE TABLE IF NOT EXISTS {$wpdb->prefix}momcs_authentication_details (
				id mediumint(9) NOT NULL AUTO_INCREMENT,
				uuid varchar(36) NOT NULL,
				authentication longtext NOT NULL,
				created_at datetime DEFAULT NULL,
				updated_at datetime DEFAULT NULL,
				PRIMARY KEY (id),
				UNIQUE KEY uuid (uuid)
			);"
		);
	}

	/**
	 * Get authentication details by channel UUID.
	 *
	 * @param string $uuid Channel UUID.
	 * @return array|null Authentication data or null if not found.
	 */
	public function get_auth_by_uuid( string $uuid ): ?array {
		global $wpdb;

		return $wpdb->get_row( //phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange -- Always the latest data is required from database.
			$wpdb->prepare(
				"SELECT * FROM {$wpdb->prefix}momcs_authentication_details WHERE uuid = %s LIMIT 1",
				$uuid
			),
			ARRAY_A
		);
	}

	/**
	 * Add new authentication details.
	 *
	 * @param array $data Authentication data.
	 * @return bool True on success, false on failure.
	 */
	public function add_auth_details( array $data ): bool {
		global $wpdb;

		$result = $wpdb->insert( $this->table_name, $data ); //phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange -- Always the latest data is required from database.
		return false !== $result;
	}

	/**
	 * Update authentication details by UUID.
	 *
	 * @param string $uuid Channel UUID.
	 * @param array  $data Authentication data.
	 * @return bool True on success, false on failure.
	 */
	public function update_auth_details( string $uuid, array $data ): bool {
		global $wpdb;

		$result = $wpdb->update( //phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange -- Always the latest data is required from database.
			$this->table_name,
			$data,
			array( 'uuid' => $uuid )
		);
		return false !== $result;
	}

	/**
	 * Update or create authentication details.
	 *
	 * @param string $uuid Channel UUID.
	 * @param array  $data Authentication data.
	 * @return bool True on success, false on failure.
	 */
	public function update_or_create_auth_details( string $uuid, array $data ): bool {
		$existing = $this->get_auth_by_uuid( $uuid );

		if ( $existing ) {
			return $this->update_auth_details( $uuid, $data );
		} else {
			return $this->add_auth_details( $data );
		}
	}

	/**
	 * Delete authentication details by UUID.
	 *
	 * @param string $uuid Channel UUID.
	 * @return bool True on success, false on failure.
	 */
	public function delete_auth_details( string $uuid ): bool {
		global $wpdb;

		$result = $wpdb->delete( //phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange -- Always the latest data is required from database.
			$this->table_name,
			array( 'uuid' => $uuid )
		);
		return false !== $result;
	}

	/**
	 * Get authentication token by channel UUID.
	 *
	 * @param string $uuid Channel UUID.
	 * @return string|null Authentication token or null if not found.
	 */
	public function get_auth_token_by_uuid( string $uuid ): ?string {
		global $wpdb;

		return $wpdb->get_var( //phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange -- Always the latest data is required from database.
			$wpdb->prepare(
				"SELECT authentication FROM {$wpdb->prefix}momcs_authentication_details WHERE uuid = %s LIMIT 1",
				$uuid
			)
		);
	}

	/**
	 * Check if authentication details exist for a channel.
	 *
	 * @param string $uuid Channel UUID.
	 * @return bool True if exists, false otherwise.
	 */
	public function auth_exists( string $uuid ): bool {
		global $wpdb;

		return (bool) $wpdb->get_var( //phpcs:ignore WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange -- Always the latest data is required from database.
			$wpdb->prepare(
				"SELECT COUNT(*) FROM {$wpdb->prefix}momcs_authentication_details WHERE uuid = %s",
				$uuid
			)
		);
	}
}
