<?php

namespace App\Services\Accounting;

use App\Models\AccountingPeriod;
use Carbon\CarbonInterface;
use DomainException;

final class AccountingPeriodGuard
{
    public function openPeriodFor(int $companyId, CarbonInterface|string $postingDate): AccountingPeriod
    {
        $date = is_string($postingDate) ? $postingDate : $postingDate->toDateString();
        $period = AccountingPeriod::query()
            ->whereHas('fiscalYear', fn ($query) => $query->where('company_id', $companyId))
            ->whereDate('starts_on', '<=', $date)
            ->whereDate('ends_on', '>=', $date)
            ->lockForUpdate()
            ->first();

        if (! $period) {
            throw new DomainException("No accounting period exists for {$date}.");
        }
        if ($period->is_locked) {
            throw new DomainException("Accounting period {$period->name} is locked.");
        }
        return $period;
    }
}
