<?php
/**
 * CPT Builder configuration and schema definitions.
 *
 * Central source of truth for label fields, supported features, argument
 * defaults, reserved post type names, and the default definition shape.
 *
 * @package CptBuilder
 * @since 1.0.0
 */

namespace CptBuilder;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Static configuration provider for the CPT Builder module.
 */
final class Config {

	/**
	 * Storage schema version for stored definitions and exports.
	 */
	public const SCHEMA_VERSION = 1;

	/**
	 * Maximum allowed length of a post type key (WordPress hard limit).
	 */
	public const MAX_KEY_LENGTH = 20;

	/**
	 * Label fields shown on the Labels tab, in display order.
	 *
	 * The two primary labels (singular_name, name) are handled on the Basic
	 * tab and intentionally excluded here.
	 *
	 * @return array<string, array{label: string, help: string}>
	 */
	public static function labelFields(): array {
		return [
			'menu_name'                => [
				'label' => __( 'Menu name', 'wp-powersuite' ),
				'help'  => __( 'Label used in the admin menu. Defaults to the plural label.', 'wp-powersuite' ),
			],
			'name_admin_bar'           => [
				'label' => __( 'Admin bar name', 'wp-powersuite' ),
				'help'  => __( 'Label used in the “+ New” admin bar menu.', 'wp-powersuite' ),
			],
			'add_new'                  => [
				'label' => __( 'Add new', 'wp-powersuite' ),
				'help'  => __( 'Text for the Add New button/menu item.', 'wp-powersuite' ),
			],
			'add_new_item'             => [
				'label' => __( 'Add new item', 'wp-powersuite' ),
				'help'  => __( 'Heading shown when adding a new item.', 'wp-powersuite' ),
			],
			'edit_item'                => [
				'label' => __( 'Edit item', 'wp-powersuite' ),
				'help'  => __( 'Heading shown when editing an item.', 'wp-powersuite' ),
			],
			'new_item'                 => [
				'label' => __( 'New item', 'wp-powersuite' ),
				'help'  => __( 'Label for a new item.', 'wp-powersuite' ),
			],
			'view_item'                => [
				'label' => __( 'View item', 'wp-powersuite' ),
				'help'  => __( 'Label for viewing a single item.', 'wp-powersuite' ),
			],
			'view_items'               => [
				'label' => __( 'View items', 'wp-powersuite' ),
				'help'  => __( 'Label for viewing the post type archive.', 'wp-powersuite' ),
			],
			'search_items'             => [
				'label' => __( 'Search items', 'wp-powersuite' ),
				'help'  => __( 'Label for the search button on the list screen.', 'wp-powersuite' ),
			],
			'not_found'                => [
				'label' => __( 'Not found', 'wp-powersuite' ),
				'help'  => __( 'Message shown when no items are found.', 'wp-powersuite' ),
			],
			'not_found_in_trash'       => [
				'label' => __( 'Not found in trash', 'wp-powersuite' ),
				'help'  => __( 'Message shown when no items are found in the trash.', 'wp-powersuite' ),
			],
			'parent_item_colon'        => [
				'label' => __( 'Parent item colon', 'wp-powersuite' ),
				'help'  => __( 'Used for hierarchical types to show the parent (e.g. “Parent Page:”).', 'wp-powersuite' ),
			],
			'all_items'                => [
				'label' => __( 'All items', 'wp-powersuite' ),
				'help'  => __( 'Submenu label linking to all items.', 'wp-powersuite' ),
			],
			'archives'                 => [
				'label' => __( 'Archives', 'wp-powersuite' ),
				'help'  => __( 'Archive label used in nav menus.', 'wp-powersuite' ),
			],
			'attributes'               => [
				'label' => __( 'Attributes', 'wp-powersuite' ),
				'help'  => __( 'Title of the attributes meta box.', 'wp-powersuite' ),
			],
			'insert_into_item'         => [
				'label' => __( 'Insert into item', 'wp-powersuite' ),
				'help'  => __( 'Media modal button text (e.g. “Insert into post”).', 'wp-powersuite' ),
			],
			'uploaded_to_this_item'    => [
				'label' => __( 'Uploaded to this item', 'wp-powersuite' ),
				'help'  => __( 'Media modal filter text for items attached to this post.', 'wp-powersuite' ),
			],
			'featured_image'           => [
				'label' => __( 'Featured image', 'wp-powersuite' ),
				'help'  => __( 'Featured image meta box title.', 'wp-powersuite' ),
			],
			'set_featured_image'       => [
				'label' => __( 'Set featured image', 'wp-powersuite' ),
				'help'  => __( 'Link text to set the featured image.', 'wp-powersuite' ),
			],
			'remove_featured_image'    => [
				'label' => __( 'Remove featured image', 'wp-powersuite' ),
				'help'  => __( 'Link text to remove the featured image.', 'wp-powersuite' ),
			],
			'use_featured_image'       => [
				'label' => __( 'Use featured image', 'wp-powersuite' ),
				'help'  => __( 'Media modal button text to use as featured image.', 'wp-powersuite' ),
			],
			'filter_items_list'        => [
				'label' => __( 'Filter items list', 'wp-powersuite' ),
				'help'  => __( 'Screen reader text for the list filtering controls.', 'wp-powersuite' ),
			],
			'items_list_navigation'    => [
				'label' => __( 'Items list navigation', 'wp-powersuite' ),
				'help'  => __( 'Screen reader text for list pagination.', 'wp-powersuite' ),
			],
			'items_list'               => [
				'label' => __( 'Items list', 'wp-powersuite' ),
				'help'  => __( 'Screen reader text for the items list.', 'wp-powersuite' ),
			],
			'item_published'           => [
				'label' => __( 'Item published', 'wp-powersuite' ),
				'help'  => __( 'Notice shown after an item is published.', 'wp-powersuite' ),
			],
			'item_published_privately' => [
				'label' => __( 'Item published privately', 'wp-powersuite' ),
				'help'  => __( 'Notice shown after an item is published privately.', 'wp-powersuite' ),
			],
			'item_reverted_to_draft'   => [
				'label' => __( 'Item reverted to draft', 'wp-powersuite' ),
				'help'  => __( 'Notice shown after an item is reverted to draft.', 'wp-powersuite' ),
			],
			'item_scheduled'           => [
				'label' => __( 'Item scheduled', 'wp-powersuite' ),
				'help'  => __( 'Notice shown after an item is scheduled.', 'wp-powersuite' ),
			],
			'item_updated'             => [
				'label' => __( 'Item updated', 'wp-powersuite' ),
				'help'  => __( 'Notice shown after an item is updated.', 'wp-powersuite' ),
			],
		];
	}

