<?php

namespace App\Services\Admin;

use App\Models\AuditLog;
use App\Models\Exercise;
use App\Services\FileUploadService;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\DB;

class ExerciseService
{
    public function __construct(private readonly FileUploadService $uploader)
    {
    }

    public function create(array $data, int $adminUserId, ?UploadedFile $gif = null, ?UploadedFile $image = null): Exercise
    {
        return DB::transaction(function () use ($data, $adminUserId, $gif, $image) {
            $exercise = Exercise::create([
                ...$this->baseFields($data),
                'created_by' => $adminUserId,
                'updated_by' => $adminUserId,
            ]);

            $this->syncRelations($exercise, $data);
            $this->handleMedia($exercise, $gif, $image);

            AuditLog::record('exercise.created', $exercise, newValues: ['name' => $exercise->name]);

            return $exercise;
        });
    }

    public function update(Exercise $exercise, array $data, int $adminUserId, ?UploadedFile $gif = null, ?UploadedFile $image = null): Exercise
    {
        return DB::transaction(function () use ($exercise, $data, $adminUserId, $gif, $image) {
            $old = $exercise->only(['name', 'difficulty', 'is_active']);

            $exercise->update([
                ...$this->baseFields($data),
                'updated_by' => $adminUserId,
            ]);

            $this->syncRelations($exercise, $data);
            $this->handleMedia($exercise, $gif, $image);

            AuditLog::record('exercise.updated', $exercise, oldValues: $old, newValues: $exercise->only(array_keys($old)));

            return $exercise;
        });
    }

    public function delete(Exercise $exercise): void
    {
        $exercise->update(['is_active' => false]);
        $exercise->delete();

        AuditLog::record('exercise.deleted', $exercise);
    }

    private function baseFields(array $data): array
    {
        return [
            'name' => $data['name'],
            'name_en' => $data['name_en'] ?? null,
            'main_muscle_id' => $data['main_muscle_id'] ?? null,
            'difficulty' => $data['difficulty'],
            'description' => $data['description'] ?? null,
            'is_active' => $data['is_active'] ?? true,
        ];
    }

    private function syncRelations(Exercise $exercise, array $data): void
    {
        $exercise->involvedMuscles()->sync($data['muscle_ids'] ?? []);
        $exercise->equipment()->sync($data['equipment_ids'] ?? []);
    }

    private function handleMedia(Exercise $exercise, ?UploadedFile $gif, ?UploadedFile $image): void
    {
        if ($gif) {
            $old = $exercise->gif_path;
            $result = $this->uploader->store($gif, 'exercise_gif', 'exercises/gif');
            $exercise->update(['gif_path' => $result['path']]);
            if ($old) {
                $this->uploader->delete('public', $old);
            }
        }

        if ($image) {
            $old = $exercise->image_path;
            $result = $this->uploader->store($image, 'exercise_image', 'exercises/image');
            $exercise->update(['image_path' => $result['path']]);
            if ($old) {
                $this->uploader->delete('public', $old);
            }
        }
    }
}
