<?php

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

final class AISBW_Settings
{
    private static ?AISBW_Settings $instance = null;

    public static function instance(): AISBW_Settings
    {
        if (null === self::$instance) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    public function init(): void
    {
        add_action('admin_init', [$this, 'register']);
    }

    public function register(): void
    {
        $settings = [
            'aisbw_default_article_length' => 'sanitize_text_field',
            'aisbw_default_tone' => 'sanitize_text_field',
            'aisbw_default_language' => [$this, 'sanitize_language_setting'],
            'aisbw_default_category_id' => 'absint',
            'aisbw_default_author_id' => 'absint',
            'aisbw_test_mode_enabled' => 'absint',
            'aisbw_autopublish_enabled' => [$this, 'sanitize_autopublish'],
            'aisbw_min_quality_score' => [$this, 'sanitize_quality_score'],
            'aisbw_cron_enabled' => [$this, 'sanitize_cron_enabled'],
            'aisbw_max_articles_per_day' => 'absint',
            'aisbw_max_ai_requests_per_day' => 'absint',
            'aisbw_featured_image_enabled' => [$this, 'sanitize_featured_image_enabled'],
            'aisbw_featured_image_model' => 'sanitize_text_field',
            'aisbw_featured_image_style' => 'sanitize_text_field',
            'aisbw_featured_image_aspect' => 'sanitize_text_field',
            'aisbw_featured_image_format' => 'sanitize_text_field',
        ];

        foreach ($settings as $name => $sanitize_callback) {
            register_setting('aisbw_settings', $name, [
                'type' => 'string',
                'sanitize_callback' => $sanitize_callback,
                'show_in_rest' => false,
            ]);
        }
    }

    public function sanitize_featured_image_enabled(mixed $value): int
    {
        $value = absint($value);
        if ($value && !aisbw_is_premium()) {
            add_settings_error('aisbw_settings', 'aisbw_featured_image_enabled', __('Featured image generation is only available in the PRO version.', 'guco-ai-blog-writer'));
            return 0;
        }
        return $value;
    }

    public function sanitize_autopublish(mixed $value): int
    {
        $value = absint($value);
        if ($value && !aisbw_is_premium()) {
            add_settings_error('aisbw_settings', 'aisbw_autopublish_enabled', __('The auto-publish feature is only available in the PRO version.', 'guco-ai-blog-writer'));
            return 0;
        }
        return $value;
    }

    public function sanitize_cron_enabled(mixed $value): int
    {
        $value = absint($value);
        if ($value && !aisbw_is_premium()) {
            add_settings_error('aisbw_settings', 'aisbw_cron_enabled', __('WP-Cron auto-scheduling is only available in the PRO version.', 'guco-ai-blog-writer'));
            return 0;
        }
        return $value;
    }

    public function sanitize_language_setting(mixed $value): string
    {
        $value = sanitize_key((string) $value);
        $allowed = class_exists('AISBW_Multilingual_Premium')
            ? AISBW_Multilingual_Premium::get_allowed_languages()
            : ['pl'];

        if (!in_array($value, $allowed, true)) {
            return 'pl';
        }

        if (!aisbw_is_premium() && 'pl' !== $value) {
            add_settings_error('aisbw_settings', 'aisbw_default_language', __('Multilingual generation is only available in the PRO version.', 'guco-ai-blog-writer'));
            return 'pl';
        }

        return $value;
    }

    public function sanitize_quality_score(mixed $value): int
    {
        $value = absint($value);

        if ($value < 0) {
            return 0;
        }

        if ($value > 100) {
            return 100;
        }

        return $value;
    }

    public static function get(string $name, mixed $default = null): mixed
    {
        $value = get_option($name, $default);

        return false === $value ? $default : $value;
    }

    public static function get_bool(string $name): bool
    {
        return (bool) absint((string) self::get($name, 0));
    }

    private function __construct()
    {
    }
}
