<?php

declare(strict_types=1);

namespace Maestro\Core\Modules\Offers\Services;

use Illuminate\Support\Facades\DB;
use Maestro\Core\Modules\Offers\Enums\OfferNumberResetPolicy;
use Maestro\Core\Modules\Offers\Models\MaestroOfferSettings;

final class OfferNumberService
{
    public static function allocateCommercialNumber(): string
    {
        return DB::transaction(function (): string {
            /** @var MaestroOfferSettings $settings */
            $settings = MaestroOfferSettings::query()->lockForUpdate()->firstOrCreate([], [
                'number_prefix' => 'OFF',
                'number_padding' => 3,
                'reset_policy' => OfferNumberResetPolicy::Yearly->value,
                'last_sequence' => 0,
                'vat_rate_presets' => [21.0, 9.0, 0.0],
            ]);

            $year = (int) now()->year;
            $policy = OfferNumberResetPolicy::tryFrom($settings->reset_policy) ?? OfferNumberResetPolicy::Yearly;

            if ($policy === OfferNumberResetPolicy::Yearly) {
                if ($settings->last_sequence_year !== $year) {
                    $settings->last_sequence_year = $year;
                    $settings->last_sequence = 0;
                }
            }

            $settings->last_sequence++;
            $settings->save();

            $suffix = str_pad((string) $settings->last_sequence, max(1, (int) $settings->number_padding), '0', STR_PAD_LEFT);
            $prefix = $settings->number_prefix ?: 'OFF';

            if ($policy === OfferNumberResetPolicy::Yearly) {
                return sprintf('%s-%d-%s', trim($prefix, '- '), $year, $suffix);
            }

            return sprintf('%s-%s', trim($prefix, '- '), $suffix);
        });
    }

    public static function allocateTemplateNumber(): string
    {
        return 'TPL-'.strtoupper(bin2hex(random_bytes(6)));
    }
}
