<?php
/**
 * Changeloger Post Types Registration
 *
 * Core post types for the free plugin
 *
 * @package Changeloger
 */

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

/**
 * Class Changeloger_Post_Types
 *
 * Handles registration of custom post types for releases and feedback
 * Pro plugin registers additional post types (Roadmap)
 */
class Changeloger_Post_Types {

	/**
	 * Release post type name
	 */
	const POST_TYPE = 'cha_release';

	/**
	 * Feedback post type name
	 */
	const POST_TYPE_FEEDBACK = 'cha_feedback';

	/**
	 * Taxonomy name for products
	 */
	const TAXONOMY_PRODUCT = 'cha_product';

	/**
	 * Taxonomy name for feedback categories
	 */
	const TAXONOMY_FEEDBACK_CATEGORY = 'cha_feedback_category';

	/**
	 * Taxonomy name for release badges
	 */
	const TAXONOMY_RELEASE_BADGE = 'cha_release_badge';

	/**
	 * Roadmap item post type name (registered by pro plugin)
	 */
	const POST_TYPE_ROADMAP = 'cha_roadmap_item';

	/**
	 * Initialize the class
	 *
	 * @return void
	 */
	public static function init(): void {
		add_action( 'init', [ __CLASS__, 'register_post_types' ] );
		add_action( 'init', [ __CLASS__, 'register_taxonomies' ] );
	}

	/**
	 * Register custom post types
	 *
	 * @return void
	 */
	public static function register_post_types(): void {
		// Release post type
		$release_labels = [
			'name'                  => _x( 'Releases', 'Post type general name', 'changeloger' ),
			'singular_name'         => _x( 'Release', 'Post type singular name', 'changeloger' ),
			'menu_name'             => _x( 'Releases', 'Admin Menu text', 'changeloger' ),
			'name_admin_bar'        => _x( 'Release', 'Add New on Toolbar', 'changeloger' ),
			'add_new'               => __( 'Add New', 'changeloger' ),
			'add_new_item'          => __( 'Add New Release', 'changeloger' ),
			'new_item'              => __( 'New Release', 'changeloger' ),
			'edit_item'             => __( 'Edit Release', 'changeloger' ),
			'view_item'             => __( 'View Release', 'changeloger' ),
			'all_items'             => __( 'All Releases', 'changeloger' ),
			'search_items'          => __( 'Search Releases', 'changeloger' ),
			'parent_item_colon'     => __( 'Parent Releases:', 'changeloger' ),
			'not_found'             => __( 'No releases found.', 'changeloger' ),
			'not_found_in_trash'    => __( 'No releases found in Trash.', 'changeloger' ),
			'featured_image'        => _x( 'Release Cover Image', 'Overrides the "Featured Image" phrase', 'changeloger' ),
			'set_featured_image'    => _x( 'Set cover image', 'Overrides the "Set featured image" phrase', 'changeloger' ),
			'remove_featured_image' => _x( 'Remove cover image', 'Overrides the "Remove featured image" phrase', 'changeloger' ),
			'use_featured_image'    => _x( 'Use as cover image', 'Overrides the "Use as featured image" phrase', 'changeloger' ),
			'archives'              => _x( 'Release archives', 'The post type archive label', 'changeloger' ),
			'insert_into_item'      => _x( 'Insert into release', 'Overrides the "Insert into post" phrase', 'changeloger' ),
			'uploaded_to_this_item' => _x( 'Uploaded to this release', 'Overrides the "Uploaded to this post" phrase', 'changeloger' ),
			'filter_items_list'     => _x( 'Filter releases list', 'Screen reader text', 'changeloger' ),
			'items_list_navigation' => _x( 'Releases list navigation', 'Screen reader text', 'changeloger' ),
			'items_list'            => _x( 'Releases list', 'Screen reader text', 'changeloger' ),
		];

		$release_args = [
			'labels'             => $release_labels,
			'public'             => false,
			'publicly_queryable' => true,
			'show_ui'            => true,
			'show_in_menu'       => false,
			'query_var'          => true,
			'rewrite'            => [ 'slug' => 'release' ],
			'capability_type'    => 'post',
			'has_archive'        => false,
			'hierarchical'       => false,
			'menu_position'      => null,
			'supports'           => [ 'title', 'editor', 'comments' ],
			'show_in_rest'       => true,
			'rest_base'          => 'cha-releases',
		];

		register_post_type( self::POST_TYPE, $release_args );

		// Feedback post type.
		$feedback_labels = [
			'name'               => _x( 'Feedback Requests', 'Post type general name', 'changeloger' ),
			'singular_name'      => _x( 'Feedback', 'Post type singular name', 'changeloger' ),
			'menu_name'          => _x( 'Feedback', 'Admin Menu text', 'changeloger' ),
			'name_admin_bar'     => _x( 'Feedback', 'Add New on Toolbar', 'changeloger' ),
			'add_new'            => __( 'Add New', 'changeloger' ),
			'add_new_item'       => __( 'Add New Feedback', 'changeloger' ),
			'new_item'           => __( 'New Feedback', 'changeloger' ),
			'edit_item'          => __( 'Edit Feedback', 'changeloger' ),
			'view_item'          => __( 'View Feedback', 'changeloger' ),
			'all_items'          => __( 'All Feedback', 'changeloger' ),
			'search_items'       => __( 'Search Feedback', 'changeloger' ),
			'not_found'          => __( 'No feedback found.', 'changeloger' ),
			'not_found_in_trash' => __( 'No feedback found in Trash.', 'changeloger' ),
		];

		$feedback_args = [
			'labels'             => $feedback_labels,
			'public'             => false,
			'publicly_queryable' => true,
			'show_ui'            => true,
			'show_in_menu'       => false,
			'query_var'          => true,
			'rewrite'            => [ 'slug' => 'feedback' ],
			'capability_type'    => 'post',
			'has_archive'        => false,
			'hierarchical'       => false,
			'menu_position'      => null,
			'supports'           => [ 'title', 'editor', 'author', 'comments' ],
			'show_in_rest'       => true,
			'rest_base'          => 'cha-feedback',
		];

		register_post_type( self::POST_TYPE_FEEDBACK, $feedback_args );

		/**
		 * Action hook for pro plugin to register additional post types
		 *
		 * Pro plugin registers:
		 * - cha_roadmap_item (Roadmap post type)
		 */
		do_action( 'changeloger_register_post_types' );
	}

