<?php

namespace App\Support;

use App\Services\Settings;

/**
 * Site-level landing-mode toggle. Lets admins flip the public marketing
 * surface (`/`, `/templates`, `/about`, `/contact`, `/pricing`) between
 * three modes:
 *
 *   - Enabled  → render the bundled marketing landing (default for SaaS)
 *   - Redirect → 302 to a buyer-supplied URL (apex marketing site at
 *                theirdomain.com while AppShot lives at app.theirdomain.com)
 *   - Login    → 302 to /login (app-only deployment, no public marketing)
 *
 * Defaults are AppMode-aware: SaaS installs default to Enabled (bundled
 * landing is the customer acquisition surface), self-hosted installs
 * default to Login (single-user installs rarely need a public landing).
 *
 * Authenticated users always pass through regardless of mode — change-plan
 * flow on /pricing and authed users browsing /templates would otherwise
 * break in Login mode. The toggle is for VISITORS, not for hiding
 * marketing pages from the customer themselves.
 *
 * Settings keys (admin-editable via /admin/marketing top card):
 *   - marketing.landing_mode: 'enabled' | 'redirect' | 'login'
 *   - marketing.redirect_url: string|null (only used when mode = redirect)
 */
enum MarketingMode: string
{
    case Enabled = 'enabled';
    case Redirect = 'redirect';
    case Login = 'login';

    public const SETTING_MODE = 'marketing.landing_mode';

    public const SETTING_REDIRECT_URL = 'marketing.redirect_url';

    /**
     * Resolve the active mode. Reads the Setting; falls back to AppMode-aware
     * default (SaaS → Enabled, self-hosted → Login). Wrapped in try/catch
     * so an early-bootstrap settings outage doesn't 500 the public marketing
     * routes — errs toward the AppMode default (the safer baseline).
     */
    public static function current(): self
    {
        try {
            $stored = Settings::get(self::SETTING_MODE);
            if (is_string($stored) && $stored !== '') {
                $mode = self::tryFrom($stored);
                if ($mode !== null) {
                    return $mode;
                }
            }
        } catch (\Throwable) {
            // Fall through to AppMode default below.
        }

        return AppMode::isSaas() ? self::Enabled : self::Login;
    }

    /**
     * Read the configured redirect URL. Returns null when missing, empty,
     * or invalid — caller decides the fallback (typically /login).
     */
    public static function redirectUrl(): ?string
    {
        try {
            $url = Settings::get(self::SETTING_REDIRECT_URL);
            if (! is_string($url)) {
                return null;
            }
            $url = trim($url);
            if ($url === '') {
                return null;
            }
            // Accept absolute http/https URLs only. Relative paths would
            // route through our own app and create a loop; non-http schemes
            // (javascript:, data:) are an XSS surface.
            if (! preg_match('#^https?://#i', $url)) {
                return null;
            }
            if (filter_var($url, FILTER_VALIDATE_URL) === false) {
                return null;
            }

            return $url;
        } catch (\Throwable) {
            return null;
        }
    }
}