	/**
	 * All recognized label keys (primary + secondary).
	 *
	 * @return array<int, string>
	 */
	public static function allLabelKeys(): array {
		return array_merge(
			[ 'name', 'singular_name' ],
			array_keys( self::labelFields() )
		);
	}

	/**
	 * Auto-generation templates for post type labels.
	 *
	 * Each entry: template (sprintf with one %s), source (singular|plural),
	 * and optional transform (lower). Labels without a template fall back to
	 * the WordPress default (e.g. featured image strings).
	 *
	 * @return array<string, array{template: string, source: string, transform?: string}>
	 */
	public static function labelTemplates(): array {
		return [
			'menu_name'                => [ 'template' => '%s', 'source' => 'plural' ],
			'name_admin_bar'           => [ 'template' => '%s', 'source' => 'singular' ],
			/* translators: %s: singular post type label. */
			'add_new'                  => [ 'template' => __( 'Add New %s', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: singular post type label. */
			'add_new_item'             => [ 'template' => __( 'Add New %s', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: singular post type label. */
			'edit_item'                => [ 'template' => __( 'Edit %s', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: singular post type label. */
			'new_item'                 => [ 'template' => __( 'New %s', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: singular post type label. */
			'view_item'                => [ 'template' => __( 'View %s', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: plural post type label. */
			'view_items'               => [ 'template' => __( 'View %s', 'wp-powersuite' ), 'source' => 'plural' ],
			/* translators: %s: plural post type label. */
			'search_items'             => [ 'template' => __( 'Search %s', 'wp-powersuite' ), 'source' => 'plural' ],
			/* translators: %s: plural post type label (lowercase). */
			'not_found'                => [ 'template' => __( 'No %s found.', 'wp-powersuite' ), 'source' => 'plural', 'transform' => 'lower' ],
			/* translators: %s: plural post type label (lowercase). */
			'not_found_in_trash'       => [ 'template' => __( 'No %s found in Trash.', 'wp-powersuite' ), 'source' => 'plural', 'transform' => 'lower' ],
			/* translators: %s: singular post type label. */
			'parent_item_colon'        => [ 'template' => __( 'Parent %s:', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: plural post type label. */
			'all_items'                => [ 'template' => __( 'All %s', 'wp-powersuite' ), 'source' => 'plural' ],
			/* translators: %s: singular post type label. */
			'archives'                 => [ 'template' => __( '%s Archives', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: singular post type label. */
			'attributes'               => [ 'template' => __( '%s Attributes', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: singular post type label (lowercase). */
			'insert_into_item'         => [ 'template' => __( 'Insert into %s', 'wp-powersuite' ), 'source' => 'singular', 'transform' => 'lower' ],
			/* translators: %s: singular post type label (lowercase). */
			'uploaded_to_this_item'    => [ 'template' => __( 'Uploaded to this %s', 'wp-powersuite' ), 'source' => 'singular', 'transform' => 'lower' ],
			/* translators: %s: plural post type label (lowercase). */
			'filter_items_list'        => [ 'template' => __( 'Filter %s list', 'wp-powersuite' ), 'source' => 'plural', 'transform' => 'lower' ],
			/* translators: %s: plural post type label. */
			'items_list_navigation'    => [ 'template' => __( '%s list navigation', 'wp-powersuite' ), 'source' => 'plural' ],
			/* translators: %s: plural post type label. */
			'items_list'               => [ 'template' => __( '%s list', 'wp-powersuite' ), 'source' => 'plural' ],
			/* translators: %s: singular post type label. */
			'item_published'           => [ 'template' => __( '%s published.', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: singular post type label. */
			'item_published_privately' => [ 'template' => __( '%s published privately.', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: singular post type label. */
			'item_reverted_to_draft'   => [ 'template' => __( '%s reverted to draft.', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: singular post type label. */
			'item_scheduled'           => [ 'template' => __( '%s scheduled.', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: singular post type label. */
			'item_updated'             => [ 'template' => __( '%s updated.', 'wp-powersuite' ), 'source' => 'singular' ],
		];
	}

	/**
	 * Generate a label value from a template definition.
	 *
	 * @param array{template: string, source: string, transform?: string} $meta     Template metadata.
	 * @param string                                                      $singular Singular label.
	 * @param string                                                      $plural   Plural label.
	 */
	public static function generateLabel( array $meta, string $singular, string $plural ): string {
		$value = $meta['source'] === 'singular' ? $singular : $plural;
		if ( $value === '' ) {
			return '';
		}

		if ( ( $meta['transform'] ?? '' ) === 'lower' ) {
			$value = function_exists( 'mb_strtolower' ) ? mb_strtolower( $value ) : strtolower( $value );
		}

		return sprintf( $meta['template'], $value );
	}

	/**
	 * Supported feature options for the Supports tab.
	 *
	 * @return array<string, array{label: string, help: string}>
	 */
	public static function supportsOptions(): array {
		return [
			'title'           => [
				'label' => __( 'Title', 'wp-powersuite' ),
				'help'  => __( 'Title input field.', 'wp-powersuite' ),
			],
			'editor'          => [
				'label' => __( 'Editor', 'wp-powersuite' ),
				'help'  => __( 'Main content editor (Block or Classic).', 'wp-powersuite' ),
			],
			'author'          => [
				'label' => __( 'Author', 'wp-powersuite' ),
				'help'  => __( 'Author selection meta box.', 'wp-powersuite' ),
			],
			'thumbnail'       => [
				'label' => __( 'Featured image', 'wp-powersuite' ),
				'help'  => __( 'Featured image support (theme must declare post-thumbnails).', 'wp-powersuite' ),
			],
			'excerpt'         => [
				'label' => __( 'Excerpt', 'wp-powersuite' ),
				'help'  => __( 'Hand-crafted summary field.', 'wp-powersuite' ),
			],
			'trackbacks'      => [
				'label' => __( 'Trackbacks', 'wp-powersuite' ),
				'help'  => __( 'Trackback and pingback support.', 'wp-powersuite' ),
			],
			'custom-fields'   => [
				'label' => __( 'Native custom fields', 'wp-powersuite' ),
				'help'  => __( 'WordPress key/value custom fields meta box (not WP PowerSuite Custom Fields).', 'wp-powersuite' ),
			],
			'comments'        => [
				'label' => __( 'Comments', 'wp-powersuite' ),
				'help'  => __( 'Comments and comment count.', 'wp-powersuite' ),
			],
			'revisions'       => [
				'label' => __( 'Revisions', 'wp-powersuite' ),
				'help'  => __( 'Store post revisions. The Revisions panel only appears after an item has been updated at least once.', 'wp-powersuite' ),
			],
			'page-attributes' => [
				'label' => __( 'Page attributes', 'wp-powersuite' ),
				'help'  => __( 'Menu order field (and parent for hierarchical types).', 'wp-powersuite' ),
			],
			'post-formats'    => [
				'label' => __( 'Post formats', 'wp-powersuite' ),
				'help'  => __( 'Enable post formats (theme support required).', 'wp-powersuite' ),
			],
		];
	}

	/**
	 * Post type keys reserved by WordPress core and not allowed for new types.
	 *
	 * @return array<int, string>
	 */
	public static function reservedPostTypes(): array {
		return [
			'post',
			'page',
			'attachment',
			'revision',
			'nav_menu_item',
			'custom_css',
			'customize_changeset',
			'oembed_cache',
			'user_request',
			'wp_block',
			'wp_template',
			'wp_template_part',
			'wp_global_styles',
			'wp_navigation',
			'wp_font_family',
			'wp_font_face',
			'action',
			'author',
			'order',
			'theme',
			'fields',
		];
	}

	/**
	 * Reserved query var / rewrite slugs that would collide with core.
	 *
	 * @return array<int, string>
	 */
	public static function reservedSlugs(): array {
		return [
			'type',
			'tab',
			'post',
			'page',
			'attachment',
			'feed',
			'author',
			'category',
			'tag',
			'page_id',
			'p',
			'name',
			'paged',
			'cpage',
			'order',
			'orderby',
			'wp_theme',
		];
	}

	/**
	 * Easy capability presets shown on the Capabilities tab.
	 *
	 * @return array<string, array{label: string, help: string}>
	 */
	public static function capabilityModes(): array {
		return [
			'post'   => [
				'label' => __( 'Same as Posts', 'wp-powersuite' ),
				'help'  => __( 'Reuse standard post permissions (edit_posts, publish_posts, …). Best for most content types.', 'wp-powersuite' ),
			],
			'page'   => [
				'label' => __( 'Same as Pages', 'wp-powersuite' ),
				'help'  => __( 'Reuse page permissions. Useful when the type should feel like hierarchical pages.', 'wp-powersuite' ),
			],
			'custom' => [
				'label' => __( 'Custom capabilities', 'wp-powersuite' ),
				'help'  => __( 'Create dedicated permissions from this post type’s key (e.g. edit_books). Optionally grant them to Administrators.', 'wp-powersuite' ),
			],
		];
	}

	/**
	 * Primitive capability names WordPress derives from capability_type.
	 *
	 * @param string $singular Singular capability type.
	 * @param string $plural   Plural capability type.
	 * @return array<int, string>
	 */
	public static function capabilityPreview( string $singular, string $plural = '' ): array {
		$singular = sanitize_key( $singular );
		if ( $singular === '' ) {
			return [];
		}

		$plural = sanitize_key( $plural );
		if ( $plural === '' ) {
			$plural = $singular . 's';
		}

		return [
			'edit_' . $singular,
			'read_' . $singular,
			'delete_' . $singular,
			'edit_' . $plural,
			'edit_others_' . $plural,
			'publish_' . $plural,
			'read_private_' . $plural,
			'delete_' . $plural,
			'delete_private_' . $plural,
			'delete_published_' . $plural,
			'delete_others_' . $plural,
			'edit_private_' . $plural,
			'edit_published_' . $plural,
			'create_' . $plural,
		];
	}

	/**
	 * Grant custom post type capabilities to the Administrator role.
	 *
	 * @param string $singular Singular capability type.
	 * @param string $plural   Plural capability type.
	 */
	public static function grantCapabilitiesToAdmin( string $singular, string $plural = '' ): void {
		$role = get_role( 'administrator' );
		if ( ! $role instanceof \WP_Role ) {
			return;
		}

		foreach ( self::capabilityPreview( $singular, $plural ) as $cap ) {
			$role->add_cap( $cap );
		}
	}

	/**
	 * Default definition used when creating a new post type.
	 *
	 * @return array<string, mixed>
	 */
	public static function defaultDefinition(): array {
		return [
			'key'        => '',
			'enabled'    => true,
			'labels'     => [
				'name'          => '',
				'singular_name' => '',
			],
			'args'       => self::defaultArgs(),
			'supports'   => [ 'title', 'editor', 'thumbnail' ],
			'taxonomies' => [],
			'schema'     => self::SCHEMA_VERSION,
			'created_at' => 0,
			'updated_at' => 0,
		];
	}

	/**
	 * Default register_post_type() argument values (UI-facing shape).
	 *
	 * @return array<string, mixed>
	 */
	public static function defaultArgs(): array {
		return [
			// General.
			'description'         => '',

			// Visibility.
			'public'              => true,
			'publicly_queryable'  => true,
			'show_ui'             => true,
			'show_in_menu'        => true,
			'show_in_nav_menus'   => true,
			'show_in_admin_bar'   => true,
			'exclude_from_search' => false,
			'hierarchical'        => false,
			'can_export'          => true,
			'delete_with_user'    => false,

			// REST API.
			'show_in_rest'          => true,
			'rest_base'             => '',
			'rest_namespace'        => '',
			'rest_controller_class' => '',

			// Menu.
			'menu_position' => '',
			'menu_icon'     => 'dashicons-admin-post',

			// Capabilities.
			'capability_mode'         => 'post',
			'capability_type'         => 'post',
			'capability_type_plural'  => '',
			'map_meta_cap'            => true,
			'grant_caps_to_admin'     => true,

			// Permalinks / archives.
			'has_archive'         => true,
			'has_archive_slug'    => '',
			'rewrite'             => true,
			'rewrite_slug'        => '',
			'rewrite_with_front'  => true,
			'rewrite_feeds'       => false,
			'rewrite_pages'       => true,
			'query_var'           => true,
			'query_var_slug'      => '',

			// Optional parent menu slug when show_in_menu is enabled.
			'show_in_menu_parent' => '',
		];
	}

	/**
	 * Boolean argument keys (used for sanitization/casting).
	 *
	 * @return array<int, string>
	 */
	public static function booleanArgKeys(): array {
		return [
			'public',
			'publicly_queryable',
			'show_ui',
			'show_in_menu',
			'show_in_nav_menus',
			'show_in_admin_bar',
			'exclude_from_search',
			'hierarchical',
			'can_export',
			'delete_with_user',
			'show_in_rest',
			'map_meta_cap',
			'grant_caps_to_admin',
			'has_archive',
			'rewrite',
			'rewrite_with_front',
			'rewrite_feeds',
			'rewrite_pages',
			'query_var',
		];
	}

	/**
	 * A curated subset of Dashicons for the icon picker.
	 *
	 * @return array<int, string>
	 */
	public static function dashicons(): array {
		$icons = [
			'dashicons-admin-post',
			'dashicons-admin-page',
			'dashicons-admin-media',
			'dashicons-admin-comments',
			'dashicons-admin-appearance',
			'dashicons-admin-plugins',
			'dashicons-admin-users',
			'dashicons-admin-tools',
			'dashicons-admin-settings',
			'dashicons-admin-network',
			'dashicons-admin-home',
			'dashicons-admin-generic',
			'dashicons-admin-collapse',
			'dashicons-admin-links',
			'dashicons-admin-multisite',
			'dashicons-format-aside',
			'dashicons-format-image',
			'dashicons-format-gallery',
			'dashicons-format-video',
			'dashicons-format-audio',
			'dashicons-format-quote',
			'dashicons-format-chat',
			'dashicons-format-status',
			'dashicons-book',
			'dashicons-book-alt',
			'dashicons-portfolio',
			'dashicons-products',
			'dashicons-cart',
			'dashicons-store',
			'dashicons-tickets-alt',
			'dashicons-megaphone',
			'dashicons-calendar-alt',
			'dashicons-location',
			'dashicons-location-alt',
			'dashicons-building',
			'dashicons-bank',
			'dashicons-groups',
			'dashicons-businessman',
			'dashicons-id',
			'dashicons-id-alt',
			'dashicons-awards',
			'dashicons-star-filled',
			'dashicons-heart',
			'dashicons-flag',
			'dashicons-pressthis',
			'dashicons-testimonial',
			'dashicons-album',
			'dashicons-images-alt2',
			'dashicons-camera',
			'dashicons-video-alt3',
			'dashicons-media-document',
			'dashicons-media-spreadsheet',
			'dashicons-clipboard',
			'dashicons-list-view',
			'dashicons-screenoptions',
			'dashicons-archive',
			'dashicons-category',
			'dashicons-tag',
			'dashicons-cloud',
			'dashicons-email',
			'dashicons-phone',
			'dashicons-smartphone',
			'dashicons-desktop',
			'dashicons-laptop',
			'dashicons-tablet',
			'dashicons-hammer',
			'dashicons-art',
			'dashicons-performance',
			'dashicons-chart-bar',
			'dashicons-chart-pie',
			'dashicons-analytics',
			'dashicons-lightbulb',
			'dashicons-sos',
			'dashicons-cart',
			'dashicons-money-alt',
			'dashicons-pets',
			'dashicons-palmtree',
			'dashicons-food',
			'dashicons-coffee',
			'dashicons-car',
		];

		return array_values( array_unique( $icons ) );
	}

	/* --------------------------------------------------------------------- */
	/* Taxonomies                                                            */
	/* --------------------------------------------------------------------- */

	/**
	 * Maximum allowed length of a taxonomy key (WordPress hard limit).
	 */
	public const MAX_TAXONOMY_KEY_LENGTH = 32;

	/**
	 * Secondary taxonomy label fields shown on the Labels tab, in order.
	 *
	 * Primary labels (name, singular_name) are handled on the Basic tab.
	 *
	 * @return array<string, array{label: string, help: string}>
	 */
	public static function taxonomyLabelFields(): array {
		return [
			'menu_name'                  => [
				'label' => __( 'Menu name', 'wp-powersuite' ),
				'help'  => __( 'Label used in the admin menu. Defaults to the plural label.', 'wp-powersuite' ),
			],
			'all_items'                  => [
				'label' => __( 'All items', 'wp-powersuite' ),
				'help'  => __( 'Label for listing all terms.', 'wp-powersuite' ),
			],
			'edit_item'                  => [
				'label' => __( 'Edit item', 'wp-powersuite' ),
				'help'  => __( 'Label for editing a single term.', 'wp-powersuite' ),
			],
			'view_item'                  => [
				'label' => __( 'View item', 'wp-powersuite' ),
				'help'  => __( 'Label for viewing a single term.', 'wp-powersuite' ),
			],
			'update_item'                => [
				'label' => __( 'Update item', 'wp-powersuite' ),
				'help'  => __( 'Label for the update button.', 'wp-powersuite' ),
			],
			'add_new_item'               => [
				'label' => __( 'Add new item', 'wp-powersuite' ),
				'help'  => __( 'Label for adding a new term.', 'wp-powersuite' ),
			],
			'new_item_name'              => [
				'label' => __( 'New item name', 'wp-powersuite' ),
				'help'  => __( 'Label for the new term name field.', 'wp-powersuite' ),
			],
			'parent_item'                => [
				'label' => __( 'Parent item', 'wp-powersuite' ),
				'help'  => __( 'Hierarchical only: label for a parent term.', 'wp-powersuite' ),
			],
			'parent_item_colon'          => [
				'label' => __( 'Parent item colon', 'wp-powersuite' ),
				'help'  => __( 'Hierarchical only: parent term label with a colon.', 'wp-powersuite' ),
			],
			'search_items'               => [
				'label' => __( 'Search items', 'wp-powersuite' ),
				'help'  => __( 'Label for searching terms.', 'wp-powersuite' ),
			],
			'popular_items'              => [
				'label' => __( 'Popular items', 'wp-powersuite' ),
				'help'  => __( 'Non-hierarchical only: label for popular terms.', 'wp-powersuite' ),
			],
			'separate_items_with_commas' => [
				'label' => __( 'Separate items with commas', 'wp-powersuite' ),
				'help'  => __( 'Non-hierarchical only: help text in the terms field.', 'wp-powersuite' ),
			],
			'add_or_remove_items'        => [
				'label' => __( 'Add or remove items', 'wp-powersuite' ),
				'help'  => __( 'Non-hierarchical only: help text when JavaScript is off.', 'wp-powersuite' ),
			],
			'choose_from_most_used'      => [
				'label' => __( 'Choose from most used', 'wp-powersuite' ),
				'help'  => __( 'Non-hierarchical only: help text for the most-used list.', 'wp-powersuite' ),
			],
			'not_found'                  => [
				'label' => __( 'Not found', 'wp-powersuite' ),
				'help'  => __( 'Message shown when no terms are found.', 'wp-powersuite' ),
			],
			'back_to_items'              => [
				'label' => __( 'Back to items', 'wp-powersuite' ),
				'help'  => __( 'Label for the link back to the terms list.', 'wp-powersuite' ),
			],
		];
	}

	/**
	 * All recognized taxonomy label keys (primary + secondary).
	 *
	 * @return array<int, string>
	 */
	public static function allTaxonomyLabelKeys(): array {
		return array_merge(
			[ 'name', 'singular_name' ],
			array_keys( self::taxonomyLabelFields() )
		);
	}

	/**
	 * Auto-generation templates for taxonomy labels.
	 *
	 * @return array<string, array{template: string, source: string, transform?: string}>
	 */
	public static function taxonomyLabelTemplates(): array {
		return [
			'menu_name'                  => [ 'template' => '%s', 'source' => 'plural' ],
			/* translators: %s: plural taxonomy label. */
			'all_items'                  => [ 'template' => __( 'All %s', 'wp-powersuite' ), 'source' => 'plural' ],
			/* translators: %s: singular taxonomy label. */
			'edit_item'                  => [ 'template' => __( 'Edit %s', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: singular taxonomy label. */
			'view_item'                  => [ 'template' => __( 'View %s', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: singular taxonomy label. */
			'update_item'                => [ 'template' => __( 'Update %s', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: singular taxonomy label. */
			'add_new_item'               => [ 'template' => __( 'Add New %s', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: singular taxonomy label. */
			'new_item_name'              => [ 'template' => __( 'New %s Name', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: singular taxonomy label. */
			'parent_item'                => [ 'template' => __( 'Parent %s', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: singular taxonomy label. */
			'parent_item_colon'          => [ 'template' => __( 'Parent %s:', 'wp-powersuite' ), 'source' => 'singular' ],
			/* translators: %s: plural taxonomy label. */
			'search_items'               => [ 'template' => __( 'Search %s', 'wp-powersuite' ), 'source' => 'plural' ],
			/* translators: %s: plural taxonomy label. */
			'popular_items'              => [ 'template' => __( 'Popular %s', 'wp-powersuite' ), 'source' => 'plural' ],
			/* translators: %s: plural taxonomy label (lowercase). */
			'separate_items_with_commas' => [ 'template' => __( 'Separate %s with commas', 'wp-powersuite' ), 'source' => 'plural', 'transform' => 'lower' ],
			/* translators: %s: plural taxonomy label (lowercase). */
			'add_or_remove_items'        => [ 'template' => __( 'Add or remove %s', 'wp-powersuite' ), 'source' => 'plural', 'transform' => 'lower' ],
			/* translators: %s: plural taxonomy label (lowercase). */
			'choose_from_most_used'      => [ 'template' => __( 'Choose from the most used %s', 'wp-powersuite' ), 'source' => 'plural', 'transform' => 'lower' ],
			/* translators: %s: plural taxonomy label (lowercase). */
			'not_found'                  => [ 'template' => __( 'No %s found.', 'wp-powersuite' ), 'source' => 'plural', 'transform' => 'lower' ],
			/* translators: %s: plural taxonomy label. */
			'back_to_items'              => [ 'template' => __( '← Go to %s', 'wp-powersuite' ), 'source' => 'plural' ],
		];
	}

	/**
	 * Taxonomy keys reserved by WordPress core.
	 *
	 * @return array<int, string>
	 */
	public static function reservedTaxonomies(): array {
		return [
			'category',
			'post_tag',
			'nav_menu',
			'link_category',
			'post_format',
			'wp_theme',
			'wp_template_part_area',
			'wp_pattern_category',
			'post_type',
			'taxonomy',
			'term',
			'terms',
			'type',
			'tag',
		];
	}

	/**
	 * Default register_taxonomy() argument values (UI-facing shape).
	 *
	 * @return array<string, mixed>
	 */
	public static function defaultTaxonomyArgs(): array {
		return [
			'description'         => '',

			// Behavior.
			'hierarchical'        => false,

			// Visibility.
			'public'              => true,
			'publicly_queryable'  => true,
			'show_ui'             => true,
			'show_in_menu'        => true,
			'show_in_nav_menus'   => true,
			'show_tagcloud'       => true,
			'show_in_quick_edit'  => true,
			'show_admin_column'   => false,
			'sort'                => false,

			// REST API.
			'show_in_rest'   => true,
			'rest_base'      => '',
			'rest_namespace' => '',

			// Permalinks.
			'rewrite'              => true,
			'rewrite_slug'         => '',
			'rewrite_with_front'   => true,
			'rewrite_hierarchical' => false,
			'query_var'            => true,
			'query_var_slug'       => '',
		];
	}

	/**
	 * Boolean taxonomy argument keys (used for sanitization/casting).
	 *
	 * @return array<int, string>
	 */
	public static function taxonomyBooleanArgKeys(): array {
		return [
			'hierarchical',
			'public',
			'publicly_queryable',
			'show_ui',
			'show_in_menu',
			'show_in_nav_menus',
			'show_tagcloud',
			'show_in_quick_edit',
			'show_admin_column',
			'sort',
			'show_in_rest',
			'rewrite',
			'rewrite_with_front',
			'rewrite_hierarchical',
			'query_var',
		];
	}

	/**
	 * Default taxonomy definition used when creating a new taxonomy.
	 *
	 * @return array<string, mixed>
	 */
	public static function defaultTaxonomyDefinition(): array {
		return [
			'key'          => '',
			'enabled'      => true,
			'object_types' => [],
			'labels'       => [
				'name'          => '',
				'singular_name' => '',
			],
			'args'         => self::defaultTaxonomyArgs(),
			'schema'       => self::SCHEMA_VERSION,
			'created_at'   => 0,
			'updated_at'   => 0,
		];
	}
}
