<?php

namespace App\Http\Controllers\Coach;

use App\Http\Controllers\Controller;
use App\Models\Client;
use App\Models\Exercise;
use App\Models\ExerciseLibrary;
use App\Models\Setting;
use App\Models\User;
use App\Models\Workout;
use App\Notifications\AdminWorkoutCreated;
use App\Notifications\WorkoutAssigned;
use App\Notifications\WorkoutUpdated;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

class WorkoutController extends Controller
{
    /**
     * Display a listing of workouts for a client.
     */
    public function index(Request $request, Client $client): Response
    {
        $this->authorize('view', $client);

        return Inertia::render('Coach/Workouts/Index', [
            'client' => $client,
            'workouts' => $client->workouts()->with('exercises')->latest()->get(),
        ]);
    }

    /**
     * Show the form for creating a new workout.
     */
    public function create(Request $request, Client $client): Response
    {
        $this->authorize('update', $client);

        // Load exercises from library (system + coach's custom)
        $exercises = ExerciseLibrary::forCoach($request->user()->id)
            ->active()
            ->orderBy('muscle_group')
            ->orderBy('name')
            ->get();

        return Inertia::render('Coach/Workouts/Create', [
            'client' => $client,
            'exercises' => $exercises,
            'muscleGroups' => ExerciseLibrary::MUSCLE_GROUPS,
            'categories' => ExerciseLibrary::CATEGORIES,
        ]);
    }

