<?php

namespace App\Http\Controllers\Api\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Subject;
use App\Models\Classes;
use App\Models\ClassesSubject;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\File;
use Exception;

class SubjectController extends Controller
{
    
    /**
     * Display All Subject related Class without Trashed.
     */
    public function indexSubjects()
    {
        try {
            $subjects = Subject::select('id','subject_name','image','is_active','deleted_at','short_description','long_description')->with('classes:id,class_name')->latest()->get();
            if ($subjects->isEmpty()) {
                return response()->json([
                    // 'validation_errors' => ['not_found' => ['No Data Found!.']],
                    'response_status' => 400
                ], 200);
            }
            $data = ['subjects' => $subjects];
            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 Subject related Class without Trashed.
     */
    public function index()
    {
        try {
            $subjects = Subject::select('id','subject_name','image','is_active','deleted_at','short_description','long_description')->with('classes:id,class_name')->where('is_active',1)->latest()->get();
            if ($subjects->isEmpty()) {
                return response()->json([
                    // 'validation_errors' => ['not_found' => ['No Data Found!.']],
                    'response_status' => 400
                ], 200);
            }
            $data = ['subjects' => $subjects];
            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 getOnlySubjects()
    {
        try {
            $subjects = Subject::select('id','subject_name')->latest()->get();
            if ($subjects->isEmpty()) {
                return response()->json([
                    // 'validation_errors' => ['not_found' => ['No Data Found!.']],
                    'response_status' => 400
                ], 200);
            }
            $data = ['subjects' => $subjects];
            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 Subject related Class with Trashed.
     */
    public function withTrashed()
    {
        try {
            $subjects = Subject::select('id','subject_name','image','is_active','deleted_at','short_description','long_description')->with('classes:id,class_name')->withTrashed()->latest()->get();
            if ($subjects->isEmpty()) {
                return response()->json([
                    // 'validation_errors' => ['not_found' => ['No Data Found!.']],
                    'response_status' => 400
                ], 200);
            }
            $data = ['subjects' => $subjects];
            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 Subject.
     */
    public function trash()
    {
        try {
            $subjects = Subject::select('id','subject_name','image','is_active','deleted_at','short_description','long_description')->with('classes:id,class_name')->onlyTrashed()->latest()->get();
            if ($subjects->isEmpty()) {
                return response()->json([
                    // 'validation_errors' => ['not_found' => ['No Data Found!']],
                    'response_status' => 400
                ], 200);
            }
            $data = ['subjects' => $subjects];
            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 Subject.
     */
    public function restore(string $id)
    {
        try {
            $subject = Subject::select('id','subject_name','image','is_active','deleted_at','short_description','long_description')->with('classes:id,class_name')->onlyTrashed()->find($id);
            if (!$subject) {
                return response()->json([
                    'validation_errors' => ['not_found' => ['No Data Found!']],
                    'response_status' => 400
                ], 200);
            }
            $subject->restore();
            $data = ['subject' => $subject];
            return response()->json([
                'data' => $data,
                'response_message' => ['success' => ['Subject Restored Successfully!']],
                'response_status' => 200
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        try {
            // Validate the request input
            $validation = Validator::make($request->all(), [
                'class_id' => 'required|string',
                'subject_name' => 'required|string|unique:subjects,subject_name',
                'short_description' => 'nullable|string',
                'long_description' => 'nullable|string',
                'image' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
            ]);

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

            // Create Image Process
            $filename = null;

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

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

            // Create the subject in the `subjects` table
            $subject = Subject::create([
                'subject_name' => $request->subject_name,
                'short_description' => $request->short_description,
                'long_description' => $request->long_description,
                'image' => $filename,
            ]);


            $classIds = explode(',', $request->class_id);

            $duplicateClasses = [];

            foreach ($classIds as $classId) {
                $classId = trim($classId);

                // Check if the subject_id and class_id already exist in `classes_subjects`
                $existingEntry = ClassesSubject::where('subject_id', $subject->id)
                    ->where('class_id', $classId)
                    ->first();

                if ($existingEntry) {
                    // Add to the list of duplicate classes to notify the user
                    $duplicateClasses[] = $classId;
                } else {
                    // Insert new record if the combination does not exist
                    ClassesSubject::create([
                        'subject_id' => $subject->id,
                        'class_id' => $classId,
                    ]);
                }
            }

            // Prepare response data
            $data = ['subject' => $subject];

            // Create a response message for duplicates, if any
            $responseMessage = ['success' => ['Subject Created Successfully!']];

            if (count($duplicateClasses) > 0) {
                $responseMessage['warning'] = ['Some classes were already associated with this subject and were not added again: ' . implode(', ', $duplicateClasses)];
            }

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

    /**
     * Display the specified subject with all Classes.
     */
    public function show($id)
    {
        try {
            $subject = Subject::select('id','subject_name','image','short_description','long_description')->with('classes:id,class_name')->find($id);
            if (!$subject) {
                return response()->json([
                    'validation_errors' => ['not_found' => ['No Data Found!']],
                    'response_status' => 400
                ], 200);
            }
            // $classes = Classes::all();
            $data = [
                'subject' => $subject,
                // 'classes' => $classes,
            ];

            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 Active Subject.
     */
    public function activeSubject(Request $request, string $id)
    {
        try {

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

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

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

            $data = ['subject' => $subject];
            return response()->json([
                'data' => $data,
                'response_message' => ['success' => ['Subject Status Updated Successfully!']],
                '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, string $id)
    {
        try {
            // Validate the request input
            $validation = Validator::make($request->all(), [
                'class_id' => 'required|string', // Accept comma-separated class IDs as a string
                'subject_name' => 'required|string|unique:subjects,subject_name,' . $id, // Ensure unique subject name excluding current ID
                'short_description' => 'nullable|string',
                'long_description' => 'nullable|string',
                'image' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
            ]);

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

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

            // Handle the image upload process
            $filename = $subject->image; // Keep the old image as default

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

                // Delete the old image if it exists
                if ($subject->image && file_exists($path . $subject->image)) {
                    unlink($path . $subject->image);
                }

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

            // Update the subject's details
            $subject->subject_name = $request->subject_name;
            $subject->short_description = $request->short_description;
            $subject->long_description = $request->long_description;
            $subject->image = $filename;
            $subject->save();

            // Update class associations
            $classIds = explode(',', $request->class_id);

            // Remove existing associations for the subject
            ClassesSubject::where('subject_id', $subject->id)->delete();

            // Insert new associations
            foreach ($classIds as $classId) {
                $classId = trim($classId);

                // Insert new record for each class ID
                ClassesSubject::create([
                    'subject_id' => $subject->id,
                    'class_id' => $classId,
                ]);
            }

            // Prepare response data
            $data = ['subject' => $subject];

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

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

            $subject->delete();
            $subject = Subject::select('id','subject_name','is_active','deleted_at','short_description','long_description')->onlyTrashed()->latest()->get();
            $data = ['subject' => $subject];
            return response()->json([
                'response_message' => ['success' => ['Subject has been sent to Trash!']],
                'response_status' => 200,
                'data' => $data
            ], 200);
        } catch (Exception $e) {
            return response()->json([
                'validation_errors' => $e->getMessage(),
                'response_status' => 400,
            ], 200);
        }
    }

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

            // Delete Image From Folder
            if ($subject->image && File::exists(public_path('uploads/subjects/' . $subject->image))) {
                File::delete(public_path('uploads/subjects/' . $subject->image));
            }

            $subject->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);
        }
    }
}
