<?php
/**
 * Feed configuration accessor.
 *
 * @package Kramar
 * @since   1.0.0
 */

declare( strict_types=1 );

namespace Kramar\Modules\Marketing;

// Prevent direct access.
defined( 'ABSPATH' ) || exit;

/**
 * Typed accessor for all Google Shopping Feed module settings.
 *
 * @since 1.0.0
 */
final class Feed_Config {

	private const CATEGORY = 'marketing';
	private const SLUG     = 'google-shopping-feed';

	/**
	 * Constructor.
	 *
	 * @since 1.0.0
	 *
	 * @param \Kramar\Plugin $plugin Main plugin instance.
	 */
	public function __construct( private \Kramar\Plugin $plugin ) {}

	/** @return string 32-char hex token. */
	public function get_token(): string {
		return (string) ( $this->get( 'token' ) ?? '' );
	}

	/** @return string One of '6h', '12h', 'daily'. */
	public function get_schedule(): string {
		$v = (string) ( $this->get( 'schedule' ) ?? '6h' );
		return in_array( $v, [ '6h', '12h', 'daily' ], true ) ? $v : '6h';
	}

	/** @return string WC attribute slug for brand (e.g. 'pa_brand'). */
	public function get_brand_attribute(): string {
		return (string) ( $this->get( 'brand_attribute' ) ?? 'pa_brand' );
	}

	/** @return string Product meta key for MPN (e.g. '_mpn'). */
	public function get_mpn_meta_key(): string {
		return (string) ( $this->get( 'mpn_meta_key' ) ?? '_mpn' );
	}

	/** @return string Google numeric category ID string, or empty. */
	public function get_google_product_category(): string {
		return (string) ( $this->get( 'google_product_category' ) ?? '' );
	}

	/**
	 * WC product-category term id => Google product category (numeric id or path).
	 *
	 * @since 1.0.0
	 *
	 * @return array<int, string>
	 */
	public function get_category_map(): array {
		$v = $this->get( 'category_map' );
		if ( ! is_array( $v ) ) {
			return [];
		}
		$map = [];
		foreach ( $v as $term_id => $gcat ) {
			$map[ (int) $term_id ] = (string) $gcat;
		}
		return $map;
	}

	/** @return string 'all', 'default', or 'parent_only'. */
	public function get_variation_mode(): string {
		$v = (string) ( $this->get( 'variation_mode' ) ?? 'all' );
		return in_array( $v, [ 'all', 'default', 'parent_only' ], true ) ? $v : 'all';
	}

	/** @return bool Whether to include out-of-stock products. */
	public function include_out_of_stock(): bool {
		return (bool) ( $this->get( 'include_out_of_stock' ) ?? false );
	}

	/**
	 * Absolute path to the kramar-feeds uploads directory.
	 *
	 * @since 1.0.0
	 *
	 * @return string Absolute directory path (no trailing slash).
	 */
	public function get_feed_dir(): string {
		$upload = wp_upload_dir();
		return rtrim( $upload['basedir'], '/' ) . '/kramar-feeds';
	}

	/**
	 * Absolute path to the generated feed XML file.
	 *
	 * @since 1.0.0
	 *
	 * @return string Absolute file path.
	 */
	public function get_feed_path(): string {
		return $this->get_feed_dir() . '/google-feed-' . $this->get_token() . '.xml';
	}

	/**
	 * Public-facing feed URL (token passed as query arg, validated server-side).
	 *
	 * @since 1.0.0
	 *
	 * @return string Absolute URL.
	 */
	public function get_feed_url(): string {
		return home_url( '/?kramar-feed=google-shopping&token=' . $this->get_token() );
	}

	/**
	 * Read one setting value.
	 *
	 * @since 1.0.0
	 *
	 * @param string $key Setting key.
	 * @return mixed
	 */
	private function get( string $key ): mixed {
		return $this->plugin->get_setting( self::CATEGORY, self::SLUG, $key );
	}
}
