<?php

namespace App\Http\Controllers\Api\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Classes;
use App\Models\Subject;
use App\Models\Unit;
use App\Models\Topic;
use App\Models\TopicQuestionType;
use App\Models\TopicQuestionOption;
use App\Models\TopicQuestionImage;
use App\Models\TopicQuestionComment;
use App\Models\TopicQuestionAnswer;
use App\Models\TopicQuestion;
use App\Models\TopicQuestionPart;
use Illuminate\Support\Facades\Validator;
use Exception;

class TopicQuestionController extends Controller
{
    /**
     * Display All Questions of Topic
     */
    public function indexQuestions()
    {
        try {
            $questions = TopicQuestion::select('id', 'class_id', 'subject_id', 'unit_id', 'topic_id', 'question', 'marks', 'difficulty_level_id', 'type_id')
            ->with('classRelation:id,class_name', 'subject:id,subject_name', 'unit:id,unit_name', 'topic:id,topic_name', 'type:id,type', 'level:id,level', 'options:id,question_id,option,is_correct', 'image:id,question_id,image', 'comment:id,question_id,comment', 'answer:id,question_id,answer', 'questionParts:id,question_id,questionPart,questionMark,questionAnswer')
            ->latest()
            ->get();
            if ($questions->isEmpty()) {
                return response()->json([
                    // 'validation_errors' => ['not_found' => ['No Data Found!.']],
                    'response_status' => 400
                ], 200);
            }
            $data = ['topicQuestions' => $questions];
            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 Active Questions of Topic
     */
    public function index()
    {
        try {
            $questions = TopicQuestion::select('id', 'class_id', 'subject_id', 'unit_id', 'topic_id', 'question', 'marks', 'difficulty_level_id', 'type_id')->with('classRelation:id,class_name', 'subject:id,subject_name', 'unit:id,unit_name', 'topic:id,topic_name', 'type:id,type', 'level:id,level', 'options:id,question_id,option,is_correct', 'image:id,question_id,image', 'comment:id,question_id,comment', 'answer:id,question_id,answer', 'questionParts:id,question_id,questionPart,questionMark,questionAnswer')->latest()->get();
            if ($questions->isEmpty()) {
                return response()->json([
                    // 'validation_errors' => ['not_found' => ['No Data Found!.']],
                    'response_status' => 400
                ], 200);
            }
            $data = ['topicQuestions' => $questions];
            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 Quesetion with Trashed.
     */
    public function withTrashed()
    {
        try {
            $questions = TopicQuestion::select('id', 'class_id', 'subject_id', 'unit_id', 'topic_id', 'question', 'marks')->with('classRelation:id,class_name', 'subject:id,subject_name', 'unit:id,unit_name', 'topic:id,topic_name', 'image:id,question_id,image')->withTrashed()->latest()->get();
            if ($questions->isEmpty()) {
                return response()->json([
                    // 'validation_errors' => ['not_found' => ['No Data Found!.']],
                    'response_status' => 400
                ], 200);
            }
            $data = ['topicQuestions' => $questions];
            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 Questions.
     */
    public function trash()
    {
        try {
            $questions = TopicQuestion::select('id', 'class_id', 'subject_id', 'unit_id', 'topic_id', 'question', 'marks')->with('classRelation:id,class_name', 'subject:id,subject_name', 'unit:id,unit_name', 'topic:id,topic_name', 'image:id,question_id,image')->onlyTrashed()->latest()->get();
            if ($questions->isEmpty()) {
                return response()->json([
                    // 'validation_errors' => ['not_found' => ['No Data Found!.']],
                    'response_status' => 400
                ], 200);
            }
            $data = ['topicQuestions' => $questions];
            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 Questions.
     */
    public function restore(string $id)
    {
        try {
            $questions = TopicQuestion::select('id', 'class_id', 'subject_id', 'unit_id', 'topic_id', 'question', 'marks')->with('classRelation:id,class_name', 'subject:id,subject_name', 'unit:id,unit_name', 'topic:id,topic_name', 'image:id,question_id,image')->onlyTrashed()->find($id);
            if (!$questions) {
                return response()->json([
                    'validation_errors' => ['not_found' => ['No Data Found!.']],
                    'response_status' => 400
                ], 200);
            }
            $questions->restore();
            $data = ['topicQuestion' => $questions];
            return response()->json([
                'data' => $data,
                'response_message' => ['success' => ['Question Restored Successfully!']],
                'response_status' => 200
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    /**
     * Create Question of Topic
     */
    public function store(Request $request)
    {
        // dd($request->all());
        try {
            $validation = Validator::make($request->all(), [
                'class_id' => 'required|exists:classes,id,deleted_at,NULL|exists:units,class_id,deleted_at,NULL|exists:topics,class_id,deleted_at,NULL',
                'subject_id' => 'required|exists:subjects,id,deleted_at,NULL|exists:units,subject_id,deleted_at,NULL|exists:topics,subject_id,deleted_at,NULL',
                'unit_id' => 'required|exists:units,id,deleted_at,NULL|exists:topics,unit_id,deleted_at,NULL',
                'topic_id' => 'required|exists:topics,id',
                'type_id' => 'required|exists:topic_question_types,id',
                'difficulty_level_id' => 'required|exists:difficulty_levels,id',
                'question' => 'required|string',
                'marks' => 'required|string',
                'options' => 'nullable|string',
                'is_correct' => 'nullable|string',
                'image' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,webp|max:2048',
                'comment' => 'nullable|string',
                'answer' => 'nullable|string',
                'multipart_question' => 'nullable|in:1',
                'questionPart' => 'required_if:multipart_question,1|array',
                'questionPart.*' => 'required_if:multipart_question,1|string',
                'questionMark' => 'required_if:multipart_question,1|array',
                'questionMark.*' => 'required_if:multipart_question,1|string',
                'questionAnswer' => 'required_if:multipart_question,1|array',
                'questionAnswer.*' => 'required_if:multipart_question,1|string',
            ]);

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

            // dd($request->all());

            // Check type_id and replace {} with ___
            $questionText = $request->question;
            if ($request->type_id == 2) {
                $questionText = str_replace('{}', '___', $questionText);
            }

            $question = TopicQuestion::create([
                'class_id' => $request->class_id,
                'subject_id' => $request->subject_id,
                'unit_id' => $request->unit_id,
                'topic_id' => $request->topic_id,
                'type_id' => $request->type_id,
                'difficulty_level_id' => $request->difficulty_level_id,
                'question' => $questionText,
                'marks' => $request->marks,
            ]);

            $insertedData = ['topicQuestion' => $question];

            // Handle options and is_correct
            if ($request->type_id == 1) {
                // Convert comma-separated strings to arrays
                $options = is_string($request->options) ? explode(',', $request->options) : $request->options;
                $is_correct = is_string($request->is_correct) ? explode(',', $request->is_correct) : $request->is_correct;

                // Filter empty options and match the correct values
                $filteredOptions = array_filter($options, function ($value) {
                    return !empty($value) || $value === '0'; // Retain non-empty and '0' values
                });

                // Ensure the is_correct array matches the number of valid options
                $filteredIsCorrect = array_slice($is_correct, 0, count($filteredOptions));

                if (!empty($filteredOptions) && !empty($filteredIsCorrect) && is_array($filteredOptions) && is_array($filteredIsCorrect)) {
                    $optionsData = [];
                    foreach ($filteredOptions as $index => $option) {
                        if (isset($filteredIsCorrect[$index])) {
                            $optionEntry = TopicQuestionOption::create([
                                'topic_id' => $request->topic_id,
                                'question_id' => $question->id,
                                'option' => $option,
                                'is_correct' => $filteredIsCorrect[$index], // Ensure correct boolean conversion
                            ]);
                            $optionsData[] = $optionEntry;
                        }
                    }
                    $insertedData['options'] = $optionsData;
                }
                // Delete existing answers for the given question
                // TopicQuestionAnswer::where('question_id', $question->id)->delete();
            } else {
                // Handle answer
                if (!empty($request->answer)) {
                    $answerEntry = TopicQuestionAnswer::create([
                        'topic_id' => $request->topic_id,
                        'question_id' => $question->id,
                        'answer' => $request->answer,
                    ]);
                    $insertedData['answer'] = $answerEntry;
                }
            }

            // Handle image
            if (!empty($request->image)) {

                // Create Image Process
                $filename = '';

                // Handle image
                if ($request->hasFile('image')) {
                    $file = $request->file('image');
                    $extension = $file->getClientOriginalExtension();
                    $filename = time() . '.' . $extension;
                    $path = public_path('uploads/questions/');

                    // Move the new image to the path
                    $file->move($path, $filename);

                    $imageEntry = TopicQuestionImage::create([
                        'topic_id' => $request->topic_id,
                        'question_id' => $question->id,
                        'image' => $filename,
                    ]);
                    $insertedData['image'] = $imageEntry;
                }
            }

            // Handle comment
            if (!empty($request->comment)) {
                $commentEntry = TopicQuestionComment::create([
                    'topic_id' => $request->topic_id,
                    'question_id' => $question->id,
                    'comment' => $request->comment,
                ]);
                $insertedData['comment'] = $commentEntry;
            }

            // Handle multipart question parts
            if ($request->multipart_question == 1) {
                $questionParts = $request->input('questionPart', []);
                $questionMarks = $request->input('questionMark', []);
                $questionAnswers = $request->input('questionAnswer', []);

                $questionPartsData = [];

                foreach ($questionParts as $index => $part) {
                    if (!empty($part) || $part === '0') {
                        $mark = isset($questionMarks[$index]) ? $questionMarks[$index] : 0;
                        $answer = isset($questionAnswers[$index]) ? $questionAnswers[$index] : null;

                        $questionPartEntry = TopicQuestionPart::create([
                            'topic_id' => $request->topic_id,
                            'question_id' => $question->id,
                            'questionPart' => $part,
                            'questionMark' => $mark,
                            'questionAnswer' => $answer,
                        ]);

                        $questionPartsData[] = $questionPartEntry;
                    }
                }

                $insertedData['question_parts'] = $questionPartsData;
            }

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

    /**
     * Display Single Types of Topic Question
     */
    public function show($id)
    {
        try {
            $topicQuestion = TopicQuestion::select('id', 'class_id', 'subject_id', 'unit_id', 'topic_id', 'question', 'marks', 'difficulty_level_id', 'type_id')->with('classRelation:id,class_name', 'subject:id,subject_name', 'unit:id,unit_name', 'topic:id,topic_name', 'type:id,type', 'level:id,level', 'options:id,question_id,option,is_correct', 'image:id,question_id,image', 'comment:id,question_id,comment', 'answer:id,question_id,answer', 'questionParts:id,question_id,questionPart,questionMark,questionAnswer')->find($id);
            if (!$topicQuestion) {
                return response()->json([
                    'validation_errors' => ['not_found' => ['No Data Found!']],
                    'response_status' => 400
                ], 200);
            }
            $data = ['topicQuestion' => $topicQuestion];
            return response()->json([
                'data' => $data,
                'response_status' => 200
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    /**
     * Update Types of Topic Question.
     */
    public function update(Request $request, string $id)
    {
        // dd($request->image);
        try {
            $validation = Validator::make($request->all(), [
                'class_id' => 'required|exists:classes,id,deleted_at,NULL|exists:units,class_id,deleted_at,NULL|exists:topics,class_id,deleted_at,NULL',
                'subject_id' => 'required|exists:subjects,id,deleted_at,NULL|exists:units,subject_id,deleted_at,NULL|exists:topics,subject_id,deleted_at,NULL',
                'unit_id' => 'required|exists:units,id,deleted_at,NULL|exists:topics,unit_id,deleted_at,NULL',
                'topic_id' => 'required|exists:topics,id',
                'type_id' => 'required|exists:topic_question_types,id',
                'difficulty_level_id' => 'required|exists:difficulty_levels,id',
                'question' => 'required|string',
                'marks' => 'required|string',
                'options' => 'nullable|string',
                'is_correct' => 'nullable|string',
                'image' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg,webp|max:2048',
                'comment' => 'nullable|string',
                'answer' => 'nullable|string',
                'multipart_question' => 'nullable|in:1',
                'questionPart' => 'required_if:multipart_question,1|array',
                'questionPart.*' => 'required_if:multipart_question,1|string',
                'questionMark' => 'required_if:multipart_question,1|array',
                'questionMark.*' => 'required_if:multipart_question,1|string',
                'questionAnswer' => 'required_if:multipart_question,1|array',
                'questionAnswer.*' => 'required_if:multipart_question,1|string',
            ]);

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

            $topicQuestion = TopicQuestion::find($id);
            if (!$topicQuestion) {
                return response()->json([
                    'validation_errors' => ['not_found' => ['No Data Found!']],
                    'response_status' => 400
                ], 200);
            }


            // dd($request->all());

            // Convert options and is_correct from string to array if necessary
            // if (is_string($request->options)) {
            //     $request->merge(['options' => explode(',', $request->options)]);
            // }
            // if (is_string($request->is_correct)) {
            //     $request->merge(['is_correct' => explode(',', $request->is_correct)]);
            // }

            // Check if the image needs to be removed
            // $existingImage = TopicQuestionImage::where('question_id', $topicQuestion->id)->first();
            // if (empty($request->image) && $existingImage) {
            //     // Delete the old image file
            //     $imagePath = public_path('uploads/questions/' . $existingImage->image);
            //     if (file_exists($imagePath)) {
            //         unlink($imagePath);
            //     }
            //     $existingImage->delete();
            // }

            // Check type_id and replace {} with ___
            $questionText = $request->question;
            if ($request->type_id == 2) {
                $questionText = str_replace('{}', '___', $questionText);
            }

            $topicQuestion->class_id = $request->class_id;
            $topicQuestion->subject_id = $request->subject_id;
            $topicQuestion->unit_id = $request->unit_id;
            $topicQuestion->topic_id = $request->topic_id;
            $topicQuestion->type_id = $request->type_id;
            $topicQuestion->difficulty_level_id = $request->difficulty_level_id;
            $topicQuestion->question = $questionText;
            $topicQuestion->marks = $request->marks;
            $topicQuestion->save();

            $insertedData = ['topicQuestion' => $topicQuestion];

            // Handle options and is_correct
            // Check if type_id is 1 to handle deletion and re-insertion
            if ($request->type_id == 1) {

                if (is_string($request->options)) {
                    // Convert the string into an array, splitting by commas
                    $optionsArray = explode(',', $request->options);

                    // Filter out any empty values from the array
                    $filteredOptions = array_filter($optionsArray, function ($value) {
                        return !empty($value) || $value === '0'; // Ensure that non-empty and '0' values are kept
                    });

                    // Merge the filtered options back into the request
                    $request->merge(['options' => $filteredOptions]);
                }
                // Handling is_correct
                if (is_string($request->is_correct)) {
                    $isCorrectArray = explode(',', $request->is_correct);

                    // Get the filtered options count
                    $optionsCount = count($filteredOptions);

                    // Filter is_correct based on the number of valid options
                    $filteredIsCorrect = array_slice($isCorrectArray, 0, $optionsCount);

                    // Ensure the is_correct array length matches the options length
                    $request->merge(['is_correct' => $filteredIsCorrect]);
                }

                // Delete existing options and is_correct for the given question
                TopicQuestionOption::where('question_id', $topicQuestion->id)->delete();

                // Insert new options and is_correct
                if (!empty($request->options) && !empty($request->is_correct) && is_array($request->options) && is_array($request->is_correct)) {
                    $optionsData = [];
                    foreach ($request->options as $index => $option) {
                        if (isset($request->is_correct[$index])) {
                            $optionEntry = TopicQuestionOption::create([
                                'topic_id' => $request->topic_id,
                                'question_id' => $topicQuestion->id,
                                'option' => $option,
                                'is_correct' => $request->is_correct[$index],
                            ]);
                            $optionsData[] = $optionEntry;
                        }
                    }
                    $insertedData['options'] = $optionsData;
                }

                // Delete existing answers for the given question
                TopicQuestionAnswer::where('question_id', $topicQuestion->id)->delete();
            } else {
                // Delete existing options and is_correct for the given question
                TopicQuestionOption::where('question_id', $topicQuestion->id)->delete();

                // Handle answer
                if (!empty($request->answer)) {
                    $answerEntry = TopicQuestionAnswer::updateOrCreate(
                        ['question_id' => $topicQuestion->id],
                        ['topic_id' => $request->topic_id, 'answer' => $request->answer]
                    );
                    $insertedData['answer'] = $answerEntry;
                }
            }

            // Handle image
            $existingImage = TopicQuestionImage::where('question_id', $topicQuestion->id)->first();
            if ($request->hasFile('image')) {
                // Delete existing image if new image is uploaded
                if ($existingImage) {
                    $imagePath = public_path('uploads/questions/' . $existingImage->image);
                    if (file_exists($imagePath)) {
                        unlink($imagePath);
                    }
                    $existingImage->delete();
                }

                $file = $request->file('image');
                $extension = $file->getClientOriginalExtension();
                $filename = time() . '.' . $extension;
                $path = public_path('uploads/questions/');
                $file->move($path, $filename);

                $imageEntry = TopicQuestionImage::updateOrCreate(
                    ['question_id' => $topicQuestion->id],
                    ['topic_id' => $request->topic_id, 'image' => $filename]
                );
                $insertedData['image'] = $imageEntry;
            } elseif ($existingImage) {
                // If no new image is uploaded but an existing image exists
                $insertedData['image'] = $existingImage;
            }

            // Handle comment
            if (!empty($request->comment)) {
                $commentEntry = TopicQuestionComment::updateOrCreate(
                    ['question_id' => $topicQuestion->id],
                    ['topic_id' => $request->topic_id, 'comment' => $request->comment]
                );
                $insertedData['comment'] = $commentEntry;
            }

            // Handle multipart question parts
            if ($request->multipart_question == 1) {

                TopicQuestionPart::where('question_id', $topicQuestion->id)->delete();

                $questionParts = $request->input('questionPart', []);
                $questionMarks = $request->input('questionMark', []);
                $questionAnswers = $request->input('questionAnswer', []);

                $questionPartsData = [];

                foreach ($questionParts as $index => $part) {
                    if (!empty($part) || $part === '0') {
                        $mark = isset($questionMarks[$index]) ? $questionMarks[$index] : 0;
                        $answer = isset($questionAnswers[$index]) ? $questionAnswers[$index] : null;

                        $questionPartEntry = TopicQuestionPart::create([
                            'topic_id' => $request->topic_id,
                            'question_id' => $topicQuestion->id,
                            'questionPart' => $part,
                            'questionMark' => $mark,
                            'questionAnswer' => $answer,
                        ]);

                        $questionPartsData[] = $questionPartEntry;
                    }
                }

                $insertedData['question_parts'] = $questionPartsData;
                TopicQuestionAnswer::where('question_id', $topicQuestion->id)->delete();
            } else {
                TopicQuestionPart::where('question_id', $topicQuestion->id)->delete();
            }


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

    /**
     * Temporary Remove Topic Question.
     */
    public function delete(string $id)
    {
        try {
            $topicQuestion = TopicQuestion::find($id);
            if (!$topicQuestion) {
                return response()->json([
                    'validation_errors' => ['not_found' => ['No Data Found!']],
                    'response_status' => 400
                ], 200);
            }

            $topicQuestion->delete();

            return response()->json([
                'response_message' => ['success' => ['Question has been sent to Trash!']],
                'response_status' => 200
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    /**
     * Permanantly Remove Types of Topic Question.
     */
    public function destroy(string $id)
    {
        try {
            $topicQuestion = TopicQuestion::onlyTrashed()->find($id);
            if (!$topicQuestion) {
                return response()->json([
                    'validation_errors' => ['not_found' => ['No Data Found!']],
                    'response_status' => 400
                ], 200);
            }

            // Delete the image associated with the topic question
            $existingImage = TopicQuestionImage::where('question_id', $topicQuestion->id)->first();
            if ($existingImage) {
                $imagePath = public_path('uploads/questions/' . $existingImage->image);
                if (file_exists($imagePath)) {
                    unlink($imagePath);
                }
                $existingImage->delete();
            }

            // Delete the topic question itself
            $topicQuestion->forceDelete();

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