<?php

namespace ModernFields\Taxonomies\Hooks;

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

use WP_REST_Response;
use WP_REST_Request;

defined('ABSPATH') || exit;

/**
 * Handles the Taxonomies management interface.
 *
 * Registers the storage CPT, submenu, REST endpoints,
 * and admin assets for the Taxonomies builder.
 *
 * @since 1.0.0
 */
class TaxonomiesAdmin implements Hooks
{
  use ChecksPermissions;

  public function registerHooks(): void
  {
    add_action('init', [$this, 'registerStorageCpt']);
    add_action('rest_api_init', [$this, 'registerRestEndpoints']);
    add_action('load-edit.php', [$this, 'redirectEditPage']);
  }

  /**
   * Registers the internal CPT used to store taxonomy definitions.
   * Config is stored as JSON in post_content (no extra meta query needed).
   */
  public function registerStorageCpt(): void
  {
    register_post_type(MODERN_FIELDS_TAXONOMIES_CPT_SLUG, [
      'label'        => 'Taxonomy Definition',
      'public'       => false,
      'show_ui'      => false,
      'show_in_rest' => false,
      'supports'     => ['title', 'editor'],
    ]);
  }

  /**
   * Registers REST API endpoints for CRUD on taxonomy definitions.
   */
  public function registerRestEndpoints(): void
  {
    # List all
    register_rest_route(MODERN_FIELDS_REST_NAMESPACE, '/taxonomy-definitions', [
      'methods'             => 'GET',
      'callback'            => [$this, 'getAll'],
      'permission_callback' => [$this, 'checkPermissions'],
    ]);

    # Create
    register_rest_route(MODERN_FIELDS_REST_NAMESPACE, '/taxonomy-definitions', [
      'methods'             => 'POST',
      'callback'            => [$this, 'create'],
      'permission_callback' => [$this, 'checkPermissions'],
    ]);

    # Get one
    register_rest_route(MODERN_FIELDS_REST_NAMESPACE, '/taxonomy-definitions/(?P<id>\d+)', [
      'methods'             => 'GET',
      'callback'            => [$this, 'getOne'],
      'permission_callback' => [$this, 'checkPermissions'],
    ]);

    # Update
    register_rest_route(MODERN_FIELDS_REST_NAMESPACE, '/taxonomy-definitions/(?P<id>\d+)', [
      'methods'             => 'PUT',
      'callback'            => [$this, 'update'],
      'permission_callback' => [$this, 'checkPermissions'],
    ]);

    # Delete
    register_rest_route(MODERN_FIELDS_REST_NAMESPACE, '/taxonomy-definitions/(?P<id>\d+)', [
      'methods'             => 'DELETE',
      'callback'            => [$this, 'delete'],
      'permission_callback' => [$this, 'checkPermissions'],
    ]);
  }

  /**
   * Returns all stored taxonomy definitions (published, draft and trashed).
   * The admin table filters Active vs Trash client-side.
   */
  public function getAll(WP_REST_Request $request): WP_REST_Response
  {
    $posts = get_posts([
      'post_type'      => MODERN_FIELDS_TAXONOMIES_CPT_SLUG,
      'post_status'    => ['publish', 'draft', 'trash'],
      'posts_per_page' => -1,
      'orderby'        => 'title',
      'order'          => 'ASC',
    ]);

    $items = array_map([$this, 'formatItem'], $posts);

    return rest_ensure_response($items);
  }

  /**
   * Returns a single taxonomy definition.
   */
  public function getOne(WP_REST_Request $request): WP_REST_Response
  {
    $id   = (int) $request->get_param('id');
    $post = get_post($id);

    if (!$post || $post->post_type !== MODERN_FIELDS_TAXONOMIES_CPT_SLUG) {
      return new WP_REST_Response(['message' => __('Not found', 'modern-fields')], 404);
    }

    return rest_ensure_response($this->formatItem($post));
  }

  /**
   * Creates a new taxonomy definition.
   */
  public function create(WP_REST_Request $request): WP_REST_Response
  {
    $params = $request->get_json_params();
    $config = $this->sanitizeConfig($params['config'] ?? []);

    $post_id = wp_insert_post([
      'post_type'    => MODERN_FIELDS_TAXONOMIES_CPT_SLUG,
      'post_title'   => sanitize_text_field($params['title'] ?? ''),
      'post_content' => wp_json_encode($config),
      'post_status'  => 'publish',
    ]);

    if (is_wp_error($post_id)) {
      return new WP_REST_Response(['message' => $post_id->get_error_message()], 500);
    }

    return rest_ensure_response($this->formatItem(get_post($post_id)));
  }

