<?php

namespace MintyPHP\Service\Settings;

use MintyPHP\I18n;

class SettingsAppGateway
{
    public function __construct(
        private readonly SettingsMetadataGateway $settingsMetadataGateway,
        private readonly ThemeConfigGateway $themeConfigService
    ) {
    }

    public function getAppTitle(): ?string
    {
        $value = $this->settingsMetadataGateway->getValue(SettingKeys::APP_TITLE_KEY);
        $value = $value !== null ? trim($value) : null;
        return $value !== '' ? $value : null;
    }

    public function setAppTitle(?string $title, ?string $description = null): bool
    {
        $value = $title !== null ? trim($title) : null;
        if ($value === '') {
            $value = null;
        }

        $desc = $description ?? 'setting.app_title';
        return $this->settingsMetadataGateway->set(SettingKeys::APP_TITLE_KEY, $value, $desc);
    }

    public function getAppLocale(): ?string
    {
        $value = $this->settingsMetadataGateway->getValue(SettingKeys::APP_LOCALE_KEY);
        $value = $value !== null ? trim($value) : '';
        return $value !== '' ? $value : null;
    }

    public function setAppLocale(?string $locale, ?string $description = null): bool
    {
        $value = $locale !== null ? trim($locale) : '';
        if ($value === '') {
            $value = null;
        } else {
            $allowed = defined('APP_LOCALES') ? APP_LOCALES : [];
            if ($allowed && !in_array($value, $allowed, true)) {
                return false;
            }
        }

        $desc = $description ?? 'setting.app_locale';
        return $this->settingsMetadataGateway->set(SettingKeys::APP_LOCALE_KEY, $value, $desc);
    }

    public function getAppTheme(): ?string
    {
        $value = $this->settingsMetadataGateway->getValue(SettingKeys::APP_THEME_KEY);
        $value = $value !== null ? strtolower(trim($value)) : '';
        if (!in_array($value, $this->allowedThemes(), true)) {
            return null;
        }

        return $value;
    }

    public function setAppTheme(?string $theme, ?string $description = null): bool
    {
        $value = $theme !== null ? strtolower(trim($theme)) : '';
        if ($value === '' || !in_array($value, $this->allowedThemes(), true)) {
            $value = null;
        }

        $desc = $description ?? 'setting.app_theme';
        return $this->settingsMetadataGateway->set(SettingKeys::APP_THEME_KEY, $value, $desc);
    }

    public function isUserThemeAllowed(): bool
    {
        $value = $this->settingsMetadataGateway->getValue(SettingKeys::APP_THEME_USER_KEY);
        if ($value === null || $value === '') {
            return true;
        }

        return in_array(strtolower($value), ['1', 'true', 'yes', 'on'], true);
    }

    public function setUserThemeAllowed(bool $allowed, ?string $description = null): bool
    {
        $value = $allowed ? '1' : '0';
        $desc = $description ?? 'setting.app_theme_user';
        return $this->settingsMetadataGateway->set(SettingKeys::APP_THEME_USER_KEY, $value, $desc);
    }

    public function isRegistrationEnabled(): bool
    {
        $value = $this->settingsMetadataGateway->getValue(SettingKeys::APP_REGISTRATION_KEY);
        if ($value === null || $value === '') {
            return true;
        }

        return in_array(strtolower($value), ['1', 'true', 'yes', 'on'], true);
    }

    public function setRegistrationEnabled(bool $allowed, ?string $description = null): bool
    {
        $value = $allowed ? '1' : '0';
        $desc = $description ?? 'setting.app_registration';
        return $this->settingsMetadataGateway->set(SettingKeys::APP_REGISTRATION_KEY, $value, $desc);
    }

    public function getAppPrimaryColor(): ?string
    {
        $value = $this->settingsMetadataGateway->getValue(SettingKeys::APP_PRIMARY_COLOR_KEY);
        $value = $value !== null ? strtolower(trim($value)) : '';
        if ($value === '') {
            return null;
        }
        if (!preg_match('/^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i', $value)) {
            return null;
        }

        return $value;
    }

    public function setAppPrimaryColor(?string $color, ?string $description = null): bool
    {
        $value = $color !== null ? strtolower(trim($color)) : '';
        if ($value !== '' && $value[0] !== '#') {
            if (preg_match('/^[0-9a-f]{3}$/i', $value)
                || preg_match('/^[0-9a-f]{4}$/i', $value)
                || preg_match('/^[0-9a-f]{6}$/i', $value)
                || preg_match('/^[0-9a-f]{8}$/i', $value)) {
                $value = '#' . $value;
            }
        }
        if ($value === '') {
            $value = null;
        } elseif (!preg_match('/^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i', $value)) {
            return false;
        }

        $desc = $description ?? 'setting.app_primary_color';
        return $this->settingsMetadataGateway->set(SettingKeys::APP_PRIMARY_COLOR_KEY, $value, $desc);
    }

    private function allowedThemes(): array
    {
        return array_keys($this->themeConfigService->all());
    }

    public function normalizeLocale(?string $locale): string
    {
        $value = strtolower(trim((string) $locale));
        $available = defined('APP_LOCALES') ? APP_LOCALES : [I18n::$defaultLocale];
        if ($value === '' || !in_array($value, $available, true)) {
            return I18n::$locale ?? I18n::$defaultLocale;
        }

        return $value;
    }
}
