<?php

namespace App\Domain\Training\Support;

use App\Domain\Shared\Exceptions\DomainException;
use App\Domain\Training\Enums\EnrollmentStatus;
use App\Domain\Training\Models\Enrollment;
use Illuminate\Database\Eloquent\Builder;

/**
 * Refuse a destructive delete while enrolments still point at the thing.
 *
 * `enrollments` is the only table GenerateRenewalInvoices bills from, so an
 * enrolment destroyed alongside its group or programme does not merely lose
 * history: the player silently stops being billed, keeps training, and no
 * screen, log or report anywhere says so. That is not hypothetical. OC-Sport's
 * season programmes were deleted and recreated under new names on 28 August
 * 2026; `forceDelete()` took 181 enrolments with them; 95 paying players got no
 * September invoice at all, and the first anyone knew of it was a parent asking
 * why there was no bill.
 *
 * Terminal enrolments count too. A cancelled enrolment is still the only record
 * of what an issued invoice bought, and issued invoices are frozen.
 */
trait GuardsEnrolmentDeletion
{
    /**
     * The count deliberately drops the branch scope. An enrolment hidden
     * because the user is looking at another branch is still an enrolment, and
     * reading zero because of it is exactly how a guard like this fails open.
     *
     * @param  Builder<Enrollment>  $enrolments  every enrolment the delete would destroy
     * @param  string  $noun  what is being deleted, in Arabic, for the message
     * @param  string  $instead  the non-destructive route to offer, in Arabic
     */
    protected function guardEnrolmentsExist(Builder $enrolments, string $noun, string $instead): void
    {
        $active = (clone $enrolments)
            ->whereIn('status', [EnrollmentStatus::Active->value, EnrollmentStatus::Pending->value])
            ->count();

        if ($active > 0) {
            throw new DomainException(
                "لا يمكن حذف {$noun}: بها {$active} اشتراك نشط. {$instead}."
            );
        }

        $historical = $enrolments->count();

        if ($historical > 0) {
            throw new DomainException(
                "لا يمكن حذف {$noun}: مرتبط بها {$historical} اشتراك سابق تستند إليه فواتير صادرة. {$instead}."
            );
        }
    }
}
