<?php
/**
 * Livada SEO — Admin Metabox
 *
 * Registers the SEO metabox on post/page edit screens, enqueues its assets,
 * and handles saving all `_livada_seo_*` post meta fields.
 *
 * @package Livada_SEO
 */

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

class Livada_SEO_Metabox {

	// ── Bootstrap ─────────────────────────────────────────────────────────────

	public static function init(): void {
		add_action( 'add_meta_boxes',       [ __CLASS__, 'register_metabox'  ] );
		add_action( 'save_post',            [ __CLASS__, 'save_meta'         ] );
		add_action( 'admin_enqueue_scripts', [ __CLASS__, 'enqueue_assets'   ] );
	}

	// ── Metabox registration ───────────────────────────────────────────────────

	/**
	 * Registers the SEO metabox for post and page post types.
	 */
	public static function register_metabox(): void {
		$post_types = [ 'post', 'page' ];

		foreach ( $post_types as $post_type ) {
			add_meta_box(
				'livada_seo_metabox',
				__( 'Livada SEO', 'livada-seo' ),
				[ __CLASS__, 'render_metabox' ],
				$post_type,
				'normal',
				'high'
			);
		}
	}

	// ── Metabox render ─────────────────────────────────────────────────────────

	/**
	 * Outputs the metabox HTML by loading the view template.
	 *
	 * @param WP_Post $post Current post object.
	 */
	public static function render_metabox( WP_Post $post ): void {
		$view = LIVADA_SEO_PATH . 'includes/admin/views/metabox.php';

		if ( file_exists( $view ) ) {
			require $view;
		}
	}

	// ── Asset enqueue ──────────────────────────────────────────────────────────

	/**
	 * Enqueues metabox JS and the shared admin CSS only on post edit screens.
	 *
	 * @param string $hook_suffix Current admin page hook.
	 */
	public static function enqueue_assets( string $hook_suffix ): void {
		if ( ! in_array( $hook_suffix, [ 'post.php', 'post-new.php' ], true ) ) {
			return;
		}

		// Admin stylesheet (shared; created by Task 11).
		wp_enqueue_style(
			'livada-seo-admin',
			LIVADA_SEO_URL . 'assets/css/admin.css',
			[],
			LIVADA_SEO_VERSION
		);

		// Metabox JavaScript.
		wp_enqueue_script(
			'livada-seo-metabox',
			LIVADA_SEO_URL . 'assets/js/metabox.js',
			[],                  // no jQuery dependency
			LIVADA_SEO_VERSION,
			true                 // footer
		);

		// Inline data for the JS (post permalink for SERP preview + AJAX nonce
		// for live features like link suggestions + REST URL/nonce for the
		// schema preview panel).
		$post_id = get_the_ID();
		wp_add_inline_script(
			'livada-seo-metabox',
			'window.livadaSEO = ' . wp_json_encode(
				[
					'permalink'  => $post_id ? get_permalink( $post_id ) : '',
					'nonce'      => wp_create_nonce( 'livada_seo_save_metabox' ),
					'adminNonce' => wp_create_nonce( 'livada_seo_admin_nonce' ),
					'ajaxUrl'    => admin_url( 'admin-ajax.php' ),
					'restUrl'    => esc_url_raw( rest_url() ),
					'restNonce'  => wp_create_nonce( 'wp_rest' ),
				]
			) . ';',
			'before'
		);

		// Media library for OG image picker.
		wp_enqueue_media();
	}

	// ── Save handler ───────────────────────────────────────────────────────────

	/**
	 * Saves all `_livada_seo_*` meta fields when a post is saved.
	 *
	 * Guards: nonce verification, capability check, autosave skip, revision skip.
	 *
	 * @param int $post_id Post being saved.
	 */
	public static function save_meta( int $post_id ): void {

		// 1. Nonce check.
		if (
			! isset( $_POST['livada_seo_metabox_nonce'] ) ||
			! wp_verify_nonce(
				sanitize_text_field( wp_unslash( $_POST['livada_seo_metabox_nonce'] ) ),
				'livada_seo_save_metabox'
			)
		) {
			return;
		}

		// 2. Capability check.
		if ( ! current_user_can( 'edit_post', $post_id ) ) {
			return;
		}

		// 3. Skip autosave.
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
			return;
		}

		// 4. Skip revisions.
		if ( wp_is_post_revision( $post_id ) ) {
			return;
		}

		// ── Text fields ───────────────────────────────────────────────────────

		$text_fields = [
			'_livada_seo_title'         => 'sanitize_text_field',
			'_livada_seo_focus_keyword' => 'sanitize_text_field',
		];

		foreach ( $text_fields as $meta_key => $sanitizer ) {
			// Form fields use the full meta key (e.g. `_livada_seo_title`) as name.
			if ( isset( $_POST[ $meta_key ] ) ) {
				$value = $sanitizer( wp_unslash( $_POST[ $meta_key ] ) );
				update_post_meta( $post_id, $meta_key, $value );
			}
		}

		// ── Textarea fields ───────────────────────────────────────────────────

		if ( isset( $_POST['_livada_seo_description'] ) ) {
			update_post_meta(
				$post_id,
				'_livada_seo_description',
				sanitize_textarea_field( wp_unslash( $_POST['_livada_seo_description'] ) )
			);
		}

		// ── URL fields ────────────────────────────────────────────────────────

		$url_fields = [ '_livada_seo_canonical', '_livada_seo_og_image' ];

		foreach ( $url_fields as $meta_key ) {
			if ( isset( $_POST[ $meta_key ] ) ) {
				$value = esc_url_raw( wp_unslash( $_POST[ $meta_key ] ) );
				update_post_meta( $post_id, $meta_key, $value );
			}
		}

