<?php

namespace ModernFields\WordPress\Endpoints;

use ModernFields\WordPress\Interfaces\Hooks;
use ModernFields\WordPress\Traits\ChecksPermissions;

use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

defined('ABSPATH') || exit;

/**
 * Registers the duplicate field group REST endpoint.
 *
 * Creates a copy of an existing field group (title appended with " (copy)"),
 * copies all meta fields, and saves as draft. The save_post hook fires
 * automatically, triggering FieldIndexer to index field blocks.
 *
 * @since 1.0.2
 */
class DuplicateFieldGroup implements Hooks
{
  use ChecksPermissions;

  /**
   * @since 1.0.2
   */
  public function registerHooks(): void
  {
    add_action('rest_api_init', [$this, 'registerRestEndpoints']);
  }

  /**
   * @since 1.0.2
   */
  public function registerRestEndpoints(): void
  {
    register_rest_route(MODERN_FIELDS_REST_NAMESPACE, '/field-groups/(?P<id>\d+)/duplicate', [
      'methods'             => WP_REST_Server::CREATABLE,
      'callback'            => [$this, 'duplicateFieldGroup'],
      'permission_callback' => [$this, 'checkPermissions'],
      'args'                => [
        'id' => [
          'required'          => true,
          'validate_callback' => fn($param) => is_numeric($param),
        ],
      ],
    ]);
  }

  /**
   * Duplicates a field group post with all its meta fields.
   *
   * @since 1.0.2
   * @param WP_REST_Request $request
   * @return WP_REST_Response|WP_Error
   */
  public function duplicateFieldGroup(WP_REST_Request $request): WP_REST_Response|WP_Error
  {
    $source_id = (int) $request->get_param('id');
    $source    = get_post($source_id);

    if (!$source || $source->post_type !== MODERN_FIELDS_CPT_SLUG) {
      return new WP_Error('not_found', __('Field group not found.', 'modern-fields'), ['status' => 404]);
    }

    $new_id = wp_insert_post([
      'post_type'    => MODERN_FIELDS_CPT_SLUG,
      'post_title'   => $source->post_title . ' (copy)',
      'post_content' => $source->post_content,
      'post_excerpt' => $source->post_excerpt,
      'post_status'  => 'draft',
      'post_author'  => get_current_user_id(),
    ], true);

    if (is_wp_error($new_id)) {
      return new WP_Error('duplicate_failed', $new_id->get_error_message(), ['status' => 500]);
    }

    $this->copyMeta($source_id, $new_id);

    $controller = new \WP_REST_Posts_Controller(MODERN_FIELDS_CPT_SLUG);
    $new_post   = get_post($new_id);
    $response   = $controller->prepare_item_for_response($new_post, $request);

    return rest_ensure_response($response->get_data());
  }

  /**
   * Copies all relevant meta fields from source to destination post.
   *
   * @since 1.0.2
   * @param int $source_id
   * @param int $dest_id
   */
  protected function copyMeta(int $source_id, int $dest_id): void
  {
    $single_metas = ['mf_location', 'mf_scope', 'mf_settings', 'mf_cpt', 'mf_position'];
    $multi_metas  = ['mf_targets', 'mf_roles'];

    foreach ($single_metas as $key) {
      $value = get_post_meta($source_id, $key, true);
      if ($value !== '' && $value !== false) {
        update_post_meta($dest_id, $key, $value);
      }
    }

    foreach ($multi_metas as $key) {
      $values = get_post_meta($source_id, $key);
      foreach ($values as $value) {
        add_post_meta($dest_id, $key, $value);
      }
    }
  }


}
