<?php
/**
 * Options
 *
 * Single source of truth for all plugin settings.
 * Declarative defaults array — adding a new option is one line here.
 *
 * @package Relatedly\Core
 * @since   2.0.0
 */

namespace Relatedly\Core;

defined( 'ABSPATH' ) || exit;

/**
 * Provides the plugin's option schema and persisted settings.
 *
 * @since 2.0.0
 */
class Options {

	const OPTION_KEY = 'relatedly_settings';

	/**
	 * Loaded and merged option values.
	 *
	 * @since 2.0.0
	 * @var array<string,mixed>
	 */
	private array $data = [];

	/**
	 * Create the options repository and load stored settings.
	 *
	 * @since 2.0.0
	 */
	public function __construct() {
		$this->load();
	}

	// -------------------------------------------------------------------------
	// Public API
	// -------------------------------------------------------------------------

	/**
	 * Get a single option value.
	 *
	 * @param string $key      Option key.
	 * @param mixed  $fallback Fallback if key not found.
	 * @return mixed
	 */
	public function get( string $key, $fallback = null ) {
		return $this->data[ $key ] ?? $fallback;
	}

	/**
	 * Get all option values.
	 *
	 * @since 2.0.0
	 * @return array<string,mixed>
	 */
	public function all(): array {
		return $this->data;
	}

	/**
	 * Persist options and refresh in-memory data.
	 *
	 * Update_option() returns false when value is unchanged - that is NOT an
	 * error, so we verify before treating it as a failure.
	 *
	 * @since 2.0.0
	 * @param array<string,mixed> $options Option values to persist.
	 * @return bool True when saved or already current.
	 */
	public function save( array $options ): bool {
		$this->data = $options;
		$result     = update_option( self::OPTION_KEY, $options );

		if ( false === $result ) {
			$stored = get_option( self::OPTION_KEY, [] );
			return $stored === $options;
		}

		return true;
	}

	/**
	 * Force reload from DB after external updates.
	 *
	 * @since 2.0.0
	 */
	public function reload(): void {
		$this->load();
	}

	// -------------------------------------------------------------------------
	// Internal
	// -------------------------------------------------------------------------

	/**
	 * Load saved options and merge with defaults.
	 *
	 * CRITICAL: uses array_key_exists, NOT wp_parse_args / isset.
	 * wp_parse_args treats `false` as "not set" and overwrites with the default —
	 * that was the root cause of the v1.8.x critical bug where every disabled
	 * toggle reset itself to enabled on the next page load.
	 */
	private function load(): void {
		$defaults = $this->defaults();
		$saved    = get_option( self::OPTION_KEY, [] );

		$this->data = [];
		foreach ( $defaults as $key => $default_value ) {
			$this->data[ $key ] = array_key_exists( $key, $saved )
			? $saved[ $key ]
			: $default_value;
		}
	}

	// -------------------------------------------------------------------------
	// Defaults — every option defined once, as data
	// -------------------------------------------------------------------------

