<?php

namespace ModernFields\FieldGroups\Factories;

use ModernFields\FieldGroups\Entities\User;
use ModernFields\FieldGroups\Repositories\UserRepository;

/**
 * Builds WordPress query arguments for retrieving field groups based on user locations.
 *
 * This builder prepares query arguments that filter field groups by location, scope and targets
 * for user-based field groups.
 * 
 * @since 1.0.0
 */
class UserQueryFactory extends QueryFactory
{
  /**
   * Constructor
   * 
   * @since 1.0.0
   * @param User|null $user The user entity used to determine field group locations
   */
  public function __construct(protected ?User $user = null) {}

  /**
   * Prepares WordPress query arguments for retrieving user field groups.
   *
   * Combines the provided meta query with base meta queries for user location type
   * and user roles. The resulting array can be used with WordPress query functions
   * like `get_posts()` or `WP_Query`.
   * 
   * @since 1.0.0
   *
   * @param array<string, mixed> $additional_meta_args Additional meta query conditions to merge with base meta query arguments
   * @return array<string, mixed> WordPress query arguments array
   */
  protected function prepareArgs(array $additional_meta_args): array
  {
    $current_user = UserRepository::getCurrentLoggedInUser();

    $base_meta_query = [
      'relation' => 'AND',
      [
        'key' => 'mf_location',
        'value' => 'user',
        'compare' => '='
      ],
      [
        'key' => 'mf_roles',
        'value' => $current_user->getRoles(),
        'compare' => 'IN'
      ],
    ];

    $meta_query = array_merge($base_meta_query, $additional_meta_args);

    $query = [
      'post_type' => MODERN_FIELDS_CPT_SLUG,
      'post_status' => 'publish',
      'posts_per_page' => -1,
      'meta_query' => $meta_query,
    ];

    return $query;
  }

  /**
   * Builds query arguments for field groups with 'all' scope.
   *
   * Returns field groups that apply to all users matching the user's roles.
   * 
   * @since 1.0.0
   * @return self
   */
  public function getAllUserQuery(): self
  {
    $query = $this->prepareArgs([
      [
        'key' => 'mf_scope',
        'value' => 'all',
        'compare' => '='
      ]
    ]);

    return $this->addQuery($query);
  }

  /**
   * Builds query arguments for field groups targeting a specific user.
   *
   * Returns field groups that are configured to apply to the current user by ID.
   * 
   * @since 1.0.0
   * @return self
   */
  public function getSpecificUserQuery(): self
  {
    if (!$this->user) {
      throw new \Exception('User must be set to use this query');
    }

    $query = $this->prepareArgs([
      [
        'key' => 'mf_scope',
        'value' => 'user',
        'compare' => '='
      ],
      [
        'key' => 'mf_targets',
        'value' => (string) $this->user->getId(),
        'compare' => '='
      ]
    ]);

    return $this->addQuery($query);
  }

  /**
   * Builds query arguments for field groups targeting a specific user role.
   *
   * Returns field groups that are configured to apply to the current user with the given role.
   * 
   * @since 1.0.0
   * @return self
   */
  public function getSpecificRoleQuery(): self
  {
    $query = $this->prepareArgs([
      [
        'key' => 'mf_scope',
        'value' => 'role',
        'compare' => '='
      ],
      [
        'key' => 'mf_targets',
        'value' => $this->user->getRoles(),
        'compare' => 'IN'
      ]
    ]);

    return $this->addQuery($query);
  }
}
