<?php

namespace Functional\Programs\Services;

use Functional\Programs\Models\Program;
use Functional\Users\Models\User;
use Illuminate\Support\Str;

/**
 * Création/mise à jour d'un programme et synchronisation de son planning (program_slots).
 */
class ProgramService
{
    /** Champs propres au programme (les slots sont synchronisés à part). */
    private const PROGRAM_FIELDS = ['name', 'description', 'duration_weeks', 'days_per_week', 'is_public'];

    public function create(User $user, array $data): Program
    {
        $program = new Program($this->programAttributes($data));
        $program->user_id = $user->id;
        $program->slug = Str::slug($data['name']);
        $program->save();

        $this->syncSlots($program, $data['slots'] ?? []);

        return $program->load('programSlots');
    }

    public function update(Program $program, array $data): Program
    {
        $program->fill($this->programAttributes($data));

        if (array_key_exists('name', $data)) {
            $program->slug = Str::slug($data['name']);
        }

        $program->save();

        if (array_key_exists('slots', $data)) {
            $this->syncSlots($program, $data['slots']);
        }

        return $program->load('programSlots');
    }

    private function programAttributes(array $data): array
    {
        return array_intersect_key($data, array_flip(self::PROGRAM_FIELDS));
    }

    /** Remplace intégralement le planning par la liste fournie (purge puis recrée). */
    private function syncSlots(Program $program, array $slots): void
    {
        $program->programSlots()->delete();

        foreach ($slots as $slot) {
            $program->programSlots()->create([
                'week' => $slot['week'],
                'weekday' => $slot['weekday'],
                'routine_id' => $slot['routine_id'] ?? null,
                'label' => $slot['label'] ?? null,
            ]);
        }
    }
}