	/**
	 * Register taxonomies
	 *
	 * @return void
	 */
	public static function register_taxonomies(): void {
		// Product taxonomy
		$product_labels = [
			'name'                       => _x( 'Products', 'Taxonomy general name', 'changeloger' ),
			'singular_name'              => _x( 'Product', 'Taxonomy singular name', 'changeloger' ),
			'search_items'               => __( 'Search Products', 'changeloger' ),
			'popular_items'              => __( 'Popular Products', 'changeloger' ),
			'all_items'                  => __( 'All Products', 'changeloger' ),
			'parent_item'                => null,
			'parent_item_colon'          => null,
			'edit_item'                  => __( 'Edit Product', 'changeloger' ),
			'update_item'                => __( 'Update Product', 'changeloger' ),
			'add_new_item'               => __( 'Add New Product', 'changeloger' ),
			'new_item_name'              => __( 'New Product Name', 'changeloger' ),
			'separate_items_with_commas' => __( 'Separate products with commas', 'changeloger' ),
			'add_or_remove_items'        => __( 'Add or remove products', 'changeloger' ),
			'choose_from_most_used'      => __( 'Choose from the most used products', 'changeloger' ),
			'not_found'                  => __( 'No products found.', 'changeloger' ),
			'menu_name'                  => __( 'Products', 'changeloger' ),
		];

		$product_args = [
			'hierarchical'          => false,
			'labels'                => $product_labels,
			'show_ui'               => false,
			'show_in_menu'          => false,
			'show_admin_column'     => true,
			'update_count_callback' => '_update_post_term_count',
			'query_var'             => true,
			'rewrite'               => [ 'slug' => 'product' ],
			'show_in_rest'          => true,
			'rest_base'             => 'cha-products',
			'meta_box_cb'           => false,
		];

		// Register for releases and feedback.
		register_taxonomy( self::TAXONOMY_PRODUCT, [ self::POST_TYPE, self::POST_TYPE_FEEDBACK ], $product_args );

		// Release Badge taxonomy.
		$badge_labels = [
			'name'                       => _x( 'Release Badges', 'Taxonomy general name', 'changeloger' ),
			'singular_name'              => _x( 'Badge', 'Taxonomy singular name', 'changeloger' ),
			'search_items'               => __( 'Search Badges', 'changeloger' ),
			'popular_items'              => __( 'Popular Badges', 'changeloger' ),
			'all_items'                  => __( 'All Badges', 'changeloger' ),
			'parent_item'                => null,
			'parent_item_colon'          => null,
			'edit_item'                  => __( 'Edit Badge', 'changeloger' ),
			'update_item'                => __( 'Update Badge', 'changeloger' ),
			'add_new_item'               => __( 'Add New Badge', 'changeloger' ),
			'new_item_name'              => __( 'New Badge Name', 'changeloger' ),
			'separate_items_with_commas' => __( 'Separate badges with commas', 'changeloger' ),
			'add_or_remove_items'        => __( 'Add or remove badges', 'changeloger' ),
			'choose_from_most_used'      => __( 'Choose from the most used badges', 'changeloger' ),
			'not_found'                  => __( 'No badges found.', 'changeloger' ),
			'menu_name'                  => __( 'Badges', 'changeloger' ),
		];

		$badge_args = [
			'hierarchical'          => false,
			'labels'                => $badge_labels,
			'show_ui'               => false,
			'show_in_menu'          => false,
			'show_admin_column'     => true,
			'update_count_callback' => '_update_post_term_count',
			'query_var'             => true,
			'rewrite'               => [ 'slug' => 'release-badge' ],
			'show_in_rest'          => true,
			'rest_base'             => 'cha-release-badges',
			'meta_box_cb'           => false,
		];

		register_taxonomy( self::TAXONOMY_RELEASE_BADGE, self::POST_TYPE, $badge_args );

		// Feedback category taxonomy.
		$fb_cat_labels = [
			'name'              => _x( 'Feedback Categories', 'Taxonomy general name', 'changeloger' ),
			'singular_name'     => _x( 'Category', 'Taxonomy singular name', 'changeloger' ),
			'search_items'      => __( 'Search Categories', 'changeloger' ),
			'all_items'         => __( 'All Categories', 'changeloger' ),
			'edit_item'         => __( 'Edit Category', 'changeloger' ),
			'update_item'       => __( 'Update Category', 'changeloger' ),
			'add_new_item'      => __( 'Add New Category', 'changeloger' ),
			'new_item_name'     => __( 'New Category Name', 'changeloger' ),
			'menu_name'         => __( 'Categories', 'changeloger' ),
		];

		$fb_cat_args = [
			'hierarchical'      => false,
			'labels'            => $fb_cat_labels,
			'show_ui'           => true,
			'show_in_menu'      => false,
			'show_admin_column' => true,
			'query_var'         => true,
			'rewrite'           => [ 'slug' => 'feedback-category' ],
			'show_in_rest'      => true,
			'rest_base'         => 'cha-feedback-categories',
		];

		register_taxonomy( self::TAXONOMY_FEEDBACK_CATEGORY, self::POST_TYPE_FEEDBACK, $fb_cat_args );

		/**
		 * Action hook for pro plugin to register additional taxonomies
		 */
		do_action( 'changeloger_register_taxonomies' );
	}