  /**
   * Updates an existing taxonomy definition.
   */
  public function update(WP_REST_Request $request): WP_REST_Response
  {
    $id   = (int) $request->get_param('id');
    $post = get_post($id);

    if (!$post || $post->post_type !== MODERN_FIELDS_TAXONOMIES_CPT_SLUG) {
      return new WP_REST_Response(['message' => __('Not found', 'modern-fields')], 404);
    }

    $params = $request->get_json_params();
    $config = $this->sanitizeConfig($params['config'] ?? []);

    $update_data = [
      'ID'           => $id,
      'post_title'   => sanitize_text_field($params['title'] ?? ''),
      'post_content' => wp_json_encode($config),
    ];

    if (isset($params['status']) && in_array($params['status'], ['publish', 'draft'], true)) {
      # Restoring from trash: untrash first so the status transition is clean.
      if ($post->post_status === 'trash') {
        wp_untrash_post($id);
      }
      $update_data['post_status'] = $params['status'];
    }

    wp_update_post($update_data);

    return rest_ensure_response($this->formatItem(get_post($id)));
  }

  /**
   * Trashes a taxonomy definition, or permanently deletes it when `force=true`.
   */
  public function delete(WP_REST_Request $request): WP_REST_Response
  {
    $id   = (int) $request->get_param('id');
    $post = get_post($id);

    if (!$post || $post->post_type !== MODERN_FIELDS_TAXONOMIES_CPT_SLUG) {
      return new WP_REST_Response(['message' => __('Not found', 'modern-fields')], 404);
    }

    $force = filter_var($request->get_param('force'), FILTER_VALIDATE_BOOLEAN);

    if ($force) {
      wp_delete_post($id, true);
    } else {
      wp_trash_post($id);
    }

    return rest_ensure_response(['success' => true]);
  }

  /**
   * Formats a post object into the API response shape.
   */
  protected function formatItem(\WP_Post $post): array
  {
    $config = $post->post_content ? json_decode($post->post_content, true) : [];

    return [
      'id'     => $post->ID,
      'title'  => $post->post_title,
      'status' => $post->post_status,
      'config' => $config,
    ];
  }

  /**
   * Sanitizes and normalizes a taxonomy config array.
   */
  protected function sanitizeConfig(array $raw): array
  {
    $labels_allowed = ['all_items', 'edit_item', 'view_item', 'update_item', 'add_new_item', 'new_item_name', 'search_items', 'not_found', 'menu_name'];

    return [
      'key'                => sanitize_key($raw['key'] ?? ''),
      'singular'           => sanitize_text_field($raw['singular'] ?? ''),
      'plural'             => sanitize_text_field($raw['plural'] ?? ''),
      'description'        => sanitize_textarea_field($raw['description'] ?? ''),
      'public'             => (bool) ($raw['public'] ?? true),
      'hierarchical'       => (bool) ($raw['hierarchical'] ?? false),
      'show_in_rest'       => (bool) ($raw['show_in_rest'] ?? true),
      'show_admin_column'  => (bool) ($raw['show_admin_column'] ?? false),
      'show_tag_cloud'     => (bool) ($raw['show_tag_cloud'] ?? true),
      'show_in_nav_menus'  => (bool) ($raw['show_in_nav_menus'] ?? true),
      'rewrite_slug'       => sanitize_key($raw['rewrite_slug'] ?? ''),
      'rest_base'          => sanitize_key($raw['rest_base'] ?? ''),
      'post_types'         => array_values(array_map('sanitize_key', (array) ($raw['post_types'] ?? []))),
      'labels'             => array_map(
        'sanitize_text_field',
        array_intersect_key(
          (array) ($raw['labels'] ?? []),
          array_flip($labels_allowed)
        )
      ),
    ];
  }

  /**
   * Redirects direct access to the storage CPT edit screen back to our page.
   */
  public function redirectEditPage(): void
  {
    if (!is_admin()) {
      return;
    }

    $post_type = isset($_GET['post_type']) ? sanitize_text_field(wp_unslash($_GET['post_type'])) : '';

    if ($post_type === MODERN_FIELDS_TAXONOMIES_CPT_SLUG) {
      wp_safe_redirect(admin_url('admin.php?page=modern-fields&tab=taxonomies'));
      exit;
    }
  }
}
