<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Quiz;
use App\Services\QuizService;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;

class QuizController extends Controller
{
    public function __construct(
        private QuizService $quizService
    ) {}

    /**
     * Display a listing of quizzes.
     */
    public function index(Request $request): JsonResponse
    {
        $query = Quiz::query();

        // Apply filters
        if ($request->has('status')) {
            $query->where('status', $request->status);
        }

        if ($request->has('visibility')) {
            $query->where('visibility', $request->visibility);
        }

        if ($request->has('is_active')) {
            $query->where('is_active', $request->boolean('is_active'));
        }

        if ($request->has('created_by')) {
            $query->where('created_by', $request->created_by);
        }

        if ($request->has('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('title', 'like', "%{$search}%")
                  ->orWhere('description', 'like', "%{$search}%");
            });
        }

        // Apply sorting
        $sortBy = $request->get('sort_by', 'created_at');
        $sortDirection = $request->get('sort_direction', 'desc');
        $query->orderBy($sortBy, $sortDirection);

        // Pagination
        $perPage = $request->get('per_page', 15);
        $quizzes = $query->with(['creator', 'questions'])
                        ->paginate($perPage);

        return response()->json([
            'success' => true,
            'data' => $quizzes,
        ]);
    }

    /**
     * Store a newly created quiz.
     */
    public function store(Request $request): JsonResponse
    {
        try {
            $quiz = $this->quizService->createQuiz($request->all(), Auth::id());

            return response()->json([
                'success' => true,
                'message' => 'Quiz created successfully',
                'data' => $quiz->load(['creator', 'questions']),
            ], 201);
        } catch (ValidationException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $e->errors(),
            ], 422);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to create quiz',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Display the specified quiz.
     */
    public function show(Quiz $quiz): JsonResponse
    {
        $quiz->load(['creator', 'questions', 'attempts']);

        return response()->json([
            'success' => true,
            'data' => $quiz,
        ]);
    }

    /**
     * Update the specified quiz.
     */
    public function update(Request $request, Quiz $quiz): JsonResponse
    {
        try {
            $quiz = $this->quizService->updateQuiz($quiz, $request->all(), Auth::id());

            return response()->json([
                'success' => true,
                'message' => 'Quiz updated successfully',
                'data' => $quiz->load(['creator', 'questions']),
            ]);
        } catch (ValidationException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Validation failed',
                'errors' => $e->errors(),
            ], 422);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to update quiz',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Remove the specified quiz.
     */
    public function destroy(Quiz $quiz): JsonResponse
    {
        try {
            $this->quizService->deleteQuiz($quiz, Auth::id());

            return response()->json([
                'success' => true,
                'message' => 'Quiz deleted successfully',
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to delete quiz',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Publish the specified quiz.
     */
    public function publish(Quiz $quiz): JsonResponse
    {
        try {
            $quiz = $this->quizService->publishQuiz($quiz, Auth::id());

            return response()->json([
                'success' => true,
                'message' => 'Quiz published successfully',
                'data' => $quiz,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to publish quiz',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Unpublish the specified quiz.
     */
    public function unpublish(Quiz $quiz): JsonResponse
    {
        try {
            $quiz = $this->quizService->unpublishQuiz($quiz, Auth::id());

            return response()->json([
                'success' => true,
                'message' => 'Quiz unpublished successfully',
                'data' => $quiz,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to unpublish quiz',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Get quiz statistics.
     */
    public function stats(Quiz $quiz, Request $request): JsonResponse
    {
        try {
            $startDate = $request->has('start_date') ? 
                \Carbon\Carbon::parse($request->start_date) : null;
            $endDate = $request->has('end_date') ? 
                \Carbon\Carbon::parse($request->end_date) : null;

            $stats = $this->quizService->getQuizStats($quiz, $startDate, $endDate);

            return response()->json([
                'success' => true,
                'data' => $stats,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to get quiz statistics',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Get quiz leaderboard.
     */
    public function leaderboard(Quiz $quiz, Request $request): JsonResponse
    {
        try {
            $limit = $request->get('limit', 10);
            $leaderboard = $this->quizService->getQuizLeaderboard($quiz, $limit);

            return response()->json([
                'success' => true,
                'data' => $leaderboard,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to get quiz leaderboard',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Create a new version of the quiz.
     */
    public function createVersion(Request $request, Quiz $quiz): JsonResponse
    {
        try {
            $newVersion = $this->quizService->createVersion($quiz, $request->all());

            return response()->json([
                'success' => true,
                'message' => 'Quiz version created successfully',
                'data' => $newVersion->load(['creator', 'questions']),
            ], 201);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to create quiz version',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Get quiz in specific language.
     */
    public function getInLanguage(Quiz $quiz, string $locale): JsonResponse
    {
        try {
            $quizData = $this->quizService->getQuizInLanguage($quiz, $locale);

            return response()->json([
                'success' => true,
                'data' => $quizData,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to get quiz in language',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Set quiz language translations.
     */
    public function setLanguage(Request $request, Quiz $quiz, string $locale): JsonResponse
    {
        try {
            $this->quizService->setQuizLanguage($quiz, $locale, $request->all());

            return response()->json([
                'success' => true,
                'message' => 'Quiz language translations updated successfully',
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to update quiz language translations',
                'error' => $e->getMessage(),
            ], 500);
        }
    }

    /**
     * Get available languages.
     */
    public function getLanguages(): JsonResponse
    {
        $languages = $this->quizService->getAvailableLanguages();

        return response()->json([
            'success' => true,
            'data' => $languages,
        ]);
    }

    /**
     * Get public quizzes.
     */
    public function public(Request $request): JsonResponse
    {
        $query = Quiz::published()->public();

        if ($request->has('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('title', 'like', "%{$search}%")
                  ->orWhere('description', 'like', "%{$search}%");
            });
        }

        $perPage = $request->get('per_page', 15);
        $quizzes = $query->with(['creator'])
                        ->orderBy('published_at', 'desc')
                        ->paginate($perPage);

        return response()->json([
            'success' => true,
            'data' => $quizzes,
        ]);
    }
}