	/**
	 * Get release badges from CSF settings
	 *
	 * @return array Array of badges with id, name, slug, and color.
	 */
	public static function get_release_badges(): array {
		// Get badges from CSF settings
		$settings = get_option( 'changeloger_settings', [] );
		$badges   = isset( $settings['release_badges'] ) ? $settings['release_badges'] : [];

		// If no badges configured, return defaults
		if ( empty( $badges ) ) {
			$badges = [
				[ 'name' => 'Major', 'color' => '#6366F1' ],
				[ 'name' => 'Minor', 'color' => '#22C55E' ],
				[ 'name' => 'Patch', 'color' => '#F59E0B' ],
				[ 'name' => 'Beta', 'color' => '#EF4444' ],
			];
		}

		$result = [];
		foreach ( $badges as $index => $badge ) {
			if ( empty( $badge['name'] ) ) {
				continue;
			}
			$result[] = [
				'id'    => $index,
				'name'  => $badge['name'],
				'slug'  => sanitize_title( $badge['name'] ),
				'color' => ! empty( $badge['color'] ) ? $badge['color'] : '#6366F1',
			];
		}

		return $result;
	}

	/**
	 * Create default release badges
	 *
	 * Called during plugin activation to seed initial badges.
	 *
	 * @return void
	 */
	public static function create_default_badges(): void {
		$default_badges = [
			[
				'name'  => __( 'Major', 'changeloger' ),
				'slug'  => 'major',
				'color' => '#EF4444',
				'order' => 1,
			],
			[
				'name'  => __( 'Minor', 'changeloger' ),
				'slug'  => 'minor',
				'color' => '#3B82F6',
				'order' => 2,
			],
			[
				'name'  => __( 'Beta', 'changeloger' ),
				'slug'  => 'beta',
				'color' => '#F59E0B',
				'order' => 3,
			],
			[
				'name'  => __( 'Patch', 'changeloger' ),
				'slug'  => 'patch',
				'color' => '#10B981',
				'order' => 4,
			],
		];

		foreach ( $default_badges as $badge_data ) {
			// Check if term already exists.
			$existing = term_exists( $badge_data['slug'], self::TAXONOMY_RELEASE_BADGE );
			if ( $existing ) {
				continue;
			}

			$term = wp_insert_term(
				$badge_data['name'],
				self::TAXONOMY_RELEASE_BADGE,
				[ 'slug' => $badge_data['slug'] ]
			);

			if ( ! is_wp_error( $term ) ) {
				update_term_meta( $term['term_id'], '_badge_color', $badge_data['color'] );
				update_term_meta( $term['term_id'], '_badge_order', $badge_data['order'] );
			}
		}
	}

