<?php

namespace WC_Affiliate\Traits;

use WC_Affiliate\Models\Affiliate;
use WP_Error;
use WP_REST_Request;

defined( 'ABSPATH' ) || exit;

/**
 * Trait Auth
 *
 * This trait provides methods to check the current user's roles and statuses in the WordPress plugin.
 *
 * @package WC_Affiliate
 */
trait Auth {

	/**
	 * Check if the current user is a logged-in member.
	 *
	 * @param WP_REST_Request $request The current request.
	 *
	 * @return bool True if the user is logged in, false otherwise.
	 */
	public function is_member( WP_REST_Request $request ): bool {
		return is_user_logged_in();
	}

	/**
	 * Check if the current user has administrator capabilities.
	 *
	 * @param WP_REST_Request $request The current request.
	 *
	 * @return bool True if the user has administrator capabilities, false otherwise.
	 */
	public function is_admin( WP_REST_Request $request ): bool {
		return current_user_can( 'manage_options' );
	}

	/**
	 * Check if the current user has editor capabilities.
	 *
	 * @param WP_REST_Request $request The current request.
	 *
	 * @return bool True if the user has editor capabilities, false otherwise.
	 */
	public function is_editor( WP_REST_Request $request ): bool {
		return current_user_can( 'edit_others_posts' );
	}

	/**
	 * Check if the current user is a guest (not logged in).
	 *
	 * @param WP_REST_Request $request The current request.
	 *
	 * @return bool True if the user is not logged in, false otherwise.
	 */
	public function is_guest( WP_REST_Request $request ): bool {
		return ! $this->is_member( $request );
	}

	/**
	 * Check affiliate access permissions
	 *
	 * @param int|null        $affiliate_id The affiliate ID to check access for. If null, the method will attempt to resolve the affiliate ID based on the current user.
	 * @param WP_REST_Request $request      The current request.
	 *
	 * @return int|WP_Error Returns affiliate ID on success, WP_Error on failure
	 */
	public function check_affiliate_access( ?int $affiliate_id, WP_REST_Request $request ) {
		// Admin users have access to all affiliates.
		if ( current_user_can( 'manage_options' ) ) {
			return $affiliate_id;
		}

		$current_user_id = get_current_user_id();

		if ( $affiliate_id ) {
			// Check if user can access this specific affiliate.
			$affiliate = new Affiliate( $affiliate_id );
			if ( ! $affiliate->exists() || (int) $affiliate->user_id !== $current_user_id ) {
				return new WP_Error( 'permission_denied', __( 'Permission denied', 'wc-affiliate' ), array( 'status' => 403 ) );
			}

			return $affiliate_id;
		} else {
			// Non-admin users must have their affiliate ID auto-resolved.
			$affiliate_model = new Affiliate();
			$user_affiliate  = $affiliate_model->get_by_user_id( $current_user_id );
			if ( ! $user_affiliate || ! $user_affiliate->exists() ) {
				return new WP_Error( 'permission_denied', __( 'Permission denied', 'wc-affiliate' ), array( 'status' => 403 ) );
			}

			return $user_affiliate->user_id;
		}
	}
}
