<?php

namespace App\Services\Accounting;

use App\Models\Branch;
use App\Models\DocumentSequence;
use Carbon\Carbon;
use Carbon\CarbonInterface;
use Illuminate\Support\Facades\DB;

final class JournalNumberService
{
    public function next(Branch $branch, CarbonInterface|string $date): string
    {
        $date = $date instanceof CarbonInterface ? $date : Carbon::parse($date);
        $year = (int) $date->format('Y');

        return DB::transaction(function () use ($branch, $year): string {
            $key = [
                'company_id' => $branch->company_id,
                'branch_id' => $branch->id,
                'document_type' => 'JV',
                'year' => $year,
                'month' => 0,
            ];
            DocumentSequence::query()->insertOrIgnore($key + [
                'last_number' => 0,
                'pattern' => '{BRANCH}-JV-{YEAR}-{SEQUENCE}',
                'created_at' => now(),
                'updated_at' => now(),
            ]);
            $sequence = DocumentSequence::query()->where($key)->lockForUpdate()->firstOrFail();
            $sequence->last_number = (int) $sequence->last_number + 1;
            $sequence->save();

            return strtr($sequence->pattern, [
                '{BRANCH}' => strtoupper($branch->code),
                '{YEAR}' => (string) $year,
                '{SEQUENCE}' => str_pad((string) $sequence->last_number, 6, '0', STR_PAD_LEFT),
            ]);
        }, 3);
    }
}
