<?php
/**
 * WPFAQBlock AJAX Handlers
 *
 * All admin-ajax.php actions for the FAQ Builder:
 *   - Save / update a FAQ
 *   - Create a new FAQ
 *   - Toggle FAQ status (publish ↔ draft)
 *   - Delete a FAQ
 *   - Save FAQ order (menu_order)
 *
 * Every handler verifies a nonce and capability before touching the DB.
 *
 * @package WPFAQBlock
 * @since   2.0.0
 */

// Prevent direct file access.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Class WPFAQBlock_Ajax
 */
class WPFAQBlock_Ajax {

	/** Nonce action string shared with JS. */
	const NONCE_ACTION = 'wpfaqblock_builder_nonce';

	/** Required capability. */
	const CAP = 'manage_options';

	// ──────────────────────────────────────────────
	// Hook Registration
	// ──────────────────────────────────────────────

	/**
	 * Register all wp_ajax_ hooks.
	 *
	 * Hooked into: init (via loader)
	 *
	 * @since 2.0.0
	 * @return void
	 */
	public function register_hooks(): void {
		$actions = array(
			'wpfaqblock_save_faq',
			'wpfaqblock_create_faq',
			'wpfaqblock_toggle_faq',
			'wpfaqblock_delete_faq',
			'wpfaqblock_save_faq_order',
			'wpfaqblock_save_group_order',
			'wpfaqblock_toggle_group',
			'wpfaqblock_create_group',
			'wpfaqblock_update_group',
			'wpfaqblock_delete_group',
			'wpfaqblock_export_faqs',
			'wpfaqblock_import_faqs',
		);

		foreach ( $actions as $action ) {
			add_action( 'wp_ajax_' . $action, array( $this, str_replace( 'wpfaqblock_', 'handle_', $action ) ) );
		}
	}

	// ──────────────────────────────────────────────
	// Shared helpers
	// ──────────────────────────────────────────────



	/**
	 * Ensure a post belongs to the wpfaqblock CPT.
	 *
	 * @since 2.0.0
	 * @param int $post_id Post ID.
	 * @return WP_Post
	 */
	private function get_valid_faq( int $post_id ): WP_Post {
		$post = get_post( $post_id );

		if ( ! $post instanceof WP_Post || WPFAQBlock_CPT::SLUG !== $post->post_type ) {
			wp_send_json_error( array( 'message' => __( 'Invalid FAQ.', 'wpfaqblock' ) ), 400 );
		}

		return $post; // @phpstan-ignore-line (wp_send_json_error exits)
	}

	// ──────────────────────────────────────────────
	// FAQ CRUD
	// ──────────────────────────────────────────────

