<?php

namespace App\Services;

use App\Models\License;
use Illuminate\Support\Str;
use Carbon\Carbon;

class LicenseKeyGenerator
{
    private const KEY_FORMAT = 'XXXX-XXXX-XXXX-XXXX';
    private const CHARS = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';

    public function generate(int $length = 16): string
    {
        $key = '';
        $charsLength = strlen(self::CHARS);
        
        for ($i = 0; $i < $length; $i++) {
            $key .= self::CHARS[random_int(0, $charsLength - 1)];
            if (($i + 1) % 4 === 0 && $i < $length - 1) {
                $key .= '-';
            }
        }
        
        return $key;
    }

    public function create(array $data): License
    {
        $key = $this->generate();
        
        while (License::where('key', $key)->exists()) {
            $key = $this->generate();
        }

        // Handle expiration date from date picker
        $expiresAt = null;
        if (!empty($data['expires_at'])) {
            try {
                $expiresAt = \Carbon\Carbon::parse($data['expires_at']);
            } catch (\Exception $e) {
                $expiresAt = null;
            }
        }

        return License::create([
            'key' => $key,
            'name' => $data['name'] ?? null,
            'email' => $data['email'] ?? null,
            'status' => 'active',
            'expires_at' => $expiresAt,
            'activated_at' => Carbon::now(),
            'max_devices' => $data['max_devices'] ?? 1,
            'current_devices' => 0,
            'note' => $data['note'] ?? null,
        ]);
    }

    public function createMultiple(array $data, int $quantity): array
    {
        $licenses = [];
        
        // Handle expiration date from date picker
        $expiresAt = null;
        if (!empty($data['expires_at'])) {
            try {
                $expiresAt = \Carbon\Carbon::parse($data['expires_at']);
            } catch (\Exception $e) {
                $expiresAt = null;
            }
        }

        for ($i = 0; $i < $quantity; $i++) {
            $key = $this->generate();
            
            while (License::where('key', $key)->exists()) {
                $key = $this->generate();
            }

            $license = License::create([
                'key' => $key,
                'name' => $data['name'] ?? null,
                'email' => $data['email'] ?? null,
                'status' => 'active',
                'expires_at' => $expiresAt,
                'activated_at' => Carbon::now(),
                'max_devices' => $data['max_devices'] ?? 1,
                'current_devices' => 0,
                'note' => $data['note'] ?? null,
            ]);
            
            $licenses[] = $license;
        }

        return $licenses;
    }

    public function validate(string $key): array
    {
        $license = License::where('key', $key)->first();

        if (!$license) {
            return [
                'valid' => false,
                'message' => 'License key not found',
            ];
        }

        if ($license->status === 'suspended') {
            return [
                'valid' => false,
                'message' => 'License is suspended',
                'license' => $license,
            ];
        }

        if ($license->status === 'revoked') {
            return [
                'valid' => false,
                'message' => 'License has been revoked',
                'license' => $license,
            ];
        }

        if ($license->isExpired()) {
            $license->update(['status' => 'expired']);
            return [
                'valid' => false,
                'message' => 'License has expired',
                'license' => $license,
            ];
        }

        return [
            'valid' => true,
            'message' => 'License is valid',
            'license' => $license,
        ];
    }

    public function renew(string $key, int $days): License
    {
        $license = License::where('key', $key)->firstOrFail();
        
        $newExpiry = $license->expires_at 
            ? Carbon::parse($license->expires_at)->addDays((int) $days)
            : Carbon::now()->addDays((int) $days);

        $license->update([
            'expires_at' => $newExpiry,
            'status' => 'active',
        ]);

        return $license;
    }

    public function renewWithDate(string $key, string $newExpiryDate): License
    {
        $license = License::where('key', $key)->firstOrFail();
        
        $newExpiry = Carbon::parse($newExpiryDate);

        $license->update([
            'expires_at' => $newExpiry,
            'status' => 'active',
        ]);

        return $license;
    }
}