<?php
/**
 * CPT + taxonomy registration for BW Map Magnet.
 */

defined( 'ABSPATH' ) || exit;

class BW_Map_Magnet_CPT {

	private static $instance = null;

	public static function instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	public function boot() {
		add_action( 'init', [ $this, 'register' ] );
		add_action( 'init', [ $this, 'register_meta' ] );
	}

	public function register() {
		register_post_type(
			BW_MAP_MAGNET_CPT,
			[
				'labels'        => [
					'name'               => __( 'Map Items', 'bw-map-magnet' ),
					'singular_name'      => __( 'Map Item', 'bw-map-magnet' ),
					'menu_name'          => __( 'Map Magnet', 'bw-map-magnet' ),
					'add_new'            => __( 'Add New', 'bw-map-magnet' ),
					'add_new_item'       => __( 'Add New Map Item', 'bw-map-magnet' ),
					'edit_item'          => __( 'Edit Map Item', 'bw-map-magnet' ),
					'new_item'           => __( 'New Map Item', 'bw-map-magnet' ),
					'view_item'          => __( 'View Map Item', 'bw-map-magnet' ),
					'search_items'       => __( 'Search Map Items', 'bw-map-magnet' ),
					'not_found'          => __( 'No map items found.', 'bw-map-magnet' ),
					'not_found_in_trash' => __( 'No map items in trash.', 'bw-map-magnet' ),
				],
				'public'        => true,
				'show_ui'       => true,
				'show_in_menu'  => true,
				'menu_icon'     => 'dashicons-location-alt',
				'menu_position' => 25,
				'supports'      => [ 'title', 'editor', 'thumbnail', 'excerpt', 'page-attributes' ],
				'has_archive'   => false,
				'rewrite'       => [ 'slug' => 'map-item' ],
				'show_in_rest'  => true,
			]
		);

		register_taxonomy(
			BW_MAP_MAGNET_TAX,
			BW_MAP_MAGNET_CPT,
			[
				'labels'            => [
					'name'          => __( 'Map Categories', 'bw-map-magnet' ),
					'singular_name' => __( 'Map Category', 'bw-map-magnet' ),
					'menu_name'     => __( 'Categories', 'bw-map-magnet' ),
					'all_items'     => __( 'All Categories', 'bw-map-magnet' ),
					'edit_item'     => __( 'Edit Category', 'bw-map-magnet' ),
					'add_new_item'  => __( 'Add New Category', 'bw-map-magnet' ),
					'new_item_name' => __( 'New Category Name', 'bw-map-magnet' ),
				],
				'hierarchical'      => true,
				'show_ui'           => true,
				'show_admin_column' => true,
				'show_in_rest'      => true,
				'rewrite'           => [ 'slug' => 'map-category' ],
			]
		);
	}

	public function register_meta() {
		$author_auth = function () {
			return current_user_can( 'edit_posts' );
		};

		register_post_meta(
			BW_MAP_MAGNET_CPT,
			'_bw_map_lat',
			[
				'type'              => 'number',
				'single'            => true,
				'show_in_rest'      => false,
				'sanitize_callback' => [ $this, 'sanitize_coord' ],
				'auth_callback'     => $author_auth,
			]
		);

		register_post_meta(
			BW_MAP_MAGNET_CPT,
			'_bw_map_lng',
			[
				'type'              => 'number',
				'single'            => true,
				'show_in_rest'      => false,
				'sanitize_callback' => [ $this, 'sanitize_coord' ],
				'auth_callback'     => $author_auth,
			]
		);

		register_post_meta(
			BW_MAP_MAGNET_CPT,
			'_bw_map_image_url',
			[
				'type'              => 'string',
				'single'            => true,
				'show_in_rest'      => false,
				'sanitize_callback' => 'esc_url_raw',
				'auth_callback'     => $author_auth,
			]
		);

		register_post_meta(
			BW_MAP_MAGNET_CPT,
			'_bw_map_focus_zoom',
			[
				'type'              => 'number',
				'single'            => true,
				'show_in_rest'      => false,
				'sanitize_callback' => function ( $v ) {
					if ( '' === $v || null === $v ) {
						return '';
					}
					$v = (int) $v;
					return max( 6, min( 19, $v ) );
				},
				'auth_callback'     => $author_auth,
			]
		);

		$term_auth = function () {
			return current_user_can( 'manage_categories' );
		};

		register_term_meta(
			BW_MAP_MAGNET_TAX,
			'_bw_map_icon',
			[
				'type'              => 'string',
				'single'            => true,
				'show_in_rest'      => false,
				'sanitize_callback' => [ $this, 'sanitize_icon_key' ],
				'auth_callback'     => $term_auth,
			]
		);

		register_term_meta(
			BW_MAP_MAGNET_TAX,
			'_bw_map_color',
			[
				'type'              => 'string',
				'single'            => true,
				'show_in_rest'      => false,
				'sanitize_callback' => [ $this, 'sanitize_hex_color' ],
				'auth_callback'     => $term_auth,
			]
		);
	}

	public function sanitize_icon_key( $value ) {
		$value = sanitize_key( (string) $value );
		if ( '' === $value ) {
			return '';
		}
		return BW_Map_Magnet_Icons::exists( $value ) ? $value : '';
	}

	public function sanitize_hex_color( $value ) {
		$value = trim( (string) $value );
		if ( '' === $value ) {
			return '';
		}
		$valid = sanitize_hex_color( $value );
		return $valid ? $valid : '';
	}

	public function sanitize_coord( $value ) {
		if ( '' === $value || null === $value ) {
			return '';
		}
		return (float) $value;
	}
}