		// ── Checkbox fields ───────────────────────────────────────────────────

		$checkbox_fields = [
			'_livada_seo_noindex',
			'_livada_seo_nofollow',
			'_livada_seo_service_schema',
			'_livada_seo_faq_schema',
			'_livada_seo_sitemap_exclude',
			'_livada_seo_cornerstone',
		];

		foreach ( $checkbox_fields as $meta_key ) {
			if ( ! empty( $_POST[ $meta_key ] ) ) {
				update_post_meta( $post_id, $meta_key, '1' );
			} else {
				delete_post_meta( $post_id, $meta_key );
			}
		}

		// ── Whitelisted select: schema content type ───────────────────────────

		$allowed_schemas = [ '', 'HowTo', 'Product', 'Event', 'Recipe', 'Review', 'Offer' ];
		$schema_type     = isset( $_POST['_livada_seo_schema_type'] )
			? sanitize_text_field( wp_unslash( $_POST['_livada_seo_schema_type'] ) )
			: '';

		if ( in_array( $schema_type, $allowed_schemas, true ) && '' !== $schema_type ) {
			update_post_meta( $post_id, '_livada_seo_schema_type', $schema_type );
		} else {
			delete_post_meta( $post_id, '_livada_seo_schema_type' );
		}

		// ── Offer fields (only meaningful when schema_type === Offer) ────────

		$offer_text = [
			'_livada_seo_offer_price'         => 'sanitize_text_field',  // numeric stored as string
			'_livada_seo_offer_valid_from'    => 'sanitize_text_field',
			'_livada_seo_offer_valid_through' => 'sanitize_text_field',
		];

		foreach ( $offer_text as $key => $sanitizer ) {
			if ( ! isset( $_POST[ $key ] ) ) {
				continue;
			}
			$val = $sanitizer( wp_unslash( $_POST[ $key ] ) );
			if ( '' === $val ) {
				delete_post_meta( $post_id, $key );
			} else {
				update_post_meta( $post_id, $key, $val );
			}
		}

		if ( isset( $_POST['_livada_seo_offer_currency'] ) ) {
			$currency = strtoupper( sanitize_text_field( wp_unslash( $_POST['_livada_seo_offer_currency'] ) ) );
			$currency = preg_replace( '/[^A-Z]/', '', (string) $currency );
			$currency = substr( (string) $currency, 0, 3 );
			if ( '' === $currency ) {
				delete_post_meta( $post_id, '_livada_seo_offer_currency' );
			} else {
				update_post_meta( $post_id, '_livada_seo_offer_currency', $currency );
			}
		}

		$availability_allowed = [ 'in_stock', 'limited', 'sold_out', 'preorder', 'out_of_stock' ];
		if ( isset( $_POST['_livada_seo_offer_availability'] ) ) {
			$avail = sanitize_key( wp_unslash( $_POST['_livada_seo_offer_availability'] ) );
			if ( in_array( $avail, $availability_allowed, true ) ) {
				update_post_meta( $post_id, '_livada_seo_offer_availability', $avail );
			} else {
				delete_post_meta( $post_id, '_livada_seo_offer_availability' );
			}
		}

		// ── Linked business location (multi-location support) ────────────────

		if ( isset( $_POST['_livada_seo_location_id'] ) ) {
			$loc_raw = wp_unslash( $_POST['_livada_seo_location_id'] );
			if ( '' === $loc_raw ) {
				delete_post_meta( $post_id, '_livada_seo_location_id' );
			} else {
				$loc_id = max( 0, (int) $loc_raw );
				update_post_meta( $post_id, '_livada_seo_location_id', $loc_id );
			}
		}

		// ── Hreflang manual overrides ────────────────────────────────────────
		// Form arrives as `_livada_seo_hreflang[N][lang|url]`. Convert to a
		// flat `[ lang => url ]` array for the schema/hreflang module.

		if ( isset( $_POST['_livada_seo_hreflang'] ) && is_array( $_POST['_livada_seo_hreflang'] ) ) {
			$rows  = wp_unslash( $_POST['_livada_seo_hreflang'] ); // phpcs:ignore
			$clean = [];

			foreach ( $rows as $row ) {
				if ( ! is_array( $row ) ) {
					continue;
				}

				$lang = sanitize_text_field( (string) ( $row['lang'] ?? '' ) );
				$url  = esc_url_raw(    (string) ( $row['url']  ?? '' ) );

				if ( '' === $lang || '' === $url ) {
					continue;
				}

				// Normalise BCP-47 codes: lang lowercase, region uppercase, "_" → "-".
				$lang = str_replace( '_', '-', $lang );
				if ( 'x-default' !== $lang ) {
					if ( false !== strpos( $lang, '-' ) ) {
						$parts    = explode( '-', $lang, 2 );
						$lang     = strtolower( $parts[0] ) . '-' . strtoupper( $parts[1] );
					} else {
						$lang = strtolower( $lang );
					}
				}

				// Strip anything not a letter/digit/-/.
				$lang = preg_replace( '/[^A-Za-z0-9\-]/', '', $lang ) ?? '';
				if ( '' === $lang ) {
					continue;
				}

				$clean[ $lang ] = $url;
			}

			if ( empty( $clean ) ) {
				delete_post_meta( $post_id, '_livada_seo_hreflang' );
			} else {
				update_post_meta( $post_id, '_livada_seo_hreflang', $clean );
			}
		} else {
			// No rows submitted at all → clear any previously saved override.
			delete_post_meta( $post_id, '_livada_seo_hreflang' );
		}
	}
}
