<?php
/**
 * Post Meta Manager
 *
 * @package SEOvaultSEO
 */

namespace SEOvaultSEO\Core;

/**
 * Handles SEO post meta with safe getter/setter methods
 */
class PostMeta {

	/**
	 * Meta key prefix
	 */
	const PREFIX = '_seovault_';

	/**
	 * Get post meta value
	 *
	 * @param int    $post_id Post ID
	 * @param string $key Meta key (without prefix)
	 * @param mixed  $default Default value
	 * @return mixed
	 */
	public static function get( $post_id, $key, $default = '' ) {
		return get_post_meta( $post_id, self::PREFIX . $key, true );
	}

	/**
	 * Set post meta value
	 *
	 * @param int    $post_id Post ID
	 * @param string $key Meta key (without prefix)
	 * @param mixed  $value Meta value
	 * @return bool|int
	 */
	public static function set( $post_id, $key, $value ) {
		return update_post_meta( $post_id, self::PREFIX . $key, $value );
	}

	/**
	 * Delete post meta value
	 *
	 * @param int    $post_id Post ID
	 * @param string $key Meta key (without prefix)
	 * @return bool
	 */
	public static function delete( $post_id, $key ) {
		return delete_post_meta( $post_id, self::PREFIX . $key );
	}

	// SEO Title

	/**
	 * Get SEO title
	 *
	 * @param int $post_id Post ID
	 * @return string
	 */
	public static function get_seo_title( $post_id ) {
		return self::get( $post_id, 'seo_title', '' );
	}

	/**
	 * Set SEO title
	 *
	 * @param int    $post_id Post ID
	 * @param string $title SEO title
	 * @return bool|int
	 */
	public static function set_seo_title( $post_id, $title ) {
		return self::set( $post_id, 'seo_title', $title );
	}

	// SEO Description

	/**
	 * Get SEO description
	 *
	 * @param int $post_id Post ID
	 * @return string
	 */
	public static function get_seo_description( $post_id ) {
		return self::get( $post_id, 'seo_description', '' );
	}

	/**
	 * Set SEO description
	 *
	 * @param int    $post_id Post ID
	 * @param string $description SEO description
	 * @return bool|int
	 */
	public static function set_seo_description( $post_id, $description ) {
		return self::set( $post_id, 'seo_description', $description );
	}

	// Focus Keyword

	/**
	 * Get focus keyword
	 *
	 * @param int $post_id Post ID
	 * @return string
	 */
	public static function get_focus_keyword( $post_id ) {
		return self::get( $post_id, 'focus_keyword', '' );
	}

	/**
	 * Set focus keyword
	 *
	 * @param int    $post_id Post ID
	 * @param string $keyword Focus keyword
	 * @return bool|int
	 */
	public static function set_focus_keyword( $post_id, $keyword ) {
		return self::set( $post_id, 'focus_keyword', $keyword );
	}

	// Secondary Keywords

	/**
	 * Get secondary keywords
	 *
	 * @param int $post_id Post ID
	 * @return string
	 */
	public static function get_secondary_keywords( $post_id ) {
		return self::get( $post_id, 'secondary_keywords', '' );
	}

	/**
	 * Set secondary keywords
	 *
	 * @param int    $post_id Post ID
	 * @param string $keywords Secondary keywords
	 * @return bool|int
	 */
	public static function set_secondary_keywords( $post_id, $keywords ) {
		return self::set( $post_id, 'secondary_keywords', $keywords );
	}

	// Canonical URL

	/**
	 * Get canonical URL
	 *
	 * @param int $post_id Post ID
	 * @return string
	 */
	public static function get_canonical_url( $post_id ) {
		return self::get( $post_id, 'canonical_url', '' );
	}

	/**
	 * Set canonical URL
	 *
	 * @param int    $post_id Post ID
	 * @param string $url Canonical URL
	 * @return bool|int
	 */
	public static function set_canonical_url( $post_id, $url ) {
		return self::set( $post_id, 'canonical_url', $url );
	}

	// Robots - Noindex

	/**
	 * Check if noindex is set
	 *
	 * @param int $post_id Post ID
	 * @return bool
	 */
	public static function is_noindex( $post_id ) {
		return (bool) self::get( $post_id, 'robots_noindex', false );
	}

	/**
	 * Whether an explicit per-post robots_noindex value is stored.
	 *
	 * Absence means inherit post-type / global robots rules. Presence of a
	 * falsy value means an explicit "index" override (e.g. Yoast force-index).
	 *
	 * @param int $post_id Post ID.
	 * @return bool
	 */
	public static function has_noindex_meta( $post_id ) {
		return metadata_exists( 'post', (int) $post_id, self::PREFIX . 'robots_noindex' );
	}

	/**
	 * Set noindex
	 *
	 * @param int  $post_id Post ID
	 * @param bool $noindex Whether to noindex
	 * @return bool|int
	 */
	public static function set_noindex( $post_id, $noindex ) {
		return self::set( $post_id, 'robots_noindex', (bool) $noindex );
	}

	// Robots - Nofollow

