<?php

// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedNamespaceFound -- APD is the established namespace shared with the Pro add-on and retained for backward compatibility.
namespace APD\Admin;

use APD\Repositories\TemplateRepository;
use APD\Theme\DesignerTheme;

defined('ABSPATH') || exit;

class AdminSettings
{
    public const OPTION = 'apd_settings';

    public function register() : void
    {
        register_setting('apd_settings_group', self::OPTION, [
            'type' => 'array',
            'sanitize_callback' => [$this, 'sanitize'],
            'default' => $this->defaults(),
        ]);
    }

    public function defaults() : array
    {
        return [
            'default_height' => '720px',
            'default_mode' => 'standalone',
            'enable_gutenberg' => '1',
            'enable_woocommerce_binding' => '1',
            'admin_theme' => 'light',
            'admin_designer_template_id' => '0',
            'admin_designer_theme_id' => DesignerTheme::FALLBACK_THEME_ID,
            'default_designer_theme_id' => DesignerTheme::FALLBACK_THEME_ID,
            'license_enabled' => '1',
            'license_key' => '',
            'license_domain' => '',
            'pixabay_api_key' => '',
            'facebook_app_id' => '',
            'pexels_api_key' => '',
            'unsplash_access_key' => '',
            'google_fonts_api_key' => '',
            'upload_max_size_mb' => '25',
            'delete_data_on_uninstall' => '0',
        ];
    }

    public function all() : array
    {
        $defaults = $this->defaults();
        $settings = wp_parse_args((array) get_option(self::OPTION, []), $defaults);

        return array_intersect_key($settings, $defaults);
    }

    public function sanitize(array $input) : array
    {
        $current = (array) get_option(self::OPTION, []);
        $submittedLicenseKey = sanitize_text_field((string) ($input['license_key'] ?? ''));
        $licenseKey = ! empty($input['license_key_clear'])
            ? ''
            : ($submittedLicenseKey !== '' ? $submittedLicenseKey : (string) ($current['license_key'] ?? ''));

        $themeService = new DesignerTheme();
        $submittedThemeId = sanitize_key((string) ($input['default_designer_theme_id'] ?? ''));
        $defaultDesignerThemeId = $themeService->hasTheme($submittedThemeId)
            ? $submittedThemeId
            : $themeService->defaultThemeId();
        $submittedAdminThemeId = sanitize_key((string) ($input['admin_designer_theme_id'] ?? ''));
        $adminDesignerThemeId = $themeService->hasTheme($submittedAdminThemeId)
            ? $submittedAdminThemeId
            : $themeService->defaultThemeId();
        $submittedAdminTemplateId = absint($input['admin_designer_template_id'] ?? 0);
        $adminTemplate = (new TemplateRepository())->getMetaPayload($submittedAdminTemplateId);
        $adminDesignerTemplateId = $adminTemplate !== [] ? (string) $submittedAdminTemplateId : '0';

        return [
            'default_height' => $this->sanitizeHeight($input['default_height'] ?? '720px'),
            'default_mode' => in_array(($input['default_mode'] ?? 'standalone'), ['standalone', 'customer', 'admin'], true) ? $input['default_mode'] : 'standalone',
            'enable_gutenberg' => ! empty($input['enable_gutenberg']) ? '1' : '0',
            'enable_woocommerce_binding' => ! empty($input['enable_woocommerce_binding']) ? '1' : '0',
            'admin_theme' => in_array(($input['admin_theme'] ?? 'light'), ['midnight', 'light', 'violet'], true) ? $input['admin_theme'] : 'light',
            'admin_designer_template_id' => $adminDesignerTemplateId,
            'admin_designer_theme_id' => $adminDesignerThemeId,
            'default_designer_theme_id' => $defaultDesignerThemeId,
            'license_enabled' => ! empty($input['license_enabled']) ? '1' : '0',
            'license_key' => $licenseKey,
            // The licensed domain is provisioned server-side and must never be
            // changed by a customer-facing settings submission.
            'license_domain' => sanitize_text_field((string) ($current['license_domain'] ?? '')),
            'pixabay_api_key' => sanitize_text_field((string) ($input['pixabay_api_key'] ?? '')),
            'facebook_app_id' => sanitize_text_field((string) ($input['facebook_app_id'] ?? '')),
            'pexels_api_key' => sanitize_text_field((string) ($input['pexels_api_key'] ?? '')),
            'unsplash_access_key' => sanitize_text_field((string) ($input['unsplash_access_key'] ?? '')),
            'google_fonts_api_key' => sanitize_text_field((string) ($input['google_fonts_api_key'] ?? '')),
            'upload_max_size_mb' => $this->sanitizeNumberString($input['upload_max_size_mb'] ?? '25', '25'),
            'delete_data_on_uninstall' => ! empty($input['delete_data_on_uninstall']) ? '1' : '0',
        ];
    }

    public function uploadMaxBytes(int $default = 10) : int
    {
        $settings = $this->all();
        $mb = (float) str_replace(',', '.', (string) ($settings['upload_max_size_mb'] ?? (string) $default));
        if ($mb <= 0) {
            $mb = (float) $default;
        }

        return (int) round($mb * MB_IN_BYTES);
    }

    private function sanitizeNumberString(mixed $value, string $default) : string
    {
        $number = (float) str_replace(',', '.', (string) $value);
        if ($number <= 0) {
            return $default;
        }
        return (string) $number;
    }

    private function sanitizeHeight(mixed $value) : string
    {
        $height = strtolower(trim(sanitize_text_field((string) $value)));
        return preg_match('/^\d+(?:\.\d+)?(?:px|rem|em|vh|vw|%)$/', $height) ? $height : '720px';
    }
}
