<?php

/**
 * Internal Linking Settings Store
 *
 * Canonical read/write access for internal linking settings with legacy migration.
 *
 * @package ProRank\SEO\Modules\Content\InternalLinking
 * @since   1.0.0
 */

declare(strict_types=1);

namespace ProRank\SEO\Modules\Content\InternalLinking;

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

class SettingsStore {
    /**
     * Canonical option key.
     */
    public const OPTION_KEY = 'prorank_seo_internal_linking_settings';

    /**
     * Legacy option keys.
     */
    private const LEGACY_OPTION_KEYS = [
        'prorank_seo_internal_linking',
        'prorank_internal_linking_settings',
    ];

    /**
     * Free plugin keeps internal-linking sources local-only.
     */
    private const SUPPORTED_KEYWORD_SOURCES = [
        'focus', 'title', 'slug', 'categories', 'tags', 'custom',
    ];

    /**
     * Get settings merged from canonical and legacy keys.
     *
     * @param array $defaults Optional defaults.
     * @return array
     */
    public static function get(array $defaults = []): array {
        $merged = [];

        foreach (self::LEGACY_OPTION_KEYS as $legacy_key) {
            $legacy = get_option($legacy_key, []);
            if (is_array($legacy)) {
                $merged = array_merge($merged, $legacy);
            }
        }

        $canonical = get_option(self::OPTION_KEY, []);
        if (is_array($canonical)) {
            $merged = array_merge($merged, $canonical);
        }

        if (!empty($defaults)) {
            $merged = wp_parse_args($merged, $defaults);
        }

        return self::normalize_free_settings(is_array($merged) ? $merged : []);
    }

    /**
     * Persist settings to the canonical key.
     *
     * @param array $settings Settings payload.
     * @return array Saved settings.
     */
    public static function update(array $settings): array {
        $settings = self::normalize_free_settings(is_array($settings) ? $settings : []);

        update_option(self::OPTION_KEY, $settings);

        foreach (self::LEGACY_OPTION_KEYS as $legacy_key) {
            delete_option($legacy_key);
        }

        return $settings;
    }

    /**
     * Migrate legacy settings into canonical key.
     *
     * @param array $defaults Optional defaults.
     * @return array Migrated settings.
     */
    public static function migrate(array $defaults = []): array {
        $settings = self::get($defaults);

        $canonical = get_option(self::OPTION_KEY, []);
        if (!is_array($canonical) || $canonical !== $settings) {
            self::update($settings);
        }

        return $settings;
    }

    /**
     * Free builds must never persist premium AI/GSC settings into runtime.
     */
    private static function normalize_free_settings(array $settings): array {
        $settings['ai_suggestions'] = false;
        $settings['ai_anchor_generation'] = false;
        $settings['gsc_integration'] = false;

        $keyword_sources = $settings['keyword_sources'] ?? self::SUPPORTED_KEYWORD_SOURCES;
        if (!is_array($keyword_sources)) {
            $keyword_sources = (array) $keyword_sources;
        }

        $keyword_sources = array_values(array_intersect(
            array_map('sanitize_text_field', $keyword_sources),
            self::SUPPORTED_KEYWORD_SOURCES
        ));

        if (empty($keyword_sources)) {
            $keyword_sources = ['title', 'slug', 'focus'];
        }

        $settings['keyword_sources'] = $keyword_sources;

        return $settings;
    }
}