	/**
	 * Check if nofollow is set
	 *
	 * @param int $post_id Post ID
	 * @return bool
	 */
	public static function is_nofollow( $post_id ) {
		return (bool) self::get( $post_id, 'robots_nofollow', false );
	}

	/**
	 * Set nofollow
	 *
	 * @param int  $post_id Post ID
	 * @param bool $nofollow Whether to nofollow
	 * @return bool|int
	 */
	public static function set_nofollow( $post_id, $nofollow ) {
		return self::set( $post_id, 'robots_nofollow', (bool) $nofollow );
	}

	// Open Graph Title

	/**
	 * Get OG title
	 *
	 * @param int $post_id Post ID
	 * @return string
	 */
	public static function get_og_title( $post_id ) {
		return self::get( $post_id, 'og_title', '' );
	}

	/**
	 * Set OG title
	 *
	 * @param int    $post_id Post ID
	 * @param string $title OG title
	 * @return bool|int
	 */
	public static function set_og_title( $post_id, $title ) {
		return self::set( $post_id, 'og_title', $title );
	}

	// Open Graph Description

	/**
	 * Get OG description
	 *
	 * @param int $post_id Post ID
	 * @return string
	 */
	public static function get_og_description( $post_id ) {
		return self::get( $post_id, 'og_description', '' );
	}

	/**
	 * Set OG description
	 *
	 * @param int    $post_id Post ID
	 * @param string $description OG description
	 * @return bool|int
	 */
	public static function set_og_description( $post_id, $description ) {
		return self::set( $post_id, 'og_description', $description );
	}

	// Open Graph Image

	/**
	 * Get OG image
	 *
	 * @param int $post_id Post ID
	 * @return string
	 */
	public static function get_og_image( $post_id ) {
		return self::get( $post_id, 'og_image', '' );
	}

	/**
	 * Set OG image
	 *
	 * @param int    $post_id Post ID
	 * @param string $url OG image URL
	 * @return bool|int
	 */
	public static function set_og_image( $post_id, $url ) {
		return self::set( $post_id, 'og_image', $url );
	}

	// Schema JSON

	/**
	 * Get schema JSON
	 *
	 * @param int $post_id Post ID
	 * @return string
	 */
	public static function get_schema_json( $post_id ) {
		return self::get( $post_id, 'schema_json', '' );
	}

	/**
	 * Set schema JSON
	 *
	 * @param int    $post_id Post ID
	 * @param string $json Schema JSON
	 * @return bool|int
	 */
	public static function set_schema_json( $post_id, $json ) {
		return self::set( $post_id, 'schema_json', $json );
	}

	/**
	 * Delete schema JSON
	 *
	 * @param int $post_id Post ID
	 * @return bool
	 */
	public static function delete_schema_json( $post_id ) {
		return self::delete( $post_id, 'schema_json' );
	}

	// Redirect URL

	/**
	 * Get redirect URL.
	 *
	 * @param int $post_id Post ID.
	 * @return string
	 */
	public static function get_redirect_url( $post_id ) {
		return self::get( $post_id, 'redirect_url', '' );
	}

	/**
	 * Set redirect URL.
	 *
	 * @param int    $post_id Post ID.
	 * @param string $url     Redirect target URL.
	 * @return bool|int
	 */
	public static function set_redirect_url( $post_id, $url ) {
		return self::set( $post_id, 'redirect_url', $url );
	}

	/**
	 * Delete redirect URL.
	 *
	 * @param int $post_id Post ID.
	 * @return bool
	 */
	public static function delete_redirect_url( $post_id ) {
		return self::delete( $post_id, 'redirect_url' );
	}

	// Redirect Type

	/**
	 * Get redirect type (301 or 302).
	 *
	 * @param int $post_id Post ID.
	 * @return int Redirect type code (301 or 302). Default 301.
	 */
	public static function get_redirect_type( $post_id ) {
		$type = (int) self::get( $post_id, 'redirect_type', 301 );
		return in_array( $type, array( 301, 302 ), true ) ? $type : 301;
	}

	/**
	 * Set redirect type.
	 *
	 * @param int $post_id Post ID.
	 * @param int $type    Redirect type (301 or 302).
	 * @return bool|int
	 */
	public static function set_redirect_type( $post_id, $type ) {
		$type = in_array( (int) $type, array( 301, 302 ), true ) ? (int) $type : 301;
		return self::set( $post_id, 'redirect_type', $type );
	}

	// Frontend Score visibility

	/**
	 * Check if frontend score is hidden for this post.
	 *
	 * @param int $post_id Post ID.
	 * @return bool
	 */
	public static function is_frontend_score_hidden( $post_id ) {
		return (bool) self::get( $post_id, 'hide_frontend_score', false );
	}

	/**
	 * Set frontend score hidden status for a post.
	 *
	 * @param int  $post_id Post ID.
	 * @param bool $hidden  Whether to hide the score.
	 * @return bool|int
	 */
	public static function set_frontend_score_hidden( $post_id, $hidden ) {
		return self::set( $post_id, 'hide_frontend_score', (bool) $hidden );
	}
}
