<?php

namespace App\Http\Controllers;

use App\Http\Requests\CreateWorkshopRequest;
use App\Http\Requests\UpdateWorkshopRequest;
use App\Models\Workshop;
use Illuminate\Support\Facades\Storage;
use Illuminate\Http\Request;

class WorkshopsController extends Controller
{
    public function index(Request $request)
    {
        $user = auth()->user();

        if (!$user) {
            return response()->json([
                'message' => 'Utilizador não autenticado',
                'data' => null,
                'errors' => null,
            ], 404);
        }

        $role = $user->role_id;

        $search = trim((string) $request->query('search', ''));
        $status = trim((string) $request->query('status', ''));
        $perPage = $request->query('per_page', 9);
        $query = Workshop::select('id', 'title', 'image', 'date', 'time_start', 'time_end', 'status')->with('users:id')
        ->when($search !== '', function ($q) use ($search) {
            $q->where('title', 'like', "%{$search}%");
        })
        ->when($status !== '' && $status !== 'inscrito', function ($q) use ($status) {
            $q->where('status', $status);
        })
        ->when($status === 'inscrito', function ($q) use ($user) {
            $q->where('status', 'pending')
              ->whereHas('users', function ($q2) use ($user) {
                $q2->where('users.id', $user->id);
            });
        })
        ->when($user->role_id !== 1, function ($q) use ($user, $status) {
            if($status === 'pending'){

            } else {
                $q->whereHas('users', function ($q2) use ($user) {
                    $q2->where('users.id', $user->id);
                });
            };
        })
        ->orderBy('date', 'asc')
        ->orderBy('time_start', 'asc')
        ->paginate($perPage);

        $query->getCollection()->transform(function ($workshop) {
            return [
                'id'         => $workshop->id,
                'title'      => $workshop->title,
                'image'      => $workshop->image,
                'date'       => $workshop->date,
                'time_start' => $workshop->time_start,
                'time_end'   => $workshop->time_end,
                'status'     => $workshop->status,
                'users'      => $workshop->users,
            ];
        });

        return response()->json([
            'message' => 'Workshops obtidos com sucesso',
            'data' => $query->items(),
            'meta' => [
                'current_page' => $query->currentPage(),
                'last_page' => $query->lastPage(),
                'per_page' => $query->perPage(),
                'total' => $query->total(),
            ],
            'userId' => $user->id,
            'role' => $role,
        ]);
    }

    public function search(Request $request)
    {
        $user = auth()->user();

        $search = trim((string) $request->query('search', ''));
    
        $workshops = Workshop::select(['id', 'title', 'image', 'date', 'time_start', 'time_end', 'status'])
            ->when($user->role_id !== 1, function ($query) {
                $query->where('status', 'pending');
            })
            ->where(function ($query) use ($search) {
                $query->where('title', 'like', "%{$search}%");
            })
            ->orderBy('date', 'asc')
            ->orderBy('time_start', 'asc')
            ->limit(20)
            ->get()
            ->map(function ($workshop) {
                return [
                    'id' => $workshop->id,
                    'title' => $workshop->title,
                    'image' => $workshop->image,
                    'date' => $workshop->date,
                    'time_start' => $workshop->time_start,
                    'time_end' => $workshop->time_end,
                    'status' => $workshop->status,
                ];
            });
    
        return response()->json([
            'message' => 'Resultados obtidos com sucesso',
            'data' => $workshops,
        ]);
    }

    public function getWorkshop($id)
    {
        $workshop = Workshop::with('users')->find($id);

        $user = auth()->user();
        $userId = $user->id;
        $role = $user->role_id;

        if (!$workshop) {
            return response()->json([
                'message' => 'Workshop não encontrado',
                'data' => null,
                'errors' => null,
            ], 404);
        }
        return response()->json([
            'message' => 'Workshop obtido com sucesso',
            'data' => $workshop,
            'errors' => null,
            'role' => $role,
            'userId' => $userId,
        ], 200);
    }

    public function create(CreateWorkshopRequest $request)
    {
        $user = auth()->user();

        if (!$user) {
            return response()->json([
                'message' => 'Utilizador não autenticado',
                'data' => null,
                'errors' => null,
            ], 404);
        }

        $validated = $request->validated();
        try {

        $imagePath = $request->file('image')->store('imageWorkshops', 'public');
            $workshop = Workshop::create([
                'title' => $validated['title'],
                'description' => $validated['description'],
                'status' => 'pending',
                'image' => $imagePath,
                'date' => $validated['date'],
                'time_start' => $validated['time_start'],
                'time_end' => $validated['time_end'],
            ]);

            $baseUrl = $request->getSchemeAndHttpHost();

            return response()->json([
                'message' => 'Workshop criado com sucesso',
                'data' => [
                    'id' => $workshop->id,
                    'title' => $workshop->title,
                    'description' => $workshop->description,
                    'image' => $baseUrl . Storage::url($workshop->image),
                    'date' => $workshop->date,
                    'time_start' => $workshop->time_start,
                    'time_end' => $workshop->time_end,
                    'status' => $workshop->status,
                ],
                'errors' => null,
            ], 201);
        } catch (\Illuminate\Validation\ValidationException $e) {
            return response()->json([
                'message' => 'Erro ao criar o workshop',
                'data' => null,
                'errors' => $e->errors(),
            ], 422);
        } catch (\Throwable $th) {
            return response()->json([
                'message' => 'Não foi possível criar o workshop',
                'data' => null,
                'errors' => $th->getMessage(),
            ], 500);
        }
    }

