<?php

namespace App\Modules\Software\Procp;

use App\Core\Software\AbstractSoftware;
use App\Models\ClientSoftwareLicense;
use Illuminate\Support\Str;

/**
 * PROCP kendi lisans ürünü modülü (PRC-873).
 *
 * PROCP'yi kendi mağazamızda satılabilir Software-lisans ürünü yapar. Generic
 * modülden farkı: **host binding ÖN-YÜKLE İSTEMEZ** (`requiresHostBinding=false`)
 * → satın alma anında key hemen üretilir; müşterinin kurulumu (PRC-867 installer)
 * ilk `POST /api/license/validate` phone-home'unda kendi domain'ine bağlanır
 * (PRC-868 LicenseValidationController — domain birincil). Böylece "satın al →
 * key → kur → doğrula" akışı IP girmeden çalışır.
 *
 * Faturalama döngüsü (dogfood, kod mevcut):
 *  - satın alma → createAccount → issueLicense (bu modül)
 *  - yenileme ödenince → HandleInvoiceStatusChange expires_at = next_due_date
 *  - ödenmezse → expires_at geçer → validate `expired` → kademeli degrade
 *  - terminate → revoked_at → validate `revoked`
 */
class Procp extends AbstractSoftware
{
    public function requiresHostBinding(): bool
    {
        // Binding satın alma anında değil, müşterinin ilk phone-home'unda oluşur.
        return false;
    }

    public function hostBindingSchema(): array
    {
        return [];
    }

    public function adminFields(): array
    {
        return [];
    }

    public function paramSchema(): array
    {
        return [];
    }

    public function testConnection(array $params): array
    {
        return $this->ok('PROCP lisans modülü — key lokal üretilir; doğrulama /api/license/validate endpoint\'inden yapılır (PRC-868).');
    }

    public function issueLicense(
        ClientSoftwareLicense $license,
        array $bindingInput,
        array $moduleConfig,
    ): array {
        // İDEMPOTENT (PRC-1065): renewal'da key rotate olmasın (extend-not-rotate).
        if ($license->issued && ! empty($license->license_key)) {
            $license->update(['last_attempt_at' => now()]);

            return $this->ok('PROCP lisans anahtarı zaten üretilmiş — renewal\'da rotate edilmez (idempotent).', [
                'license_id' => $license->id,
            ]);
        }

        $license->update([
            // PROCP-XXXX-XXXX-XXXX biçimi (installer placeholder ile uyumlu),
            // uniform alfabe + uniqueness guard (PRC-1065).
            'license_key' => self::uniqueLicenseKey('PROCP-', 3, 4),
            'host_binding' => [],           // ilk phone-home'da (validate) bağlanır
            'binding_input' => $bindingInput,
            'issued' => true,
            'issued_at' => now(),
            'last_error' => null,
            'last_attempt_at' => now(),
        ]);

        return $this->ok('PROCP lisans anahtarı üretildi. Müşteri kurulumunda girecek; ilk doğrulamada domain\'e bağlanır.', [
            'license_id' => $license->id,
        ]);
    }
}
