<?php

namespace App\Http\Controllers;

use App\Models\Video;
use Illuminate\Http\Request;
use App\Http\Requests\CreateVideoRequest;
use App\Http\Requests\UpdateVideoRequest;
use Illuminate\Support\Facades\Storage;
use App\Models\Category;

class VideosController extends Controller
{
    public function __construct()
    {
        // Aumentar limites temporariamente para uploads grandes
        // Nota: Estas configurações devem ser feitas antes do PHP processar o POST
        // Por isso também estão no public/index.php
        @ini_set('upload_max_filesize', '200M');
        @ini_set('post_max_size', '200M');
        @ini_set('max_execution_time', '300'); // 5 minutos
        @ini_set('max_input_time', '300');
        @ini_set('memory_limit', '512M');
    }

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

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

        $userId = $user->id;
        $role = $user->role_id;

        $search = trim((string) $request->query('search', ''));
        $categoryId = $request->query('category');
        $watched = $request->query('watched');
        $perPage = $request->query('per_page', 9);

        $query = Video::select(['id', 'title', 'thumbnail', 'is_active'])
            ->with([
                'categories:id,name',
                'views' => function ($q) use ($user) {
                    $q->select('id', 'video_id', 'user_id')
                        ->where('user_id', $user->id);
                }
            ])

            ->when($search !== '', function ($q) use ($search) {
                $q->where(function ($sub) use ($search) {
                    $sub->where('title', 'like', "%{$search}%")
                        ->orWhere('tags', 'like', "%{$search}%");
                });
            })

            ->when($categoryId, function ($q) use ($categoryId) {
                $q->whereHas('categories', function ($c) use ($categoryId) {
                    $c->where('categories.id', $categoryId);
                });
            })

            ->when($user->role_id !== 1, function ($q) {
                $q->where('is_active', true);
            })

            ->when($watched !== null, function ($q) use ($watched, $user) {

                if ((int) $watched === 1) {
                    $q->whereHas('views', function ($v) use ($user) {
                        $v->where('user_id', $user->id);
                    });
                }

                if ((int) $watched === 0) {
                    $q->whereDoesntHave('views', function ($v) use ($user) {
                        $v->where('user_id', $user->id);
                    });
                }
            })

            ->orderByRaw('
                CASE WHEN EXISTS (
                    SELECT 1 FROM video_views
                    WHERE video_views.video_id = videos.id
                    AND video_views.user_id = ?
                ) THEN 1 ELSE 0 END ASC,
                videos.order ASC
            ', [$user->id])
            ->paginate($perPage);

        $query->getCollection()->transform(function ($video) {
            return [
                'id' => $video->id,
                'title' => $video->title,
                'thumbnail' => $video->thumbnail,
                'is_active' => $video->is_active,
                'categories' => $video->categories,
                'watched' => $video->views->isNotEmpty(),
            ];
        });

        $categories = Category::select('id', 'name')
            ->where('is_active', true)
            ->whereHas('videos')
            ->orderBy('name', 'asc')
            ->get();

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

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

        if (!$user) {
            return response()->json([
                'message' => 'Não autenticado',
            ], 401);
        }

        $videos = Video::select(['id', 'title', 'thumbnail', 'is_active', 'order'])
            ->with(['categories:id,name'])

            // 👇 regra base: vídeos não vistos
            ->whereDoesntHave('views', function ($q) use ($user) {
                $q->where('user_id', $user->id);
            })

            // 👇 users normais não veem inativos
            ->when($user->role_id !== 1, function ($q) {
                $q->where('is_active', true);
            })

            ->orderBy('order', 'asc')
            ->limit(3)
            ->get()
            ->map(function ($video) {
                return [
                    'id' => $video->id,
                    'title' => $video->title,
                    'thumbnail' => $video->thumbnail,
                    'is_active' => $video->is_active,
                    'categories' => $video->categories,
                    'watched' => false, // aqui já sabes que não foram vistos
                ];
            });

        return response()->json([
            'message' => 'Dashboard videos',
            'data' => $videos,
        ]);
    }


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

        $search = trim((string) $request->query('search', ''));

        $videos = Video::select(['id', 'title', 'thumbnail', 'is_active'])
            ->with([
                'categories:id,name',
                'views' => function ($query) use ($user) {
                    $query->select('id', 'video_id', 'user_id')
                        ->where('user_id', $user->id);
                }
            ])
            ->when($user->role_id !== 1, function ($query) {
                $query->where('is_active', true);
            })
            ->where(function ($query) use ($search) {
                $query->where('title', 'like', "%{$search}%")
                    ->orWhere('tags', 'like', "%{$search}%");
            })
            ->limit(20)
            ->get()
            ->map(function ($video) {
                return [
                    'id' => $video->id,
                    'title' => $video->title,
                    'thumbnail' => $video->thumbnail,
                    'is_active' => $video->is_active,
                    'categories' => $video->categories,
                    'watched' => $video->views->isNotEmpty(),
                ];
            });