	/**
	 * Save (update) an existing FAQ.
	 *
	 * POST fields: nonce, post_id, question, answer, group_id, status
	 *
	 * @since 2.0.0
	 * @return void
	 */
	public function handle_save_faq(): void {
		check_ajax_referer( self::NONCE_ACTION, 'nonce' );

		if ( ! current_user_can( self::CAP ) ) {
			wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'wpfaqblock' ) ), 403 );
		}

		$post_id  = isset( $_POST['post_id'] )  ? absint( $_POST['post_id'] )                        : 0;
		$question = isset( $_POST['question'] ) ? sanitize_text_field( wp_unslash( $_POST['question'] ) ) : '';
		$answer   = isset( $_POST['answer'] )   ? wp_kses_post( wp_unslash( $_POST['answer'] ) )         : '';
		$group_id = isset( $_POST['group_id'] ) ? absint( $_POST['group_id'] )                       : 0;
		$status   = isset( $_POST['status'] )   && '1' === $_POST['status'] ? 'publish' : 'draft';

		if ( empty( $question ) ) {
			wp_send_json_error( array( 'message' => __( 'Question cannot be empty.', 'wpfaqblock' ) ) );
		}

		$this->get_valid_faq( $post_id );

		$result = wp_update_post(
			array(
				'ID'           => $post_id,
				'post_title'   => $question,
				'post_content' => $answer,
				'post_status'  => $status,
			),
			true
		);

		if ( is_wp_error( $result ) ) {
			wp_send_json_error( array( 'message' => $result->get_error_message() ) );
		}

		// Update taxonomy group.
		if ( $group_id > 0 ) {
			wp_set_object_terms( $post_id, array( $group_id ), WPFAQBlock_Taxonomy::SLUG );
		} else {
			wp_set_object_terms( $post_id, array(), WPFAQBlock_Taxonomy::SLUG );
		}

		wp_send_json_success(
			array(
				'message'  => __( 'FAQ updated.', 'wpfaqblock' ),
				'post_id'  => $post_id,
				'question' => esc_html( $question ),
				'status'   => $status,
			)
		);
	}

	/**
	 * Create a new FAQ post.
	 *
	 * POST fields: nonce, question, answer, group_id, status
	 *
	 * @since 2.0.0
	 * @return void
	 */
	public function handle_create_faq(): void {
		check_ajax_referer( self::NONCE_ACTION, 'nonce' );

		if ( ! current_user_can( self::CAP ) ) {
			wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'wpfaqblock' ) ), 403 );
		}

		$question = isset( $_POST['question'] ) ? sanitize_text_field( wp_unslash( $_POST['question'] ) ) : '';
		$answer   = isset( $_POST['answer'] )   ? wp_kses_post( wp_unslash( $_POST['answer'] ) )         : '';
		$group_id = isset( $_POST['group_id'] ) ? absint( $_POST['group_id'] )                           : 0;
		$status   = isset( $_POST['status'] )   && '1' === $_POST['status'] ? 'publish' : 'draft';

		if ( empty( $question ) ) {
			wp_send_json_error( array( 'message' => __( 'Question cannot be empty.', 'wpfaqblock' ) ) );
		}

		$post_id = wp_insert_post(
			array(
				'post_type'    => WPFAQBlock_CPT::SLUG,
				'post_title'   => $question,
				'post_content' => $answer,
				'post_status'  => $status,
				'menu_order'   => 0,
			),
			true
		);

		if ( is_wp_error( $post_id ) ) {
			wp_send_json_error( array( 'message' => $post_id->get_error_message() ) );
		}

		if ( $group_id > 0 ) {
			wp_set_object_terms( $post_id, array( $group_id ), WPFAQBlock_Taxonomy::SLUG );
		}

		wp_send_json_success(
			array(
				'message'  => __( 'FAQ created.', 'wpfaqblock' ),
				'post_id'  => $post_id,
				'question' => esc_html( $question ),
				'status'   => $status,
				'group_id' => $group_id,
			)
		);
	}

	/**
	 * Toggle a FAQ between publish and draft.
	 *
	 * POST fields: nonce, post_id, status (1=publish, 0=draft)
	 *
	 * @since 2.0.0
	 * @return void
	 */
	public function handle_toggle_faq(): void {
		check_ajax_referer( self::NONCE_ACTION, 'nonce' );

		if ( ! current_user_can( self::CAP ) ) {
			wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'wpfaqblock' ) ), 403 );
		}

		$post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0;
		$status  = isset( $_POST['status'] )  && '1' === $_POST['status'] ? 'publish' : 'draft';

		$this->get_valid_faq( $post_id );

		$result = wp_update_post(
			array(
				'ID'          => $post_id,
				'post_status' => $status,
			),
			true
		);

		if ( is_wp_error( $result ) ) {
			wp_send_json_error( array( 'message' => $result->get_error_message() ) );
		}

		wp_send_json_success(
			array(
				'message' => __( 'Status updated.', 'wpfaqblock' ),
				'post_id' => $post_id,
				'status'  => $status,
			)
		);
	}

	/**
	 * Permanently delete a FAQ.
	 *
	 * POST fields: nonce, post_id
	 *
	 * @since 2.0.0
	 * @return void
	 */
	public function handle_delete_faq(): void {
		check_ajax_referer( self::NONCE_ACTION, 'nonce' );

		if ( ! current_user_can( self::CAP ) ) {
			wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'wpfaqblock' ) ), 403 );
		}

		$post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0;

		$this->get_valid_faq( $post_id );

		$result = wp_delete_post( $post_id, true );

		if ( ! $result ) {
			wp_send_json_error( array( 'message' => __( 'Could not delete FAQ.', 'wpfaqblock' ) ) );
		}

		wp_send_json_success(
			array(
				'message' => __( 'FAQ deleted.', 'wpfaqblock' ),
				'post_id' => $post_id,
			)
		);
	}

	// ──────────────────────────────────────────────
	// Order (Step 8 — Drag & Drop)
	// ──────────────────────────────────────────────

	/**
	 * Save new FAQ order (menu_order) after drag-and-drop.
	 *
	 * POST fields: nonce, order[] (array of post IDs in new order)
	 *
	 * @since 2.0.0
	 * @return void
	 */
	public function handle_save_faq_order(): void {
		check_ajax_referer( self::NONCE_ACTION, 'nonce' );

		if ( ! current_user_can( self::CAP ) ) {
			wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'wpfaqblock' ) ), 403 );
		}

		$order = isset( $_POST['order'] ) && is_array( $_POST['order'] )
			? array_map( 'absint', $_POST['order'] )
			: array();

		if ( empty( $order ) ) {
			wp_send_json_error( array( 'message' => __( 'No order data received.', 'wpfaqblock' ) ) );
		}

		foreach ( $order as $position => $post_id ) {
			wp_update_post(
				array(
					'ID'         => $post_id,
					'menu_order' => $position,
				)
			);
		}

		wp_send_json_success( array( 'message' => __( 'Order saved.', 'wpfaqblock' ) ) );
	}

	/**
	 * Save new group order after drag-and-drop.
	 *
	 * POST fields: nonce, order[] (array of term IDs in new order)
	 *
	 * @since 2.0.0
	 * @return void
	 */
	public function handle_save_group_order(): void {
		check_ajax_referer( self::NONCE_ACTION, 'nonce' );

		if ( ! current_user_can( self::CAP ) ) {
			wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'wpfaqblock' ) ), 403 );
		}

		$order = isset( $_POST['order'] ) && is_array( $_POST['order'] )
			? array_map( 'absint', $_POST['order'] )
			: array();

		if ( empty( $order ) ) {
			wp_send_json_error( array( 'message' => __( 'No order data received.', 'wpfaqblock' ) ) );
		}

		foreach ( $order as $position => $term_id ) {
			update_term_meta( $term_id, '_wpfaqblock_term_order', $position );
		}

		wp_send_json_success( array( 'message' => __( 'Group order saved.', 'wpfaqblock' ) ) );
	}

	// ──────────────────────────────────────────────
	// Groups (Step 9 — Add Group Modal)
	// ──────────────────────────────────────────────

	/**
	 * Create a new faq_group term.
	 *
	 * POST fields: nonce, name
	 *
	 * @since 2.0.0
	 * @return void
	 */
	public function handle_create_group(): void {
		check_ajax_referer( self::NONCE_ACTION, 'nonce' );

		if ( ! current_user_can( self::CAP ) ) {
			wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'wpfaqblock' ) ), 403 );
		}

		$name = isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : '';

		if ( empty( $name ) ) {
			wp_send_json_error( array( 'message' => __( 'Group name cannot be empty.', 'wpfaqblock' ) ) );
		}

		if ( term_exists( $name, WPFAQBlock_Taxonomy::SLUG ) ) {
			wp_send_json_error( array( 'message' => __( 'This Category already exists.', 'wpfaqblock' ) ) );
		}

		$result = wp_insert_term( $name, WPFAQBlock_Taxonomy::SLUG );

		if ( is_wp_error( $result ) ) {
			wp_send_json_error( array( 'message' => $result->get_error_message() ) );
		}

		wp_send_json_success(
			array(
				'message' => __( 'Group created.', 'wpfaqblock' ),
				'term_id' => $result['term_id'],
				'name'    => esc_html( $name ),
			)
		);
	}

	/**
	 * Update a faq_group term name.
	 *
	 * POST fields: nonce, term_id, name
	 *
	 * @since 2.0.0
	 * @return void
	 */
	public function handle_update_group(): void {
		check_ajax_referer( self::NONCE_ACTION, 'nonce' );

		if ( ! current_user_can( self::CAP ) ) {
			wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'wpfaqblock' ) ), 403 );
		}

		$term_id = isset( $_POST['term_id'] ) ? absint( $_POST['term_id'] ) : 0;
		$name    = isset( $_POST['name'] )    ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : '';

		if ( empty( $name ) || ! $term_id ) {
			wp_send_json_error( array( 'message' => __( 'Invalid data.', 'wpfaqblock' ) ) );
		}

		$existing_term = term_exists( $name, WPFAQBlock_Taxonomy::SLUG );
		if ( $existing_term && (int) $existing_term['term_id'] !== $term_id ) {
			wp_send_json_error( array( 'message' => __( 'Another Category with this name already exists.', 'wpfaqblock' ) ) );
		}

		$result = wp_update_term( $term_id, WPFAQBlock_Taxonomy::SLUG, array( 'name' => $name ) );

		if ( is_wp_error( $result ) ) {
			wp_send_json_error( array( 'message' => $result->get_error_message() ) );
		}

		wp_send_json_success(
			array(
				'message' => __( 'Group updated.', 'wpfaqblock' ),
				'term_id' => $term_id,
				'name'    => esc_html( $name ),
			)
		);
	}

	/**
	 * Toggle a faq_group active status.
	 *
	 * POST fields: nonce, term_id, status (1=active, 0=inactive)
	 *
	 * @since 2.0.0
	 * @return void
	 */
	public function handle_toggle_group(): void {
		check_ajax_referer( self::NONCE_ACTION, 'nonce' );

		if ( ! current_user_can( self::CAP ) ) {
			wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'wpfaqblock' ) ), 403 );
		}

		$term_id = isset( $_POST['term_id'] ) ? absint( $_POST['term_id'] ) : 0;
		$status  = isset( $_POST['status'] )  && '1' === $_POST['status'] ? '1' : '0';

		if ( ! $term_id ) {
			wp_send_json_error( array( 'message' => __( 'Invalid group.', 'wpfaqblock' ) ) );
		}

		update_term_meta( $term_id, 'faqb_group_status', $status );

		wp_send_json_success(
			array(
				'message' => __( 'Group status updated.', 'wpfaqblock' ),
				'term_id' => $term_id,
				'status'  => $status,
			)
		);
	}

	/**
	 * Delete a faq_group term (FAQs inside are NOT deleted — just ungrouped).
	 *
	 * POST fields: nonce, term_id
	 *
	 * @since 2.0.0
	 * @return void
	 */
	public function handle_delete_group(): void {
		check_ajax_referer( self::NONCE_ACTION, 'nonce' );

		if ( ! current_user_can( self::CAP ) ) {
			wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'wpfaqblock' ) ), 403 );
		}

		$term_id = isset( $_POST['term_id'] ) ? absint( $_POST['term_id'] ) : 0;

		if ( ! $term_id ) {
			wp_send_json_error( array( 'message' => __( 'Invalid group.', 'wpfaqblock' ) ) );
		}

		// Fetch all FAQs in this group and delete them.
		$faqs = get_posts(
			array(
				'post_type'      => WPFAQBlock_CPT::SLUG,
				'posts_per_page' => -1,
				'tax_query'      => array(
					array(
						'taxonomy' => WPFAQBlock_Taxonomy::SLUG,
						'field'    => 'term_id',
						'terms'    => $term_id,
					),
				),
				'fields'         => 'ids',
				'post_status'    => array( 'publish', 'draft' ),
			)
		);

		foreach ( $faqs as $faq_id ) {
			wp_delete_post( $faq_id, true ); // Permanently delete FAQs.
		}

		$result = wp_delete_term( $term_id, WPFAQBlock_Taxonomy::SLUG );

		if ( is_wp_error( $result ) || ! $result ) {
			wp_send_json_error( array( 'message' => __( 'Could not delete group.', 'wpfaqblock' ) ) );
		}

		wp_send_json_success(
			array(
				'message' => __( 'Group deleted.', 'wpfaqblock' ),
				'term_id' => $term_id,
			)
		);
	}

	// ──────────────────────────────────────────────
	// Import / Export
	// ──────────────────────────────────────────────

	/**
	 * Export all FAQs, one or more categories, or selected post IDs.
	 *
	 * POST fields: nonce, mode(all|category|selected), group_id, group_ids, faq_ids
	 *
	 * @since 2.0.0
	 * @return void
	 */
	public function handle_export_faqs(): void {
		check_ajax_referer( self::NONCE_ACTION, 'nonce' );

		if ( ! current_user_can( self::CAP ) ) {
			wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'wpfaqblock' ) ), 403 );
		}

		$mode = isset( $_POST['mode'] ) ? sanitize_key( wp_unslash( $_POST['mode'] ) ) : 'all';
		$args = array(
			'post_type'      => WPFAQBlock_CPT::SLUG,
			'post_status'    => array( 'publish', 'draft' ),
			'posts_per_page' => -1,
			'orderby'        => 'menu_order',
			'order'          => 'ASC',
			'no_found_rows'  => true,
		);

		if ( 'selected' === $mode ) {
			$faq_ids = isset( $_POST['faq_ids'] ) ? sanitize_text_field( wp_unslash( $_POST['faq_ids'] ) ) : '';
			$faq_ids = array_filter( array_map( 'absint', preg_split( '/[\s,]+/', $faq_ids ) ) );

			if ( empty( $faq_ids ) ) {
				wp_send_json_error( array( 'message' => __( 'Please select at least one FAQ to export.', 'wpfaqblock' ) ) );
			}

			$args['post__in'] = array_values( array_unique( $faq_ids ) );
			$args['orderby'] = 'post__in';
		} elseif ( 'category' === $mode ) {
			$raw_group_ids         = isset( $_POST['group_ids'] ) ? trim( sanitize_text_field( wp_unslash( $_POST['group_ids'] ) ) ) : '';
			$group_ids             = array();
			$include_uncategorized = false;

			if ( '' !== $raw_group_ids ) {
				$requested_group_ids    = array_map( 'absint', preg_split( '/[\s,]+/', $raw_group_ids, -1, PREG_SPLIT_NO_EMPTY ) );
				$include_uncategorized = in_array( 0, $requested_group_ids, true );
				$group_ids             = array_values(
					array_filter(
						array_unique( $requested_group_ids ),
						static function ( $group_id ) {
							return $group_id > 0;
						}
					)
				);
			} else {
				$group_id = isset( $_POST['group_id'] ) ? absint( $_POST['group_id'] ) : 0;

				if ( $group_id > 0 ) {
					$group_ids = array( $group_id );
				} else {
					$include_uncategorized = true;
				}
			}

			if ( empty( $group_ids ) && ! $include_uncategorized ) {
				wp_send_json_error( array( 'message' => __( 'Please select at least one category to export.', 'wpfaqblock' ) ) );
			}

			$tax_query = array();

			if ( ! empty( $group_ids ) ) {
				$tax_query[] = array(
					'taxonomy' => WPFAQBlock_Taxonomy::SLUG,
					'field'    => 'term_id',
					'terms'    => $group_ids,
				);
			}

			if ( $include_uncategorized ) {
				$tax_query[] = array(
					'taxonomy' => WPFAQBlock_Taxonomy::SLUG,
					'operator' => 'NOT EXISTS',
				);
			}

			$args['tax_query'] = count( $tax_query ) > 1 ? array_merge( array( 'relation' => 'OR' ), $tax_query ) : $tax_query; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
		} else {
			$mode = 'all';
		}

		$query = new WP_Query( $args );
		$faqs = array();

		foreach ( $query->posts as $faq ) {
			if ( ! $faq instanceof WP_Post ) {
				continue;
			}

			$terms = get_the_terms( $faq->ID, WPFAQBlock_Taxonomy::SLUG );
			$term = ( ! empty( $terms ) && ! is_wp_error( $terms ) ) ? reset( $terms ) : null;

			$faqs[] = array(
				'question'   => $faq->post_title,
				'answer'     => $faq->post_content,
				'status'     => $faq->post_status,
				'menu_order' => (int) $faq->menu_order,
				'category'   => $term instanceof WP_Term
					? array(
						'name' => $term->name,
						'slug' => $term->slug,
					)
					: null,
			);
		}

		$export = array(
			'source'      => 'WPFAQBlock',
			'version'     => WPFAQBLOCK_VERSION,
			'exported_at' => current_time( 'mysql' ),
			'count'       => count( $faqs ),
			'faqs'        => $faqs,
		);

		wp_send_json_success(
			array(
				'message'  => __( 'FAQs exported.', 'wpfaqblock' ),
				'filename' => 'wpfaqblock-faqs-' . gmdate( 'Ymd-His' ) . '.json',
				'export'   => $export,
			)
		);
	}

	/**
	 * Import FAQs from a WPFAQBlock JSON payload.
	 *
	 * POST fields: nonce, payload, target_group_id(preserve|0|term_id)
	 *
	 * @since 2.0.0
	 * @return void
	 */
	public function handle_import_faqs(): void {
		check_ajax_referer( self::NONCE_ACTION, 'nonce' );

		if ( ! current_user_can( self::CAP ) ) {
			wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'wpfaqblock' ) ), 403 );
		}

		$payload = isset( $_POST['payload'] ) ? wp_unslash( $_POST['payload'] ) : '';
		$target_group_id = isset( $_POST['target_group_id'] ) ? sanitize_text_field( wp_unslash( $_POST['target_group_id'] ) ) : 'preserve';
		$data = json_decode( $payload, true );

		if ( ! is_array( $data ) ) {
			wp_send_json_error( array( 'message' => __( 'Invalid import file.', 'wpfaqblock' ) ) );
		}

		$items = isset( $data['faqs'] ) && is_array( $data['faqs'] ) ? $data['faqs'] : $data;
		if ( empty( $items ) || ! is_array( $items ) ) {
			wp_send_json_error( array( 'message' => __( 'No FAQs found in import file.', 'wpfaqblock' ) ) );
		}

		$imported = 0;
		$skipped = 0;

		foreach ( $items as $item ) {
			if ( ! is_array( $item ) ) {
				$skipped++;
				continue;
			}

			$question = isset( $item['question'] ) && is_scalar( $item['question'] ) ? sanitize_text_field( (string) $item['question'] ) : '';
			$answer = isset( $item['answer'] ) && is_scalar( $item['answer'] ) ? wp_kses_post( (string) $item['answer'] ) : '';
			$status = isset( $item['status'] ) && 'draft' === (string) $item['status'] ? 'draft' : 'publish';

			if ( '' === $question ) {
				$skipped++;
				continue;
			}

			$post_id = wp_insert_post(
				array(
					'post_type'    => WPFAQBlock_CPT::SLUG,
					'post_title'   => $question,
					'post_content' => $answer,
					'post_status'  => $status,
					'menu_order'   => isset( $item['menu_order'] ) ? absint( $item['menu_order'] ) : 0,
				),
				true
			);

			if ( is_wp_error( $post_id ) ) {
				$skipped++;
				continue;
			}

			$term_id = 0;
			if ( 'preserve' === $target_group_id ) {
				$term_id = $this->resolve_import_category( $item );
			} else {
				$term_id = absint( $target_group_id );
			}

			if ( $term_id > 0 ) {
				wp_set_object_terms( $post_id, array( $term_id ), WPFAQBlock_Taxonomy::SLUG );
			}

			$imported++;
		}

		wp_send_json_success(
			array(
				'message'  => sprintf(
					/* translators: 1: imported count, 2: skipped count */
					__( 'Imported %1$d FAQ(s). Skipped %2$d item(s).', 'wpfaqblock' ),
					$imported,
					$skipped
				),
				'imported' => $imported,
				'skipped'  => $skipped,
			)
		);
	}

	/**
	 * Resolve or create a category from imported FAQ data.
	 *
	 * @since 2.0.0
	 *
	 * @param array $item Import item.
	 * @return int Term ID, or 0 for uncategorized.
	 */
	private function resolve_import_category( array $item ): int {
		if ( empty( $item['category'] ) || ! is_array( $item['category'] ) ) {
			return 0;
		}

		$name = isset( $item['category']['name'] ) && is_scalar( $item['category']['name'] ) ? sanitize_text_field( (string) $item['category']['name'] ) : '';
		$slug = isset( $item['category']['slug'] ) && is_scalar( $item['category']['slug'] ) ? sanitize_title( (string) $item['category']['slug'] ) : '';

		if ( '' !== $slug ) {
			$term = get_term_by( 'slug', $slug, WPFAQBlock_Taxonomy::SLUG );
			if ( $term instanceof WP_Term ) {
				return (int) $term->term_id;
			}
		}

		if ( '' !== $name ) {
			$term = get_term_by( 'name', $name, WPFAQBlock_Taxonomy::SLUG );
			if ( $term instanceof WP_Term ) {
				return (int) $term->term_id;
			}

			$result = wp_insert_term(
				$name,
				WPFAQBlock_Taxonomy::SLUG,
				array_filter(
					array(
						'slug' => $slug,
					)
				)
			);

			if ( ! is_wp_error( $result ) && ! empty( $result['term_id'] ) ) {
				return (int) $result['term_id'];
			}
		}

		return 0;
	}
}