    public function update(UpdateWorkshopRequest $request, $id)
    {

        $user = auth()->user();

        if (!$user) {
            return response()->json([
                'message' => 'Utilizador não autenticado',
                'data' => null,
                'errors' => null,
            ], 404);
        }

        $validated = $request->validated();

        if ($request->hasFile('image')) {
            $imagePath = $request->file('image')->store('imageWorkshops', 'public');
            $validated['image'] = $imagePath;
        }

        $workshop = Workshop::find($id);

        if (!$workshop) {
            return response()->json([
                'message' => 'Workshop não encontrado',
                'data' => null,
                'errors' => null,
            ], 404);
        }

        try {
            $workshop->update($validated);

            return response()->json([
                'message' => 'Workshop atualizado com sucesso',
                'data' => $workshop,
                'errors' => null,
            ], 200);
        } catch (\Illuminate\Validation\ValidationException $e) {
            return response()->json([
                'message' => 'Erro ao atualizar o workshop',
                'data' => null,
                'errors' => [
                    'message' => 'Erro ao atualizar o workshop',
                    'errors' => $e->errors(),
                ],
            ], 422);
        } catch (\Throwable $th) {
            return response()->json([
                'message' => 'Não foi possível atualizar o workshop',
                'data' => null,
                'errors' => [
                    'message' => 'Não foi possível atualizar o workshop',
                    'errors' => $th->getMessage(),
                ],
            ], 500);
        }
    }

    public function destroy($id)
    {
        $user = auth()->user();

        if (!$user) {
            return response()->json([
                'message' => 'Utilizador não autenticado',
                'data' => null,
                'errors' => null,
            ], 404);
        }

        $workshop = Workshop::find($id);

        if (!$workshop) {
            return response()->json([
                'message' => 'Workshop não encontrado',
                'data' => null,
                'errors' => null,
            ], 404);
        }

        try {
            $workshop->delete();

            return response()->json([
                'message' => 'Workshop apagado com sucesso',
                'data' => null,
                'errors' => null,
            ], 200);
        } catch (\Throwable $th) {
            return response()->json([
                'message' => 'Não foi possível apagar o workshop',
                'data' => null,
                'errors' => $th->getMessage(),
            ], 500);
        }
    }

    /*  
    Workshop inexistente - 404 

    Workshop canceled ou realized - 422 - não aceitar novas inscrições

    Utilizador já inscrito - 409 ou 200 com mensagem “já inscrito” (escolher um e mantém em todo o projeto)

    Cancelar inscrição sem estar inscrito - 404 ou 422

    Admin - Pode inscrever-se como qualquer utilizador autenticado, salvo regra explícita em contrário

    is_active === false - Bloquear inscrição se usares este campo na listagem
    */

    public function inscrever($id)
    {
        $user = auth()->user();

        if (!$user) {
            return response()->json([
                'message' => 'Utilizador não autenticado',
                'data' => null,
                'errors' => null,
            ], 404);
        }

        $workshop = Workshop::find($id);

        if (!$workshop) {
            return response()->json([
                'message' => 'Workshop não encontrado',
                'data' => null,
                'errors' => null,
            ], 404);
        }

        if ($workshop->status !== 'pending') {
            return response()->json([
                'message' => 'Já não é possível inscrever-se neste Workshop',
                'data' => null,
                'errors' => null,
            ], 422);
        }

        if ($workshop->users()->where('user_id', $user->id)->exists()) {
            return response()->json([
                'message' => 'Já está inscrito neste Workshop',
                'data' => null,
                'errors' => null,
            ], 409);
        }

        $workshop->users()->attach($user->id);

        return response()->json([
            'message' => 'Inscrição realizada',
            'data' => null,
            'errors' => null,
        ], 200);
    }

    public function cancelarInscricao($id)
    {
        $user = auth()->user();

        if (!$user) {
            return response()->json([
                'message' => 'Utilizador não autenticado',
                'data' => null,
                'errors' => null,
                ], 404);
        }

        $workshop = Workshop::find($id);

        if (!$workshop) {
            return response()->json([
                'message' => 'Workshop não encontrado',
                'data' => null,
                'errors' => null,
            ], 404);
        }

        if (!$workshop->users()->where('user_id', $user->id)->exists()) {
            return response()->json([
                'message' => 'Não está inscrito neste Workshop',
                'data' => null,
                'errors' => null,
                ], 404);
        }

        $workshop->users()->detach($user->id);

        return response()->json([
            'message' => 'Inscrição anulada',
            'data' => null,
            'errors' => null,
        ], 200);
    }
}