	/**
	 * Migrate old release_type meta to badge taxonomy
	 *
	 * @return int Number of releases migrated.
	 */
	public static function migrate_release_types_to_badges(): int {
		global $wpdb;

		// Ensure default badges exist.
		self::create_default_badges();

		// Get all releases with old release_type meta.
		$releases = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE meta_key = %s",
				'_cha_release_type'
			)
		);

		if ( empty( $releases ) ) {
			return 0;
		}

		$migrated = 0;

		foreach ( $releases as $release ) {
			$type_slug = sanitize_key( $release->meta_value );

			// Find corresponding badge term.
			$term = get_term_by( 'slug', $type_slug, self::TAXONOMY_RELEASE_BADGE );

			if ( $term ) {
				// Assign badge to release.
				wp_set_object_terms( $release->post_id, $term->term_id, self::TAXONOMY_RELEASE_BADGE );

				// Delete old meta.
				delete_post_meta( $release->post_id, '_cha_release_type' );

				++$migrated;
			}
		}

		return $migrated;
	}

	/**
	 * Get change item groups
	 *
	 * @return array
	 */
	public static function get_change_groups(): array {
		// Static cache to avoid repeated DB calls within same request.
		static $cached_groups = null;

		if ( null !== $cached_groups ) {
			return $cached_groups;
		}

		// Get settings.
		$settings      = get_option( 'changeloger_settings', [] );
		$custom_groups = isset( $settings['change_groups'] ) ? $settings['change_groups'] : [];

		// Build from custom groups if defined.
		if ( ! empty( $custom_groups ) && is_array( $custom_groups ) ) {
			$groups = [];
			foreach ( $custom_groups as $group ) {
				if ( ! empty( $group['name'] ) ) {
					// Auto-generate slug from name (e.g., "Recent Updates" -> "recent-updates").
					$slug            = sanitize_title( $group['name'] );
					$groups[ $slug ] = $group['name'];
				}
			}
			if ( ! empty( $groups ) ) {
				$cached_groups = $groups;
				return $cached_groups;
			}
		}

		// Default fallback.
		$cached_groups = [
			'improvements' => __( 'Improvements', 'changeloger' ),
			'fixes'        => __( 'Fixes', 'changeloger' ),
			'patches'      => __( 'Patches', 'changeloger' ),
		];

		return $cached_groups;
	}

	/**
	 * Generate a slug from a status name
	 *
	 * @param string $name The status display name.
	 * @return string
	 */
	private static function generate_status_slug( string $name ): string {
		return str_replace( '-', '_', sanitize_title( $name ) );
	}

	/**
	 * Get the default roadmap status definitions
	 *
	 * @return array
	 */
	private static function get_default_roadmap_statuses(): array {
		return [
			[ 'name' => 'Planned',     'color' => '#3b82f6' ],
			[ 'name' => 'In Progress', 'color' => '#f59e0b' ],
			[ 'name' => 'Completed',   'color' => '#10b981' ],
			[ 'name' => 'Rejected',    'color' => '#ef4444' ],
		];
	}

	/**
	 * Get feedback statuses
	 *
	 * Combines 'In Review' with dynamic roadmap statuses from settings.
	 *
	 * @return array Slug => label pairs.
	 */
	public static function get_feedback_statuses(): array {
		$statuses = [
			'in_review' => __( 'In Review', 'changeloger' ),
		];

		$roadmap_statuses = self::get_roadmap_statuses();
		foreach ( $roadmap_statuses as $slug => $label ) {
			$statuses[ $slug ] = $label;
		}

		return $statuses;
	}

	/**
	 * Get roadmap statuses from settings
	 *
	 * @return array Slug => label pairs.
	 */
	public static function get_roadmap_statuses(): array {
		if ( class_exists( 'Changeloger_Pro_Post_Types' ) ) {
			return Changeloger_Pro_Post_Types::get_roadmap_statuses();
		}

		$columns  = self::get_roadmap_columns();
		$statuses = [];

		foreach ( $columns as $slug => $data ) {
			$statuses[ $slug ] = $data['label'];
		}

		return $statuses;
	}

	/**
	 * Get roadmap columns
	 *
	 * @return array
	 */
	public static function get_roadmap_columns(): array {
		if ( class_exists( 'Changeloger_Pro_Post_Types' ) ) {
			return Changeloger_Pro_Post_Types::get_roadmap_columns();
		}

		$settings       = get_option( 'changeloger_settings', [] );
		$saved_statuses = isset( $settings['roadmap_statuses'] ) ? $settings['roadmap_statuses'] : [];

		// Fall back to defaults if empty or not an array.
		if ( empty( $saved_statuses ) || ! is_array( $saved_statuses ) ) {
			$saved_statuses = self::get_default_roadmap_statuses();
		}

		$columns = [];
		foreach ( $saved_statuses as $entry ) {
			if ( empty( $entry['name'] ) ) {
				continue;
			}
			$slug             = self::generate_status_slug( $entry['name'] );
			$columns[ $slug ] = [
				'label' => $entry['name'],
				'color' => ! empty( $entry['color'] ) ? $entry['color'] : '#6366F1',
			];
		}

		return $columns;
	}

	/**
	 * Get feedback categories from database
	 *
	 * @return array slug => name pairs.
	 */
	public static function get_feedback_categories(): array {
		$terms = get_terms(
			[
				'taxonomy'   => self::TAXONOMY_FEEDBACK_CATEGORY,
				'hide_empty' => false,
				'orderby'    => 'name',
				'order'      => 'ASC',
			]
		);

		if ( is_wp_error( $terms ) || empty( $terms ) ) {
			return self::get_default_feedback_categories();
		}

		$categories = [];
		foreach ( $terms as $term ) {
			$categories[ $term->slug ] = $term->name;
		}

		return $categories;
	}

	/**
	 * Get default feedback categories
	 *
	 * @return array
	 */
	public static function get_default_feedback_categories(): array {
		return [
			'feature-requests' => __( 'Feature Requests', 'changeloger' ),
			'bug-reports'      => __( 'Bug Reports', 'changeloger' ),
			'integrations'     => __( 'Integrations', 'changeloger' ),
			'languages'        => __( 'Languages', 'changeloger' ),
		];
	}

	/**
	 * Create default feedback categories if they don't exist
	 *
	 * @return void
	 */
	public static function create_default_feedback_categories(): void {
		$categories = self::get_default_feedback_categories();

		foreach ( $categories as $slug => $name ) {
			if ( ! term_exists( $slug, self::TAXONOMY_FEEDBACK_CATEGORY ) ) {
				wp_insert_term( $name, self::TAXONOMY_FEEDBACK_CATEGORY, [ 'slug' => $slug ] );
			}
		}
	}

	/**
	 * Get feedback status label
	 *
	 * @param string $status Status key.
	 * @return string
	 */
	public static function get_feedback_status_label( string $status ): string {
		$statuses = self::get_feedback_statuses();
		return isset( $statuses[ $status ] ) ? $statuses[ $status ] : $status;
	}

	/**
	 * Get roadmap status label
	 *
	 * @param string $status Status key.
	 * @return string
	 */
	public static function get_roadmap_status_label( string $status ): string {
		$statuses = self::get_roadmap_statuses();
		return isset( $statuses[ $status ] ) ? $statuses[ $status ] : $status;
	}
}
