<?php

namespace App\Domain\Participant\Services;

use App\Domain\Participant\Models\Participant;
use App\Domain\Shared\Exceptions\DomainException;
use App\Domain\Training\Models\Enrollment;
use Illuminate\Support\Facades\DB;

class TransferService
{
    public function transferToBranch(Participant $participant, int $newBranchId, string $reason, $actor): Participant
    {
        if ($participant->branch_id === $newBranchId) {
            throw new DomainException('المشترك مسجل بالفعل في هذا الفرع');
        }

        if ($participant->status === 'blacklisted') {
            throw new DomainException('لا يمكن نقل مشترك محظور');
        }

        // Cross-branch by definition, and therefore explicit: this is the one
        // operation whose whole purpose is to move a member from one branch to
        // another. Scoped, the enrolment cancellation below would only reach
        // the rows visible from the branch the operator happens to be in, and
        // the member would arrive at the new branch still actively enrolled in
        // the old one's groups — on its rosters, its attendance sheets and its
        // session lists forever.
        return Participant::acrossBranches(fn () => DB::transaction(function () use ($participant, $newBranchId, $reason, $actor) {
            $oldBranchId = $participant->branch_id;

            Enrollment::where('participant_id', $participant->id)
                ->where('status', 'active')
                ->update(['status' => 'cancelled']);

            $participant->update([
                'branch_id' => $newBranchId,
                'status' => 'active',
                'notes' => trim(($participant->notes ?? '') . "\nنقل من فرع {$oldBranchId} - السبب: {$reason} - بتاريخ " . now()->format('Y-m-d')),
            ]);

            return $participant->fresh();
        }));
    }
}