	/**
	 * Get default values for every registered option.
	 *
	 * @since 2.0.0
	 * @return array<string,mixed>
	 */
	public function defaults(): array {
		return [
			// General.
			'enabled'                                 => true,
			'post_types'                              => [ 'post' ],
			'related_method'                          => 'both',

			// Inline related posts.
			'inline_enabled'                          => false,
			'inline_paragraph_interval'               => 4,
			'inline_theme'                            => 'theme1',
			'inline_max_posts'                        => 1,

			// End-of-content related posts.
			'end_content_enabled'                     => false,
			'end_content_theme'                       => 'theme1',
			'end_content_max_posts'                   => 5,
			'end_content_columns'                     => 1,

			// RSS feed integration.
			'rss_enabled'                             => false,
			'rss_paragraph_interval'                  => 10,
			'rss_end_content_enabled'                 => false,
			'rss_end_content_max_posts'               => 3,
			'utm_source'                              => 'rss',
			'utm_medium'                              => 'related_posts',
			'utm_campaign'                            => 'rss_related_posts',
			'rss_utm_content_inline'                  => 'inline',
			'rss_utm_content_end'                     => 'end_content',

			// Exclusions and caching.
			'exclude_current_post'                    => true,
			'exclude_categories'                      => [],
			'exclude_tags'                            => [],
			'cache_duration'                          => 12 * HOUR_IN_SECONDS,
			'enable_cache'                            => false,
			'debug_mode'                              => false,

			// Link behaviour.
			'link_target'                             => '_self',
			'link_rel'                                => '',

			// Click and impression tracking.
			'enable_click_tracking'                   => false,

			// Email reports.
			'email_reports_enabled'                   => false,
			'email_reports_frequency'                 => 'weekly',
			'email_reports_recipients'                => [],
			'email_reports_day'                       => 1,
			'email_reports_time'                      => '09:00',
			'email_reports_include_summary'           => true,
			'email_reports_include_top_posts'         => true,
			'email_reports_include_comparison'        => false,
			'email_reports_top_posts_count'           => 10,

			// Customisation.
			'disabled_default_inline_labels'          => [],
			'disabled_default_end_content_labels'     => [],
			'data_retention_days'                     => 90,

			// Floating sidebar.
			'floating_sidebar_enabled'                => false,
			'floating_sidebar_variant'                => 'variant1',
			'floating_sidebar_position'               => 'right',
			'floating_sidebar_width'                  => '300px',
			'floating_sidebar_num_posts'              => 1,
			'floating_sidebar_display_trigger'        => 'always',
			'floating_sidebar_scroll_percentage'      => 25,
			'floating_sidebar_dismiss_behavior'       => 'per_page',
			'floating_sidebar_auto_refresh_enabled'   => false,
			'floating_sidebar_auto_refresh_seconds'   => 10,
			'floating_sidebar_z_index'                => 9999,

			// Inline theme colours.

			// Theme 1 - Simple.
			'inline_theme1_bg'                        => '#f9f9f9',
			'inline_theme1_border_color'              => '#0073aa',
			'inline_theme1_title_color'               => '#333333',
			'inline_theme1_title_size'                => '18px',
			'inline_theme1_title_weight'              => 'normal',
			'inline_theme1_label_color'               => '#0073aa',
			'inline_theme1_label_size'                => '16px',
			'inline_theme1_label_weight'              => 'normal',
			'inline_theme1_excerpt_color'             => '#666666',
			'inline_theme1_excerpt_size'              => '14px',
			'inline_theme1_show_excerpt'              => true,

			// Theme 2 - Minimal.
			'inline_theme2_font_size'                 => '14px',
			'inline_theme2_font_weight'               => 'bold',
			'inline_theme2_color'                     => '#333333',
			'inline_theme2_bg'                        => '#ffffff',
			'inline_theme2_border_color'              => '#dddddd',
			'inline_theme2_label_color'               => '#999999',
			'inline_theme2_label_size'                => '12px',

			// Theme 3 - Featured.
			'inline_theme3_bg'                        => '#ffffff',
			'inline_theme3_border_color'              => '#e1e1e1',
			'inline_theme3_title_color'               => '#333333',
			'inline_theme3_label_color'               => '#0073aa',
			'inline_theme3_thumbnail_size'            => 'thumbnail',
			'inline_theme3_thumbnail_alignment'       => 'left',
			'inline_theme3_excerpt_color'             => '#666666',
			'inline_theme3_title_size'                => '16px',
			'inline_theme3_show_excerpt'              => true,
			'inline_theme3_title_weight'              => 'normal',
			'inline_theme3_label_size'                => '16px',
			'inline_theme3_label_weight'              => 'normal',

			// Theme 4 - Quote.
			'inline_theme4_bg'                        => '#f8f9fa',
			'inline_theme4_accent_color'              => '#0073aa',
			'inline_theme4_title_color'               => '#333333',
			'inline_theme4_title_size'                => '18px',
			'inline_theme4_title_style'               => 'italic',
			'inline_theme4_excerpt_color'             => '#666666',
			'inline_theme4_excerpt_size'              => '14px',
			'inline_theme4_show_excerpt'              => true,
			'inline_theme4_padding'                   => '20px',

			// Theme 5 - Badge.
			'inline_theme5_bg'                        => '#0073aa',
			'inline_theme5_text_color'                => '#ffffff',
			'inline_theme5_label_color'               => 'rgba(255,255,255,0.8)',
			'inline_theme5_font_size'                 => '13px',
			'inline_theme5_label_size'                => '10px',
			'inline_theme5_padding'                   => '8px 12px',

			// Theme 6 - Callout.
			'inline_theme6_bg'                        => '#fff3cd',
			'inline_theme6_border_color'              => '#ffc107',
			'inline_theme6_title_color'               => '#333333',
			'inline_theme6_title_size'                => '18px',
			'inline_theme6_title_weight'              => 'bold',
			'inline_theme6_excerpt_color'             => '#666666',
			'inline_theme6_excerpt_size'              => '14px',
			'inline_theme6_show_excerpt'              => true,
			'inline_theme6_padding'                   => '20px',

			// Theme 7 - Gradient.
			'inline_theme7_gradient_start'            => '#667eea',
			'inline_theme7_gradient_end'              => '#764ba2',
			'inline_theme7_title_color'               => '#ffffff',
			'inline_theme7_title_size'                => '18px',
			'inline_theme7_excerpt_color'             => 'rgba(255,255,255,0.9)',
			'inline_theme7_excerpt_size'              => '14px',
			'inline_theme7_show_excerpt'              => true,
			'inline_theme7_padding'                   => '25px',

			// Theme 8 - Card.
			'inline_theme8_bg'                        => '#ffffff',
			'inline_theme8_title_color'               => '#333333',
			'inline_theme8_title_size'                => '18px',
			'inline_theme8_date_color'                => '#999999',
			'inline_theme8_date_type'                 => 'published',
			'inline_theme8_show_date'                 => true,
			'inline_theme8_excerpt_color'             => '#666666',
			'inline_theme8_excerpt_size'              => '14px',
			'inline_theme8_show_excerpt'              => true,
			'inline_theme8_padding'                   => '20px',
			'inline_theme8_border_radius'             => '8px',

			// End-content theme colours.

			// Theme 1 - List.
			'end_theme1_bg'                           => '#f9f9f9',
			'end_theme1_border_color'                 => '#e1e1e1',
			'end_theme1_title_color'                  => '#0073aa',
			'end_theme1_title_size'                   => '18px',
			'end_theme1_title_weight'                 => 'normal',
			'end_theme1_label_color'                  => '#333333',
			'end_theme1_label_size'                   => '20px',
			'end_theme1_label_weight'                 => 'bold',
			'end_theme1_excerpt_color'                => '#666666',
			'end_theme1_excerpt_size'                 => '14px',
			'end_theme1_show_excerpt'                 => true,

			// Theme 2 - Simple List.
			'end_theme2_title_color'                  => '#333333',
			'end_theme2_title_size'                   => '16px',
			'end_theme2_title_weight'                 => 'normal',
			'end_theme2_label_color'                  => '#333333',
			'end_theme2_label_size'                   => '16px',
			'end_theme2_label_weight'                 => 'bold',
			'end_theme2_bg'                           => '#ffffff',
			'end_theme2_border_color'                 => '#e1e1e1',
			'end_theme2_thumbnail_size'               => 'medium',
			'end_theme2_show_excerpt'                 => false,
			'end_theme2_excerpt_color'                => '#666666',
			'end_theme2_excerpt_size'                 => '14px',

			// Theme 3 - Masonry.
			'end_theme3_title_color'                  => '#333333',
			'end_theme3_title_size'                   => '16px',
			'end_theme3_title_weight'                 => 'normal',
			'end_theme3_bg'                           => '#ffffff',
			'end_theme3_border_color'                 => '#e1e1e1',
			'end_theme3_label_color'                  => '#333333',
			'end_theme3_label_size'                   => '20px',
			'end_theme3_label_weight'                 => 'bold',
			'end_theme3_thumbnail_size'               => 'medium',
			'end_theme3_excerpt_color'                => '#666666',
			'end_theme3_excerpt_size'                 => '13px',
			'end_theme3_show_excerpt'                 => true,

			// Theme 4 - Carousel.
			'end_theme4_title_color'                  => '#333333',
			'end_theme4_title_size'                   => '16px',
			'end_theme4_bg'                           => '#ffffff',
			'end_theme4_border_color'                 => '#e1e1e1',
			'end_theme4_label_color'                  => '#333333',
			'end_theme4_label_size'                   => '20px',
			'end_theme4_thumbnail_size'               => 'medium',
			'end_theme4_excerpt_color'                => '#666666',
			'end_theme4_excerpt_size'                 => '13px',
			'end_theme4_show_excerpt'                 => true,

			// Theme 5 - Timeline.
			'end_theme5_title_color'                  => '#333333',
			'end_theme5_title_size'                   => '18px',
			'end_theme5_bg'                           => '#ffffff',
			'end_theme5_line_color'                   => '#0073aa',
			'end_theme5_label_color'                  => '#333333',
			'end_theme5_label_size'                   => '20px',
			'end_theme5_date_color'                   => '#999999',
			'end_theme5_date_type'                    => 'modified',
			'end_theme5_excerpt_color'                => '#666666',
			'end_theme5_excerpt_size'                 => '14px',
			'end_theme5_show_excerpt'                 => true,

			// Theme 6 - Compact.
			'end_theme6_title_color'                  => '#333333',
			'end_theme6_title_size'                   => '15px',
			'end_theme6_bg'                           => '#f9f9f9',
			'end_theme6_label_color'                  => '#333333',
			'end_theme6_label_size'                   => '18px',
			'end_theme6_meta_color'                   => '#999999',

			// Floating sidebar variant colours.

			'floating_sidebar_variant1_bg'            => '#ffffff',
			'floating_sidebar_variant1_border_color'  => '#e1e1e1',
			'floating_sidebar_variant1_title_color'   => '#333333',
			'floating_sidebar_variant1_title_size'    => '16px',
			'floating_sidebar_variant1_label_color'   => '#0073aa',
			'floating_sidebar_variant1_label_size'    => '12px',
			'floating_sidebar_variant1_excerpt_color' => '#666666',

			'floating_sidebar_variant2_bg'            => '#f8f9fa',
			'floating_sidebar_variant2_title_color'   => '#333333',
			'floating_sidebar_variant2_label_color'   => '#0073aa',

			'floating_sidebar_variant3_bg'            => '#ffffff',
			'floating_sidebar_variant3_title_color'   => '#333333',
			'floating_sidebar_variant3_label_color'   => '#0073aa',

			'floating_sidebar_variant4_bg'            => '#ffffff',
			'floating_sidebar_variant4_title_color'   => '#333333',
			'floating_sidebar_variant4_label_color'   => '#0073aa',

			'floating_sidebar_variant5_bg'            => '#0073aa',
			'floating_sidebar_variant5_text_color'    => '#ffffff',
			'floating_sidebar_variant5_label_color'   => 'rgba(255,255,255,0.8)',
		];
	}
}