        return response()->json([
            'message' => 'Resultados obtidos com sucesso',
            'data' => $videos,
        ]);
    }

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

        if ($user->role_id !== 1) {
            $videos = Video::select('id')->with('views')->where('is_active', true)->count();
            $videosWatched = Video::with('views')->where('is_active', true)->whereHas('views', function ($query) use ($userID) {
                $query->where('user_id', $userID);
            })->count();
        } else {
            $videos = Video::select('id')->with('views')->where('is_active', true)->count();
        }

        return response()->json([
            'message' => 'Vídeos ativos obtidos com sucesso',
            'data' => [
                'videos' => $videos,
                'videosWatched' => $videosWatched ?? 0,
            ],
            'errors' => null,
        ], 200);
    }

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

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

        $userID = $user->id;

        if ($user->role_id !== 1) {
            /*             $video = Video::with('categories')->where('is_active', true)->find($id); */
            $video = Video::with([
                'categories' => function ($query) use ($userID) {
                    $query->where('is_active', true);
                },
                'views' => function ($query) use ($userID) {
                    $query->where('user_id', $userID);
                }
            ])->find($id);

            /* Para não mostrar vídeos inactivos para utilizadores não administradores */
            if (!$video || $video->is_active === false) {
                return response()->json([
                    'message' => 'Acesso negado',
                    'data' => null,
                    'errors' => null,
                ], 404);
            }
        }

        $video = Video::with('categories')->find($id);


        if ($video) {
            $video->url = Storage::url($video->url);
            $video->thumbnail = Storage::url($video->thumbnail);
            return response()->json([
                'message' => 'Vídeo obtido com sucesso',
                'data' => [
                    'id' => $video->id,
                    'title' => $video->title,
                    'description' => $video->description,
                    'url' => $video->url,
                    'thumbnail' => $video->thumbnail,
                    'duration' => $video->duration,
                    'tags' => $video->tags,
                    'order' => $video->order,
                    'categories' => $video->categories->map(function ($category) {
                        return [
                            'id' => $category->id,
                            'name' => $category->name,
                        ];
                    })->values(),
                    'is_active' => $video->is_active,
                    'watched' => $video->views->isNotEmpty(),
                ],
                'errors' => null,
            ], 200);
        } else {
            return response()->json([
                'message' => 'Vídeo não encontrado',
                'data' => null,
                'errors' => null,
            ], 404);
        }
    }


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

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

        $validated = $request->validated();

        $videoPath = $request->file('url')->store('videos', 'public');
        $thumbnailPath = $request->file('thumbnail')->store('thumbnails', 'public');

        $video = Video::create([
            'title' => $validated['title'],
            'description' => $validated['description'],
            'url' => $videoPath,
            'thumbnail' => $thumbnailPath,
            'duration' => $validated['duration'] ?? '00:00',
            'tags' => $validated['tags'],
            'order' => $validated['order'],
        ]);

        $video->categories()->sync($request->input('category_ids', []));

        $baseUrl = $request->getSchemeAndHttpHost();

        return response()->json([
            'message' => 'Vídeo adicionado com sucesso',
            'data' => [
                'id' => $video->id,
                'title' => $video->title,
                'description' => $video->description,
                'url' => $baseUrl . Storage::url($video->url),
                'thumbnail' => $baseUrl . Storage::url($video->thumbnail),
                'duration' => $video->duration,
                'tags' => $video->tags,
                'order' => $video->order,
                'categories' => $video->categories->pluck('name'),
                'is_active' => $video->is_active,
            ],
            'errors' => null,
        ], 201);
    }

    public function update(UpdateVideoRequest $request, $id)
    {
        $user = auth()->user();

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

        $videoToUpdate = Video::find($id);

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

        $validated = $request->validated();

        if ($request->hasFile('thumbnail')) {
            // Apagar thumbnail antiga
            if ($videoToUpdate->thumbnail && Storage::disk('public')->exists($videoToUpdate->thumbnail)) {
                Storage::disk('public')->delete($videoToUpdate->thumbnail);
            }
            $validated['thumbnail'] = $request->file('thumbnail')->store('thumbnails', 'public');
        }

        try {

            $videoToUpdate->update([
                'title' => $validated['title'] ?? $videoToUpdate->title,
                'description' => $validated['description'] ?? $videoToUpdate->description,
                'tags' => $validated['tags'] ?? $videoToUpdate->tags,
                'thumbnail' => $validated['thumbnail'] ?? $videoToUpdate->thumbnail,
                'is_active' => array_key_exists('is_active', $validated) ? $validated['is_active'] : $videoToUpdate->is_active,
                'order' => $validated['order'] ?? $videoToUpdate->order,
            ]);

            $videoToUpdate->categories()->sync($request->input('category_ids', []));

            return response()->json([
                'message' => 'Dados do vídeo atualizados com sucesso',
                'data' => $videoToUpdate->load('categories'),
                'errors' => null,
            ], 200);
        } catch (\Throwable $th) {
            return response()->json([
                'message' => 'Não foi possível atualizar o vídeo',
                'data' => null,
                'errors' => null,
            ], 500);
        }
    }

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

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

        $video = Video::find($id);

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

        $video->delete();
        return response()->json([
            'message' => 'Vídeo apagado com sucesso',
            'data' => null,
            'errors' => null,
        ], 200);
    }
}
