<?php

/**
 * MVC License Service — handles activation, validation, and grace period.
 *
 * Talks to Arbiter API at /api/mvc/* endpoints.
 * Stores license state in Blueprint dbGet/dbSet.
 *
 * Keys stored:
 *   modpackchecker.order_id        — BuiltByBit order ID
 *   modpackchecker.license_status  — active|grace|expired|inactive
 *   modpackchecker.tier            — standard|professional
 *   modpackchecker.grace_expires   — ISO timestamp (set on first validation failure)
 *   modpackchecker.last_validated  — ISO timestamp of last successful validation
 *   modpackchecker.latest_version  — latest version from Arbiter
 */

namespace Pterodactyl\Services;

use Pterodactyl\BlueprintFramework\Libraries\ExtensionLibrary\Admin\BlueprintAdminLibrary as BlueprintExtensionLibrary;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class LicenseService
{
    private string $arbiterBase = 'https://discord-bot.firefrostgaming.com/api/mvc';
    private int $graceDays = 7;

    public function __construct(
        private BlueprintExtensionLibrary $blueprint
    ) {}

    /**
     * Activate a license by order ID.
     * Called from admin UI "Save & Activate" button.
     */
    public function activate(string $orderId): array
    {
        $orderId = strtoupper(trim($orderId));
        $domain = config('app.url');

        try {
            $response = Http::timeout(15)->post("{$this->arbiterBase}/activate", [
                'order_id' => $orderId,
                'domain' => $domain,
                'ip' => request()->server('SERVER_ADDR', ''),
            ]);

            $data = $response->json();

            if ($response->successful() && ($data['status'] ?? '') === 'active') {
                $this->blueprint->dbSet('modpackchecker', 'order_id', $orderId);
                $this->blueprint->dbSet('modpackchecker', 'license_status', 'active');
                $this->blueprint->dbSet('modpackchecker', 'tier', $data['tier'] ?? 'standard');
                $this->blueprint->dbSet('modpackchecker', 'last_validated', now()->toISOString());
                $this->blueprint->dbSet('modpackchecker', 'grace_expires', '');

                return ['success' => true, 'tier' => $data['tier'] ?? 'standard'];
            }

            return ['success' => false, 'error' => $data['error'] ?? 'Activation failed'];

        } catch (\Exception $e) {
            Log::error('[MVC License] Activation error: ' . $e->getMessage());
            return ['success' => false, 'error' => 'Could not reach license server. Try again later.'];
        }
    }

    /**
     * Validate (phone-home). Called daily by mvc:validate Artisan command.
     * On failure, enters grace period. After 7 days, marks expired.
     */
    public function validate(): array
    {
        $orderId = $this->blueprint->dbGet('modpackchecker', 'order_id');
        if (empty($orderId)) {
            return ['status' => 'inactive', 'message' => 'No license configured'];
        }

        $domain = config('app.url');

        try {
            $response = Http::timeout(15)->post("{$this->arbiterBase}/validate", [
                'order_id' => $orderId,
                'domain' => $domain,
                'version' => config('app.version', '1.0.0'),
                'php_version' => PHP_VERSION,
            ]);

            $data = $response->json();

            if ($response->successful() && ($data['status'] ?? '') === 'active') {
                $this->blueprint->dbSet('modpackchecker', 'license_status', 'active');
                $this->blueprint->dbSet('modpackchecker', 'tier', $data['tier'] ?? 'standard');
                $this->blueprint->dbSet('modpackchecker', 'last_validated', now()->toISOString());
                $this->blueprint->dbSet('modpackchecker', 'grace_expires', '');

                if (!empty($data['latest_version'])) {
                    $this->blueprint->dbSet('modpackchecker', 'latest_version', $data['latest_version']);
                }

                return ['status' => 'active', 'tier' => $data['tier'] ?? 'standard'];
            }

            return $this->enterGracePeriod($data['error'] ?? 'Validation failed');

        } catch (\Exception $e) {
            Log::warning('[MVC License] Validation failed: ' . $e->getMessage());
            return $this->enterGracePeriod('Could not reach license server');
        }
    }

    /**
     * Enter or continue grace period. After 7 days, expire.
     */
    private function enterGracePeriod(string $reason): array
    {
        $graceExpires = $this->blueprint->dbGet('modpackchecker', 'grace_expires');

        if (empty($graceExpires)) {
            // First failure — start grace period
            $expires = now()->addDays($this->graceDays)->toISOString();
            $this->blueprint->dbSet('modpackchecker', 'license_status', 'grace');
            $this->blueprint->dbSet('modpackchecker', 'grace_expires', $expires);

            Log::warning("[MVC License] Grace period started. Expires: {$expires}. Reason: {$reason}");
            return ['status' => 'grace', 'expires' => $expires, 'reason' => $reason];
        }

        // Check if grace period expired
        if (now()->greaterThan($graceExpires)) {
            $this->blueprint->dbSet('modpackchecker', 'license_status', 'expired');
            Log::error('[MVC License] Grace period expired. License marked as expired.');
            return ['status' => 'expired', 'reason' => $reason];
        }

        return ['status' => 'grace', 'expires' => $graceExpires, 'reason' => $reason];
    }

    /**
     * Deactivate license on this panel.
     */
    public function deactivate(): array
    {
        $orderId = $this->blueprint->dbGet('modpackchecker', 'order_id');
        if (empty($orderId)) {
            return ['success' => true];
        }

        try {
            Http::timeout(15)->post("{$this->arbiterBase}/deactivate", [
                'order_id' => $orderId,
                'domain' => config('app.url'),
            ]);
        } catch (\Exception $e) {
            // Best-effort — clear local state regardless
        }

        $this->blueprint->dbSet('modpackchecker', 'order_id', '');
        $this->blueprint->dbSet('modpackchecker', 'license_status', 'inactive');
        $this->blueprint->dbSet('modpackchecker', 'tier', 'standard');
        $this->blueprint->dbSet('modpackchecker', 'grace_expires', '');

        return ['success' => true];
    }

    /**
     * Check if a pro feature is allowed based on current tier + license status.
     */
    public function isProFeatureAllowed(): bool
    {
        $status = $this->blueprint->dbGet('modpackchecker', 'license_status');
        $tier = $this->blueprint->dbGet('modpackchecker', 'tier');

        if ($status === 'expired') {
            return false;
        }

        return $tier === 'professional';
    }

    /**
     * Get full license state for the admin UI.
     */
    public function getState(): array
    {
        return [
            'order_id' => $this->blueprint->dbGet('modpackchecker', 'order_id') ?: '',
            'status' => $this->blueprint->dbGet('modpackchecker', 'license_status') ?: 'inactive',
            'tier' => $this->blueprint->dbGet('modpackchecker', 'tier') ?: 'standard',
            'grace_expires' => $this->blueprint->dbGet('modpackchecker', 'grace_expires') ?: '',
            'last_validated' => $this->blueprint->dbGet('modpackchecker', 'last_validated') ?: '',
            'latest_version' => $this->blueprint->dbGet('modpackchecker', 'latest_version') ?: '',
        ];
    }
}
