<?php

namespace App\Http\Controllers\Api\Teacher;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\File;
use App\Models\Quiz;
use App\Models\QuizLink;
use App\Models\QuizStudent;
use App\Models\QuizUnit;
use App\Models\QuizTopic;
use App\Models\QuizTopicQuestion;
use App\Models\Topic;
use App\Models\TopicQuestion;
use App\Models\Unit;
use Exception;
use Illuminate\Support\Facades\Auth;


class QuizController extends Controller
{
    /**
     * Display All Quiz without Trashed.
     */
    public function index()
    {
        try {
            $teacherId = Auth::guard('sanctum')->user()->id;
            $quizzes = Quiz::with([
                'teacher',
                'classRelation',
                'subject',
                'links',
                'students' => function ($query) {
                    $query->with([
                        'student:id,first_name,last_name,upn,email'
                    ]);
                },
                'units' => function ($query) {
                    $query->with([
                        'unit:id,unit_name',
                        'topics' => function ($query) {
                            $query->with([
                                'topic:id,topic_name',
                                'questions' => function ($query) {
                                    $query->with([
                                        'question:id,question,type_id,difficulty_level_id',
                                        'question.questionParts' => function ($query) {
                                            $query->select('id', 'question_id', 'topic_id','questionPart','questionAnswer','questionMark');
                                        }
                                    ]);
                                }
                            ]);
                        }
                    ]);
                }
            ])->where('teacher_id', $teacherId)
                ->latest()
                ->get();

            if ($quizzes->isEmpty()) {
                return response()->json([
                    'response_status' => 400
                ], 200);
            }
            $data = ['quizzes' => $quizzes];
            return response()->json([
                'data' => $data,
                'response_status' => 200
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    // public function index()
    // {
    //     try {
    //         $teacherId = Auth::guard('sanctum')->user()->id;
    //         $currentDate = now()->format('Y-m-d');

    //         $quizzes = Quiz::with([
    //             'teacher',
    //             'classRelation',
    //             'subject',
    //             'links',
    //             'students' => function ($query) {
    //                 $query->with([
    //                     'student:id,first_name,last_name,upn,email'
    //                 ]);
    //             },
    //             'units' => function ($query) {
    //                 $query->with([
    //                     'unit:id,unit_name',
    //                     'topics' => function ($query) {
    //                         $query->with([
    //                             'topic:id,topic_name',
    //                             'questions' => function ($query) {
    //                                 $query->with([
    //                                     'question:id,question,type_id,difficulty_level_id',
    //                                 ]);
    //                             }
    //                         ]);
    //                     }
    //                 ]);
    //             }
    //             ])->where('teacher_id', $teacherId)
    //             ->latest()
    //             ->get();

    //         // Add `expire_status` directly to each quiz
    //         $quizzes->each(function ($quiz) use ($currentDate) {
    //             $quiz->expire_status = $quiz->end_date < $currentDate ? 'Expire' : 'Active';
    //         });

    //         if ($quizzes->isEmpty()) {
    //             return response()->json([
    //                 'response_status' => 400
    //             ], 200);
    //         }

    //         $data = ['quizzes' => $quizzes];
    //         return response()->json([
    //             'data' => $data,
    //             'response_status' => 200
    //         ], 200);
    //     } catch (Exception $e) {
    //         return response()->json([
    //             'validation_errors' => $e->getMessage(),
    //             'response_status' => 400,
    //         ], 200);
    //     }
    // }

    // public function index()
    // {
    //     try {
    //         $teacherId = Auth::guard('sanctum')->user()->id;
    //         $quizzes = Quiz::with([
    //             'teacher',
    //             'classRelation',
    //             'subject',
    //             'links',
    //             'students' => function ($query) {
    //                 $query->with(['student:id,first_name,last_name,upn,email']);
    //             },
    //             'units' => function ($query) {
    //                 $query->with([
    //                     'unit:id,unit_name',
    //                     'topics' => function ($query) {
    //                         $query->with([
    //                             'topic:id,topic_name',
    //                             'questions' => function ($query) {
    //                                 $query->with(['question:id,question,type_id,difficulty_level_id']);
    //                             }
    //                         ]);
    //                     }
    //                 ]);
    //             }
    //         ])
    //             ->where('teacher_id', $teacherId)
    //             ->latest()
    //             ->get()
    //             ->map(function ($quiz) {
    //                 // Calculate expire status based on end_date
    //                 $currentDate = now();
    //                 $endDate = \Carbon\Carbon::parse($quiz->end_date);
    //                 $quiz->expire_status = $endDate->lt($currentDate) ? 'Expired' : 'Active';
    //                 return $quiz;
    //             });

    //         if ($quizzes->isEmpty()) {
    //             return response()->json([
    //                 'response_status' => 400
    //             ], 200);
    //         }

    //         $data = ['quizzes' => $quizzes];
    //         return response()->json([
    //             'data' => $data,
    //             'response_status' => 200
    //         ], 200);
    //     } catch (Exception $e) {
    //         return response()->json([
    //             'validation_errors' => $e->getMessage(),
    //             'response_status' => 400,
    //         ], 200);
    //     }
    // }


    /**
     * Display All Quiz with Trashed.
     */
    public function withTrashed()
    {
        try {
            $quizzes = Quiz::with(['teacher', 'classRelation', 'subject', 'links', 'students', 'units.topics.questions'])->withTrashed()->latest()->get();
            if ($quizzes->isEmpty()) {
                return response()->json([
                    'response_status' => 400
                ], 200);
            }
            $data = ['quizzes' => $quizzes];
            return response()->json([
                'data' => $data,
                'response_status' => 200
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    /**
     * Display Only Trashed Quiz.
     */
    public function trash()
    {
        try {
            $quizzes = Quiz::with(['teacher', 'classRelation', 'subject', 'links', 'students', 'units.topics.questions'])->onlyTrashed()->latest()->get();
            if ($quizzes->isEmpty()) {
                return response()->json([
                    'response_status' => 400
                ], 200);
            }
            $data = ['quizzes' => $quizzes];
            return response()->json([
                'data' => $data,
                'response_status' => 200
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    /**
     * Display Restore Trashed Quiz.
     */
    public function restore(string $id)
    {
        try {
            $quiz = Quiz::with(['teacher', 'classRelation', 'subject', 'links', 'students', 'units.topics.questions'])->onlyTrashed()->find($id);
            if (!$quiz) {
                return response()->json([
                    'validation_errors' => ['not_found' => ['No Data Found!']],
                    'response_status' => 400
                ], 200);
            }
            $quiz->restore();
            $data = ['quiz' => $quiz];
            return response()->json([
                'data' => $data,
                'response_message' => ['success' => ['Quiz Restored Successfully!']],
                'response_status' => 200
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }


    /**
     * Store a newly created or update an existing quiz.
     */
    public function store(Request $request)
    {
        try {
            $validation = Validator::make($request->all(), [
                'teacherId' => 'required|exists:teachers,id',
                'teacher_class_id' => 'required|exists:teacher_classes,id',
                'selectedClass' => 'required|exists:classes,id',
                'selectedSection' => 'required|string',
                'selectedSubject' => 'required|exists:subjects,id',
                'quizName' => 'required|string',
                'questionOrder' => 'required|string',
                'messageForStudents' => 'nullable|string',
                'isPublish' => 'required|boolean',
                'startDate' => ['nullable', 'required_if:isPublish,1', 'date'],
                'endDate' => ['nullable', 'required_if:isPublish,1', 'date'],
                'links' => 'nullable|array',
                'selectedStudents' => 'nullable|array',
                'selectedUnitWithValue' => 'nullable|array',
                'selectedTopics' => 'nullable|array',
                'selectedQuestions' => 'nullable|array',
            ]);

            if ($validation->fails()) {
                return response()->json([
                    'validation_errors' => $validation->messages(),
                    'response_status' => 400,
                ], 200);
            }

            // Store the new Quiz
            $quiz = Quiz::create([
                'teacher_id' => $request->teacherId,
                'teacher_class_id' => $request->teacher_class_id,
                'class_id' => $request->selectedClass,
                'section' => $request->selectedSection,
                'subject_id' => $request->selectedSubject,
                'quiz_name' => $request->quizName,
                'quiz_question_order' => $request->questionOrder,
                'quiz_message' => $request->messageForStudents,
                'is_publish' => $request->isPublish,
                'start_date' => $request->startDate,
                'end_date' => $request->endDate,
            ]);

            // Insert related QuizLinks
            if (!empty($request->links) && is_array($request->links)) {
                foreach ($request->links as $link) {
                    // Check if the link is not an empty string or null
                    if (!empty($link) && filter_var($link, FILTER_VALIDATE_URL)) {
                        QuizLink::create([
                            'quiz_id' => $quiz->id,
                            'link' => $link,
                        ]);
                    }
                }
            }

            // Insert related QuizStudents
            if (!empty($request->selectedStudents) && is_array($request->selectedStudents)) {
                foreach ($request->selectedStudents as $student_id) {
                    QuizStudent::create([
                        'quiz_id' => $quiz->id,
                        'student_register_id' => $student_id,
                    ]);
                }
            }

            // Insert related QuizUnits, Topics, and Topic Questions
            if (!empty($request->selectedUnitWithValue) && is_array($request->selectedUnitWithValue)) {
                foreach ($request->selectedUnitWithValue as $unit) {
                    // Check if unit['value'] exists in the database and is valid
                    if (isset($unit['value'])) {
                        $unitExists = Unit::where('id', $unit['value'])->exists();
                        if ($unitExists) {
                            // Insert the QuizUnit
                            $quizUnit = QuizUnit::create([
                                'quiz_id' => $quiz->id,
                                'quiz_subject_id' => $request->selectedSubject,
                                'unit_id' => $unit['value'],
                            ]);

                            // Check if topics for this unit exist and are arrays
                            foreach ($request->selectedTopics as $topic) {
                                if ($topic['unit_id'] == $unit['value']) {
                                    $topicExists = Topic::where('id', $topic['topic_id'])
                                        ->where('unit_id', $unit['value'])
                                        ->exists();
                                    if ($topicExists) {
                                        $quizTopic = QuizTopic::create([
                                            'quiz_id' => $quiz->id,
                                            'quiz_unit_id' => $quizUnit->id,
                                            'topic_id' => $topic['topic_id'],
                                        ]);

                                        // Check if topic_questions exist for this topic
                                        foreach ($request->selectedQuestions as $question) {
                                            if ($question['topic_id'] == $topic['topic_id']) {
                                                $questionExists = TopicQuestion::where('id', $question['question_id'])
                                                    ->where('topic_id', $topic['topic_id'])
                                                    ->first();
                                                if ($questionExists) {
                                                    QuizTopicQuestion::create([
                                                        'quiz_id' => $quiz->id,
                                                        'quiz_topic_id' => $quizTopic->id,
                                                        'question_id' => $question['question_id'],
                                                        'marks' => $questionExists->marks ?? 0,
                                                    ]);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            
            // // ===== Calculate total marks & total time =====
            $totalMarks = QuizTopicQuestion::where('quiz_id', $quiz->id)->sum('marks');
            $totalMinutes = round(($totalMarks / 45) * 60);
            
            // Convert minutes to HH:MM:SS
            $hours = floor($totalMinutes / 60);
            $minutes = $totalMinutes % 60;
            $formattedTime = sprintf('%02d:%02d:00', $hours, $minutes);
            
            $quiz->update([
                'total_marks' => $totalMarks,
                'total_time' => $formattedTime, // e.g., "01:30:00"
            ]);

            // Fetch the full quiz data with related entities
            $quizData = Quiz::with([
                'teacher',
                'classRelation',
                'subject',
                'links',
                'students' => function ($query) {
                    $query->with([
                        'student:id,first_name,last_name,upn,email'
                    ]);
                },
                'units' => function ($query) {
                    $query->with([
                        'unit:id,unit_name', // Fetch only specific unit fields
                        'topics' => function ($query) {
                            $query->with([
                                'topic:id,topic_name', // Fetch only specific topic fields
                                'questions' => function ($query) {
                                    $query->with([
                                        'question:id,question,type_id,difficulty_level_id',
                                        'question.questionParts' => function ($query) {
                                            $query->select('id', 'question_id', 'topic_id','questionPart','questionAnswer','questionMark');
                                        }
                                    ]);
                                }
                            ]);
                        }
                    ]);
                }
            ])->find($quiz->id);

            return response()->json([
                'response_status' => 200,
                'response_message' => ['success' => ['Assessment Created Successfully!']],
                'data' => ['quiz' => $quizData]
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    /**
     * Update the Active Quiz.
     */
    public function activeQuiz(Request $request, string $id)
    {
        try {

            $validation = Validator::make($request->all(), [
                'id' => 'nullable|exists:quizzes,id',
            ]);

            if ($validation->fails()) {
                return response()->json([
                    'validation_errors' => $validation->messages(),
                    'response_status' => 400,
                ], 200);
            }

            // Find the quiz by ID
            $quiz = Quiz::select('id', 'is_active')->find($id);
            if (!$quiz) {
                return response()->json([
                    'validation_errors' => ['not_found' => ['No Data Found!']],
                    'response_status' => 400
                ], 200);
            }
            $quiz->is_active = !$quiz->is_active;
            $quiz->save();

            $data = ['quiz' => $quiz];
            return response()->json([
                'data' => $data,
                'response_message' => ['success' => ['Assessment Status Updated Successfully!']],
                'response_status' => 200
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    /**
     * Update the Publish Quiz.
     */
    public function publishQuiz(Request $request, string $id)
    {
        try {
            // Validate the request data
            $validation = Validator::make($request->all(), [
                'isPublish' => 'required|boolean',
                'startDate' => ['nullable', 'required_if:isPublish,1', 'date'],
                'endDate' => ['nullable', 'required_if:isPublish,1', 'date'],
            ]);

            if ($validation->fails()) {
                return response()->json([
                    'validation_errors' => $validation->messages(),
                    'response_status' => 400,
                ], 200);
            }

            // Find the quiz by ID
            $quiz = Quiz::find($id);
            if (!$quiz) {
                return response()->json([
                    'validation_errors' => ['not_found' => ['No Data Found!']],
                    'response_status' => 400,
                ], 200);
            }

            // Update the relevant fields
            $quiz->is_publish = $request->isPublish; // Update is_publish based on isPublish
            if ($request->isPublish) {
                // Set start_date and end_date if isPublish is true
                $quiz->start_date = $request->startDate;
                $quiz->end_date = $request->endDate;
            } else {
                // Clear the dates if not publishing
                $quiz->start_date = null;
                $quiz->end_date = null;
            }

            // Save the updated quiz
            $quiz->save();

            $data = ['quiz' => $quiz];
            return response()->json([
                'data' => $data,
                'response_message' => ['success' => ['Assessment Published Successfully!']],
                'response_status' => 200,
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    /**
     * Display the specified resource.
     */
    public function show($id)
    {
        try {
            $teacherId = Auth::guard('sanctum')->user()->id;
            $quiz = Quiz::with([
                'teacher',
                'classRelation',
                'subject',
                'links',
                'students' => function ($query) {
                    $query->with([
                        'student:id,first_name,last_name,upn,email'
                    ]);
                },
                'units' => function ($query) {
                    $query->with([
                        'unit:id,unit_name', // Fetch only specific unit fields
                        'topics' => function ($query) {
                            $query->with([
                                'topic:id,topic_name', // Fetch only specific topic fields
                                'questions' => function ($query) {
                                    $query->with([
                                        'question:id,question,type_id,difficulty_level_id',
                                        'question.questionParts' => function ($query) {
                                            $query->select('id', 'question_id', 'topic_id','questionPart','questionAnswer','questionMark');
                                        }
                                    ]);
                                }
                            ]);
                        }
                    ]);
                }
            ])->where('teacher_id', $teacherId)
                ->find($id);

            if (!$quiz) {
                return response()->json([
                    'validation_errors' => ['not_found' => ['No Data Found!']],
                    'response_status' => 400
                ], 200);
            }
            $data = ['quiz' => $quiz];
            return response()->json([
                'data' => $data,
                'response_status' => 200
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }


    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, $id)
    {
        try {
            $validation = Validator::make($request->all(), [
                'teacherId' => 'required|exists:teachers,id',
                'teacher_class_id' => 'required|exists:teacher_classes,id',
                'selectedClass' => 'required|exists:classes,id',
                'selectedSection' => 'required|string',
                'selectedSubject' => 'required|exists:subjects,id',
                'quizName' => 'required|string',
                'questionOrder' => 'required|string',
                'messageForStudents' => 'nullable|string',
                'isPublish' => 'required|boolean',
                'startDate' => ['nullable'],
                'endDate' => ['nullable'],
                'links' => 'nullable|array',
                'selectedStudents' => 'nullable|array',
                'selectedUnitWithValue' => 'nullable|array',
                'selectedTopics' => 'nullable|array',
                'selectedQuestions' => 'nullable|array',
            ]);

            if ($validation->fails()) {
                return response()->json([
                    'validation_errors' => $validation->messages(),
                    'response_status' => 400,
                ], 200);
            }

            // Find the quiz by ID and update
            $quiz = Quiz::findOrFail($id);
            $quiz->update([
                'teacher_id' => $request->teacherId,
                'teacher_class_id' => $request->teacher_class_id,
                'class_id' => $request->selectedClass,
                'section' => $request->selectedSection,
                'subject_id' => $request->selectedSubject,
                'quiz_name' => $request->quizName,
                'quiz_question_order' => $request->questionOrder,
                'quiz_message' => $request->messageForStudents,
                'is_publish' => $request->isPublish,
                'start_date' => $request->startDate,
                'end_date' => $request->endDate,
            ]);

            // Update related QuizLinks
            QuizLink::where('quiz_id', $quiz->id)->forceDelete(); // Remove old links
            if (!empty($request->links) && is_array($request->links)) {
                foreach ($request->links as $link) {
                    if (!empty($link) && filter_var($link, FILTER_VALIDATE_URL)) {
                        QuizLink::create([
                            'quiz_id' => $quiz->id,
                            'link' => $link,
                        ]);
                    }
                }
            }

            // Update related QuizStudents
            QuizStudent::where('quiz_id', $quiz->id)->forceDelete(); // Remove old students
            if (!empty($request->selectedStudents) && is_array($request->selectedStudents)) {
                foreach ($request->selectedStudents as $student_id) {
                    QuizStudent::create([
                        'quiz_id' => $quiz->id,
                        'student_register_id' => $student_id,
                    ]);
                }
            }

            // Update related QuizUnits, Topics, and Topic Questions
            QuizUnit::where('quiz_id', $quiz->id)->forceDelete(); // Remove old units, topics, questions
            if (!empty($request->selectedUnitWithValue) && is_array($request->selectedUnitWithValue)) {
                foreach ($request->selectedUnitWithValue as $unit) {
                    if (isset($unit['value'])) {
                        $unitExists = Unit::where('id', $unit['value'])->exists();
                        if ($unitExists) {
                            $quizUnit = QuizUnit::create([
                                'quiz_id' => $quiz->id,
                                'quiz_subject_id' => $request->selectedSubject,
                                'unit_id' => $unit['value'],
                            ]);

                            foreach ($request->selectedTopics as $topic) {
                                if ($topic['unit_id'] == $unit['value']) {
                                    $topicExists = Topic::where('id', $topic['topic_id'])
                                        ->where('unit_id', $unit['value'])
                                        ->exists();
                                    if ($topicExists) {
                                        $quizTopic = QuizTopic::create([
                                            'quiz_id' => $quiz->id,
                                            'quiz_unit_id' => $quizUnit->id,
                                            'topic_id' => $topic['topic_id'],
                                        ]);

                                        foreach ($request->selectedQuestions as $question) {
                                            if ($question['topic_id'] == $topic['topic_id']) {
                                                $questionExists = TopicQuestion::where('id', $question['question_id'])
                                                    ->where('topic_id', $topic['topic_id'])
                                                    ->first();
                                                if ($questionExists) {
                                                    QuizTopicQuestion::create([
                                                        'quiz_id' => $quiz->id,
                                                        'quiz_topic_id' => $quizTopic->id,
                                                        'question_id' => $question['question_id'],
                                                        'marks' => $questionExists->marks ?? 0,
                                                    ]);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            
            $totalMarks = QuizTopicQuestion::where('quiz_id', $quiz->id)->sum('marks');
            $totalMinutes = round(($totalMarks / 45) * 60);
            $hours = floor($totalMinutes / 60);
            $minutes = $totalMinutes % 60;
            $formattedTime = sprintf('%02d:%02d:00', $hours, $minutes);
            
            $quiz->update([
                'total_marks' => $totalMarks,
                'total_time' => $formattedTime,
            ]);

            // Fetch the updated quiz data with related entities
            $quizData = Quiz::with([
                'teacher',
                'classRelation',
                'subject',
                'links',
                'students' => function ($query) {
                    $query->with([
                        'student:id,first_name,last_name,upn,email'
                    ]);
                },
                'units' => function ($query) {
                    $query->with([
                        'unit:id,unit_name', // Fetch only specific unit fields
                        'topics' => function ($query) {
                            $query->with([
                                'topic:id,topic_name', // Fetch only specific topic fields
                                'questions' => function ($query) {
                                    $query->with([
                                        'question:id,question,type_id,difficulty_level_id',
                                        'question.questionParts' => function ($query) {
                                            $query->select('id', 'question_id', 'topic_id','questionPart','questionAnswer','questionMark');
                                        }
                                    ]);
                                }
                            ]);
                        }
                    ]);
                }
            ])->find($quiz->id);

            return response()->json([
                'response_status' => 200,
                'response_message' => ['success' => ['Assessment Updated Successfully!']],
                'data' => ['quiz' => $quizData]
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    /**
     * Remove from storage.
     */
    public function destroy(string $id)
    {
        try {
            $quiz = Quiz::find($id);
            if (!$quiz) {
                return response()->json([
                    // 'validation_errors' => ['not_found' => ['No Data Found!']],
                    'response_status' => 400
                ], 200);
            }

            $quiz->forceDelete();
            return response()->json([
                'response_message' => ['success' => ['Assessment Deleted Successfully!']],
                'response_status' => 200,
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }
}
