<?php

declare(strict_types=1);

namespace Maestro\Core\Modules\Invoices\Services;

use Illuminate\Support\Facades\DB;
use Maestro\Core\Modules\Invoices\Enums\InvoiceType;
use Maestro\Core\Modules\Invoices\Models\Invoice;

final class InvoiceNumberService
{
    public static function assignNext(Invoice $invoice): void
    {
        if ($invoice->document_number !== null) {
            return;
        }

        $year = (int) $invoice->invoice_date->format('Y');
        $type = $invoice->type instanceof InvoiceType ? $invoice->type->value : (string) $invoice->type;

        DB::transaction(function () use ($invoice, $year, $type): void {
            $max = (int) (Invoice::query()
                ->where('type', $type)
                ->where('fiscal_year', $year)
                ->whereNotNull('sequence_value')
                ->lockForUpdate()
                ->max('sequence_value') ?? 0);

            $next = $max + 1;
            $prefix = $type === InvoiceType::CreditNote->value ? 'CN' : 'INV';

            $invoice->document_number = sprintf('%s-%d-%05d', $prefix, $year, $next);
            $invoice->fiscal_year = $year;
            $invoice->sequence_value = $next;
            $invoice->save();
        });
    }
}
