<?php

namespace App\Domain\Training\Services;

use App\Domain\Shared\Exceptions\DomainException;
use App\Domain\Training\Models\TrainingProgram;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class TrainingProgramService
{
    public function create(array $data, User $actor): TrainingProgram
    {
        return DB::transaction(function () use ($data, $actor) {
            $slug = Str::limit($data['slug'] ?? Str::slug($data['name']), 90, '');
            $exists = TrainingProgram::where('slug', $slug)->exists();
            if ($exists) {
                $slug = Str::limit($slug, 85, '') . '-' . Str::random(4);
            }

            return TrainingProgram::create(array_merge($data, [
                'slug' => $slug,
                'created_by' => $actor->id,
            ]));
        });
    }

    public function update(TrainingProgram $program, array $data): TrainingProgram
    {
        return DB::transaction(function () use ($program, $data) {
            if (isset($data['slug']) && $data['slug'] !== $program->slug) {
                $exists = TrainingProgram::where('slug', $data['slug'])
                    ->where('id', '!=', $program->id)
                    ->exists();
                if ($exists) {
                    throw new DomainException('هذا المعرف مستخدم بالفعل');
                }
            }
            $program->update($data);
            return $program->fresh();
        });
    }

    public function changeStatus(TrainingProgram $program, string $newStatus): TrainingProgram
    {
        $allowed = match ($program->status->value ?? $program->status) {
            'draft' => ['active'],
            'active' => ['full', 'closed', 'archived'],
            'full' => ['active', 'closed'],
            'closed' => ['archived', 'active'],
            default => [],
        };

        if (!in_array($newStatus, $allowed)) {
            throw new DomainException("لا يمكن تغيير حالة البرنامج من '{$program->status->value}' إلى '{$newStatus}'");
        }

        $program->update(['status' => $newStatus]);
        return $program->fresh();
    }

    public function delete(TrainingProgram $program): void
    {
        DB::transaction(function () use ($program) {
            if ($program->groups()->whereIn('status', ['active', 'forming'])->exists()) {
                throw new DomainException('لا يمكن حذف برنامج يحتوي على مجموعات نشطة');
            }
            $program->delete();
        });
    }
}
