<?php

namespace ModernFields\FieldGroups\Locations\Hooks;

use ModernFields\FieldGroups\Entities\FieldGroup;
use ModernFields\FieldGroups\Locations\Location;
use ModernFields\FieldGroups\Locations\UseCases\SaveFieldsUseCase;
use ModernFields\FieldGroups\Locations\UseCases\GroupAssetsLoaderUseCase;
use ModernFields\FieldGroups\Repositories\UserRepository;
use ModernFields\FieldGroups\Repositories\FieldGroupRepository;
use ModernFields\WordPress\Security\SecurityHelper;
use ModernFields\WordPress\Interfaces\Hooks;

defined('ABSPATH') || exit;

/**
 * UserLocation Class
 *
 * Handles the integration of Modern Fields fields into the WordPress user profile page.
 * This class is responsible for:
 * - Registering required hooks for displaying fields on user profile pages
 * - Enqueuing necessary scripts and styles for the field interface
 * - Preparing and injecting inline styles for field blocks
 * - Registering user meta fields dynamically for REST API access
 * 
 * @since 1.0.0
 */
class UserLocation extends Location implements Hooks
{
  /**
   * Register the WordPress hooks required for the user profile location.
   * 
   * @since 1.0.0
   * @return void
   */
  public function registerHooks(): void
  {
    add_action('admin_enqueue_scripts', [$this, 'enqueueAssets']);
    add_action('show_user_profile', [$this, 'renderFieldsGroups']);
    add_action('edit_user_profile', [$this, 'renderFieldsGroups']);
    add_action('user_new_form', [$this, 'renderNewUserFieldsGroups']);
    add_action('personal_options_update', [$this, 'saveFields']);
    add_action('edit_user_profile_update', [$this, 'saveFields']);
    add_action('user_register', [$this, 'saveFields']);
  }

  /**
   * Checks if the current admin screen is a user profile page.
   * 
   * @since 1.0.0
   * @return bool True if the current screen is a user profile page, false otherwise.
   */
  protected function isUserProfilePage(): bool
  {
    # Check if the current admin page is a user profile page
    $allowed_pages = ['profile.php', 'user-edit.php', 'user-new.php'];
    if (!SecurityHelper::isCurrentAdminPage($allowed_pages)) {
      return false;
    }

    return true;
  }

  /**
   * Get the current user ID from the query string or current logged-in user.
   * 
   * Retrieves the user ID from the 'user_id' query parameter if available,
   * otherwise falls back to the currently logged-in user's ID.
   * 
   * @since 1.0.0
   * @return int The user ID, sanitized as an absolute integer.
   */
  protected function getCurrentEditedUserId(): int
  {
    $user_id = isset($_GET['user_id']) ? absint($_GET['user_id']) : get_current_user_id();
    return $user_id;
  }

  /**
   * Enqueue assets for the user profile React application.
   * 
   * Loads the necessary JavaScript and CSS assets for rendering field groups
   * on the user profile page. Only enqueues assets if the current screen is
   * a user profile page and field groups exist for the user.
   * 
   * @since 1.0.0
   * @return void
   */
  public function enqueueAssets(): void
  {
    if (!$this->isUserProfilePage()) {
      return;
    }

    $user_id = $this->getCurrentEditedUserId();
    $user = UserRepository::getUserById($user_id);

    $field_groups = FieldGroupRepository::getUserFieldGroups($user);

    $context = [
      "user" => $user->toArray(),
    ];

    $groupAssetsLoaderUseCase = new GroupAssetsLoaderUseCase('user-fields', $field_groups, $context);
    $groupAssetsLoaderUseCase->execute();
  }

  /**
   * Render the user fields for the given user.
   * 
   * Outputs the root container divs for each field group that will be
   * populated by the React application. Each container includes a data
   * attribute with the field group ID for React to mount the component.
   *
   * @since 1.0.0
   * @return void
   */
  public function renderFieldsGroups(): void
  {
    $user_id = $this->getCurrentEditedUserId();
    $user = UserRepository::getUserById($user_id);
    $field_groups = FieldGroupRepository::getUserFieldGroups($user);

    foreach ($field_groups as $field_group) {
      echo wp_kses_post($this->renderMarkup($field_group));
    }
  }

  /**
   * Render the new user fields for the new user page.
   * 
   * @since 1.0.0
   * @return void
   */
  public function renderNewUserFieldsGroups(): void
  {
    $field_groups = FieldGroupRepository::getNewUserFieldGroups();

    foreach ($field_groups as $field_group) {
      echo wp_kses_post($this->renderMarkup($field_group));
    }
  }

  /**
   * Render the markup for the given field group.
   * 
   * @since 1.0.0
   * @param FieldGroup $field_group The field group to render the markup for.
   * @return string The rendered markup.
   */
  protected function renderMarkup(FieldGroup $field_group): string
  {
    return '<div class="mf-user-fields-root" data-group-id="' . esc_attr($field_group->getId()) . '"></div>';
  }

  /**
   * Save the user fields for the given user.
   * 
   * Handles saving field values when the user profile is updated. Validates
   * the nonce and user capabilities before processing the save operation.
   *
   * @since 1.0.0
   * @param int $user_id The ID of the user to save the fields for.
   * @return void
   */
  public function saveFields($user_id): void
  {
    $nonce_valid = SecurityHelper::checkNonce('_wpnonce_create-user', 'create-user') || SecurityHelper::checkNonce('_wpnonce', 'update-user_' . $user_id);

    if (!$nonce_valid) {
      return;
    }

    if (!current_user_can('edit_user', $user_id)) {
      return;
    }

    $user = UserRepository::getUserById($user_id);

    $field_groups = FieldGroupRepository::getUserFieldGroups($user);

    $saveFieldsUseCase = new SaveFieldsUseCase($user, $field_groups);
    $saveFieldsUseCase->execute();
  }
}
