<?php

namespace App\Services\Addons;

use App\Models\Addon;
use App\Services\License\EnvatoVerifier;
use App\Services\License\LicenseStorage;

/**
 * Addon license enforcement that piggybacks on the MAIN MailTrixy
 * purchase code.
 *
 * Addons are NOT sold separately on CodeCanyon — they ship with the
 * platform and are unlocked by the same Envato purchase code the
 * customer used at install time. There is no per-addon product id;
 * every addon checks against the main app's saved license file.
 *
 * Practical consequence:
 *   - One verification step (during install OR via the banner on the
 *     addons page if the customer skipped the installer).
 *   - That single license unlocks every addon, present or future.
 *   - Re-licensing means flipping main_app license — every addon
 *     inherits automatically.
 */
class AddonLicenseService
{
    /**
     * The main-app license file is what every addon checks against.
     * Constants mirror the convention used by LicenseStorage so the
     * filename is `licenses/main_app_mailtrixy.json`.
     */
    private const MAIN_TYPE = 'main_app';
    private const MAIN_SLUG = 'mailtrixy';

    public function __construct(
        private readonly EnvatoVerifier $verifier,
        private readonly LicenseStorage $storage,
    ) {}

    /**
     * Verify a customer-typed Envato purchase code against the main
     * MailTrixy product id and persist the license JSON. Called from
     * the addons page when the platform was upgraded without going
     * through the installer (so no main_app license file exists yet).
     *
     * Throws RuntimeException with a customer-friendly message on any
     * failure — same behaviour as the installer's verifyLicense().
     */
    public function verifyPlatformLicense(string $purchaseCode): array
    {
        // No second arg → EnvatoVerifier uses config('license.product_id'),
        // which is the main MailTrixy product id. That's exactly what we
        // want for the addon flow too: it's the same paid product.
        $sale = $this->verifier->verify($purchaseCode);

        $payload = [
            'type'          => self::MAIN_TYPE,
            'slug'          => self::MAIN_SLUG,
            'purchase_code' => $purchaseCode,
            'product_id'    => (string) config('license.product_id'),
            'domain'        => request()->getHost(),
            'verified_at'   => now()->utc()->toIso8601String(),
            'envato_buyer'  => (string) ($sale['buyer'] ?? ''),
        ];

        $this->storage->save(self::MAIN_TYPE, self::MAIN_SLUG, $payload);

        return $payload;
    }

    /**
     * Every addon answers "am I licensed?" the same way: is there a
     * main_app license file on disk? `$addon` is accepted for API
     * symmetry with the caller (AddonController iterates Addon
     * instances) and for forward-compatibility if we ever do reintroduce
     * per-addon licensing.
     *
     * @param  Addon|null  $addon  Unused — kept for future-proofing.
     */
    public function isLicensed(?Addon $addon = null): bool
    {
        return $this->storage->exists(self::MAIN_TYPE, self::MAIN_SLUG);
    }

    /**
     * Read the main MailTrixy license back out. Lets the addons index
     * UI show "Licensed via MailTrixy — bought by {envato_buyer} on
     * {date}" without each row hitting disk.
     */
    public function readPlatformLicense(): ?array
    {
        return $this->storage->read(self::MAIN_TYPE, self::MAIN_SLUG);
    }
}
