<?php

namespace App\Support;

use App\Services\Settings;

/**
 * Helper for admin-controlled subscription notification toggles. Each
 * notification category gets a `notifications.{key}_enabled` Settings
 * row; default is true (admins opt-out, not opt-in) so a fresh install
 * sends the full lifecycle out of the box.
 *
 * The renewal-reminder cadence is exposed as its own integer key —
 * defaults to 7 days. Range enforced in the admin form.
 */
class NotificationSettings
{
    /** Customer-facing categories (sent to the subscriber's email). */
    public const KEYS = [
        'subscription_activated',
        'subscription_canceled',
        'plan_changed',
        'renewal_reminder',
        'refund_issued',
        'payment_action_required',
        'subscription_paused',
        'subscription_halted',
        'subscription_expired',
        // Welcome email at registration. Fires post-verification if
        // verify is required, else immediately. Free signups get this;
        // paid users get this AND subscription_activated later.
        'user_welcome',
        // Invite email — the set-password/accept link for an admin-invited
        // (self-hosted, Δ20) or owner-invited (SaaS, future) member.
        'workspace_invite',
    ];

    /** Admin-facing categories (sent to notifications.admin_email).
     *  Single mailbox by design — per-admin-user gets noisy fast and
     *  the inbox stops being read. Admin can opt-out per category. */
    public const ADMIN_KEYS = [
        'admin_new_subscription',
        'admin_subscription_canceled',
        'admin_refund_issued',
        'admin_payment_failed',
        'admin_webhook_failed',
        'admin_user_registered',
    ];

    /** Default-on for every category. Compliance-friendly: receipt-like
     *  emails ship unless admin explicitly silences them. */
    public static function enabled(string $key): bool
    {
        try {
            return (bool) Settings::get("notifications.{$key}_enabled", true);
        } catch (\Throwable) {
            return true;
        }
    }

    public static function setEnabled(string $key, bool $value): void
    {
        Settings::set("notifications.{$key}_enabled", $value);
    }

    /** Renewal reminder lead time (days before period_ends_at). */
    public static function renewalReminderDays(): int
    {
        try {
            $days = (int) Settings::get('notifications.renewal_reminder_days', 7);
        } catch (\Throwable) {
            $days = 7;
        }

        return max(1, min(30, $days));
    }

    public static function setRenewalReminderDays(int $days): void
    {
        Settings::set('notifications.renewal_reminder_days', max(1, min(30, $days)));
    }

    /** Resolve the admin notification email. Explicit override wins,
     *  else falls back to site.support_email (admin already had to set
     *  that for the marketing footer + receipts). Null when neither
     *  is configured — dispatcher silently skips admin notifications
     *  rather than queueing emails to nowhere. */
    public static function adminEmail(): ?string
    {
        try {
            $override = Settings::get('notifications.admin_email');
            if (is_string($override) && $override !== '') {
                return $override;
            }
            $support = Settings::get('site.support_email');
            if (is_string($support) && $support !== '') {
                return $support;
            }
        } catch (\Throwable) {
            // Fall through.
        }

        return null;
    }

    public static function setAdminEmail(?string $email): void
    {
        Settings::set('notifications.admin_email', $email ?: null);
    }

    /** Snapshot of all toggles + lead-time + admin email, for admin UI
     *  hydration. Customer + admin keys interleaved under flat keys so
     *  the React form maps 1:1. */
    public static function all(): array
    {
        $out = [
            'renewal_reminder_days' => self::renewalReminderDays(),
            'admin_email' => self::adminEmail() ?? '',
        ];
        foreach (self::KEYS as $k) {
            $out["{$k}_enabled"] = self::enabled($k);
        }
        foreach (self::ADMIN_KEYS as $k) {
            $out["{$k}_enabled"] = self::enabled($k);
        }

        return $out;
    }
}