    /**
     * Store a newly created workout.
     */
    public function store(Request $request, Client $client): RedirectResponse
    {
        $this->authorize('update', $client);

        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'description' => 'nullable|string|max:1000',
            'is_active' => 'boolean',
            'days' => 'nullable|array',
            'days.*' => 'string|in:LUN,MAR,MIE,JUE,VIE,SAB,DOM',
            'exercises' => 'required|array|min:1',
            'exercises.*.name' => 'required|string|max:255',
            'exercises.*.muscle_group' => 'nullable|string|max:50',
            'exercises.*.sets' => 'required|integer|min:1|max:20',
            'exercises.*.reps' => 'required|string|max:20',
            'exercises.*.rest' => 'nullable|string|max:20',
            'exercises.*.notes' => 'nullable|string|max:500',
            'exercises.*.gif_url' => 'nullable|string|max:500',
            'exercises.*.day' => 'nullable|string|max:10',
        ]);

        // Deactivate other workouts if this one should be active
        if ($request->boolean('is_active', true)) {
            $client->workouts()->update(['is_active' => false]);
        }

        $workout = $client->workouts()->create([
            'name' => $validated['name'],
            'description' => $validated['description'] ?? null,
            'days' => $validated['days'] ?? [],
            'is_active' => $request->boolean('is_active', true),
        ]);

        // Create exercises
        foreach ($validated['exercises'] as $index => $exerciseData) {
            $workout->exercises()->create([
                'name' => $exerciseData['name'],
                'muscle_group' => $exerciseData['muscle_group'] ?? 'full_body',
                'sets' => $exerciseData['sets'],
                'reps' => $exerciseData['reps'],
                'rest_seconds' => is_numeric($exerciseData['rest'] ?? null) ? (int)$exerciseData['rest'] : 60,
                'notes' => $exerciseData['notes'] ?? null,
                'gif_url' => $exerciseData['gif_url'] ?? null,
                'order' => $exerciseData['order'] ?? $index,
                'day' => $exerciseData['day'] ?? null,
            ]);
        }

        // Send notification to client if they have a user account
        if ($client->clientUser) {
            $client->clientUser->notify(new WorkoutAssigned($workout));
        }

        // Notify admins about new workout creation
        if (Setting::get('notify_new_workout', true)) {
            $admins = User::where('role', 'admin')->where('status', 'active')->get();
            foreach ($admins as $admin) {
                $admin->notify(new AdminWorkoutCreated($workout, $request->user()));
            }
        }

        return redirect()->route('coach.clients.workouts.index', $client)
            ->with('success', 'Rutina creada correctamente.');
    }

    /**
     * Display the specified workout.
     */
    public function show(Request $request, Client $client, Workout $workout): Response
    {
        $this->authorize('view', $client);

        return Inertia::render('Coach/Workouts/Show', [
            'client' => $client,
            'workout' => $workout->load('exercises'),
        ]);
    }

    /**
     * Show the form for editing the specified workout.
     */
    public function edit(Request $request, Client $client, Workout $workout): Response
    {
        $this->authorize('update', $client);

        // Load exercises from library (system + coach's custom)
        $exercises = ExerciseLibrary::forCoach($request->user()->id)
            ->orderBy('name')
            ->get(['id', 'name', 'muscle_group', 'gif_url', 'instructions']);

        return Inertia::render('Coach/Workouts/Edit', [
            'client' => $client,
            'workout' => $workout->load('exercises'),
            'exercises' => $exercises,
            'muscleGroups' => [
                'chest' => 'Pecho',
                'back' => 'Espalda',
                'shoulders' => 'Hombros',
                'biceps' => 'Bíceps',
                'triceps' => 'Tríceps',
                'legs' => 'Piernas',
                'glutes' => 'Glúteos',
                'abs' => 'Abdominales',
                'cardio' => 'Cardio',
                'full_body' => 'Cuerpo Completo',
            ],
        ]);
    }

    /**
     * Update the specified workout.
     */
    public function update(Request $request, Client $client, Workout $workout): RedirectResponse
    {
        $this->authorize('update', $client);

        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'description' => 'nullable|string|max:1000',
            'days' => 'required|array|min:1',
            'duration_weeks' => 'nullable|integer|min:1|max:52',
            'exercises' => 'required|array|min:1',
            'exercises.*.id' => 'nullable|exists:exercises,id',
            'exercises.*.name' => 'required|string|max:255',
            'exercises.*.muscle_group' => 'required|string|max:50',
            'exercises.*.sets' => 'required|integer|min:1|max:20',
            'exercises.*.reps' => 'required|string|max:20',
            'exercises.*.rest_seconds' => 'nullable|integer|min:0|max:600',
            'exercises.*.notes' => 'nullable|string|max:500',
            'exercises.*.video_url' => 'nullable|url|max:255',
            'exercises.*.gif_url' => 'nullable|string|max:500',
            'exercises.*.day' => 'nullable|string|max:10',
        ]);

        $workout->update([
            'name' => $validated['name'],
            'description' => $validated['description'] ?? null,
            'days' => $validated['days'],
            'duration_weeks' => $validated['duration_weeks'] ?? null,
        ]);

        // Sync exercises
        $existingIds = [];
        foreach ($validated['exercises'] as $index => $exerciseData) {
            if (isset($exerciseData['id'])) {
                $exercise = Exercise::find($exerciseData['id']);
                if ($exercise && $exercise->workout_id === $workout->id) {
                    $exercise->update([...$exerciseData, 'order' => $index]);
                    $existingIds[] = $exercise->id;
                }
            } else {
                $newExercise = $workout->exercises()->create([
                    ...$exerciseData,
                    'order' => $index,
                ]);
                $existingIds[] = $newExercise->id;
            }
        }

        // Delete removed exercises
        $workout->exercises()->whereNotIn('id', $existingIds)->delete();

        // Send notification to client if they have a user account
        if ($client->clientUser) {
            $client->clientUser->notify(new WorkoutUpdated($workout));
        }

        return back()->with('success', 'Rutina actualizada correctamente.');
    }

    /**
     * Remove the specified workout.
     */
    public function destroy(Request $request, Client $client, Workout $workout): RedirectResponse
    {
        $this->authorize('update', $client);

        $workoutName = $workout->name;
        $coachName = $request->user()->name;

        $workout->delete();

        // Notify client if they have a user account
        if ($client->user) {
            $client->user->notify(new \App\Notifications\WorkoutDeleted($workoutName, $coachName));
        }

        return redirect()->route('coach.clients.workouts.index', $client)
            ->with('success', 'Rutina eliminada correctamente.');
    }

    /**
     * Toggle workout active status.
     */
    public function toggleActive(Request $request, Client $client, Workout $workout): RedirectResponse
    {
        $this->authorize('update', $client);

        if (!$workout->is_active) {
            // Deactivate other workouts first
            $client->workouts()->where('id', '!=', $workout->id)->update(['is_active' => false]);
        }

        $workout->update(['is_active' => !$workout->is_active]);

        return back()->with('success', $workout->is_active ? 'Rutina activada.' : 'Rutina desactivada.');
    }

    /**
     * Duplicate a workout.
     */
    public function duplicate(Request $request, Client $client, Workout $workout): RedirectResponse
    {
        $this->authorize('update', $client);

        $newWorkout = $workout->replicate();
        $newWorkout->name = $workout->name . ' (Copia)';
        $newWorkout->is_active = false;
        $newWorkout->save();

        foreach ($workout->exercises as $exercise) {
            $newExercise = $exercise->replicate();
            $newExercise->workout_id = $newWorkout->id;
            $newExercise->save();
        }

        return back()->with('success', 'Rutina duplicada correctamente.');
    }
}
