<?php

namespace App\Services\License;

use App\Models\License;
use App\Models\OrderItem;
use App\Models\User;
use App\Services\Security\SignatureService;
use Carbon\Carbon;

class LicenseGeneratorService
{
    public function __construct(private SignatureService $signer) {}

    public function generateFromOrderItem(OrderItem $item, User $user): License
    {
        $secret = $this->signer->generateSecret();
        $key    = $this->signer->generateLicenseKey();

        $config = $this->resolveConfig($item->license_type, $item->product->license_rules ?? []);

        $license = License::create([
            'license_key'      => $key,
            'user_id'          => $user->id,
            'product_id'       => $item->product_id,
            'order_id'         => $item->order_id,
            'order_item_id'    => $item->id,
            'type'             => $item->license_type,
            'status'           => 'active',
            'max_activations'  => $config['max_activations'],
            'activations_count'=> 0,
            'max_domains'      => $config['max_domains'] ?? null,
            'activated_at'     => now(),
            'expires_at'       => $config['expires_at'],
            'secret_key'       => $secret,
            'is_trial'         => $item->license_type === 'trial',
            'trial_days'       => $config['trial_days'] ?? null,
            'is_subscription'  => $item->license_type === 'subscription',
            'checksum'         => '',
        ]);

        // Compute checksum after creation (includes the ID)
        $checksumData = [
            'id'         => $license->id,
            'key'        => $key,
            'product_id' => $item->product_id,
            'user_id'    => $user->id,
            'type'       => $item->license_type,
        ];
        $license->checksum = $this->signer->computeLicenseChecksum($checksumData, $secret);
        $license->save();

        return $license;
    }

    private function resolveConfig(string $type, array $rules): array
    {
        $trialDays  = (int) setting('trial_days',    14);
        $maxDefault = (int) setting('max_activations', 1);

        $defaults = [
            // Regular — single domain, configurable max activations
            'single'    => ['max_activations' => $maxDefault, 'max_domains' => 1,    'expires_at' => null],
            // Extended — unlimited domains & activations
            'unlimited' => ['max_activations' => 9999,        'max_domains' => null, 'expires_at' => null],
        ];

        $config = array_merge($defaults[$type] ?? $defaults['single'], $rules[$type] ?? []);

        // Resolve relative expiry from rules
        if (isset($rules[$type]['expires_days']) && ! isset($rules[$type]['expires_at'])) {
            $config['expires_at'] = Carbon::now()->addDays($rules[$type]['expires_days']);
        }

        return $config;
    }
}
