<?php

namespace App\Http\Controllers\Result;

use App\Models\Result\Exam;
use App\Models\Result\Grade;
use Illuminate\Http\Request;
use App\Models\Result\MarkHead;
use App\Models\Result\ExamPublish;
use App\Jobs\ProcessExamResultJob;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\Controller;
use App\Models\Academic\AcademicYear;

class ExamSetupController extends Controller
{
    
    public function index()
    {
        $grades = Grade::orderBy('mark_from', 'desc')->get();
        $marks = MarkHead::all();
        $academic_year = '';
        $academicYears = AcademicYear::pluck('year', 'id');
        $exams = Exam::with('academic_year')->orderBy('id','desc')->get();
        $published_exam = ExamPublish::with(['exam', 'academic_year'])->where('is_published', 1)->orderBy('id', 'desc')->get();
        $exam_id = '';
        return view('pages.result.exam_setup.index', compact('grades','marks', 'exams', 'academicYears', 'academic_year','published_exam','exam_id'));
    }

    public function grade_store(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:50',
            'gpa' => 'required|string|max:50',
            'mark_from' => 'required|integer|max:100',
            'mark_to' => 'required|integer|max:100',
            'remark' => 'max:100',
        ]);
        $grade = new Grade();
        $grade->name = $request->name;
        $grade->gpa = $request->gpa;
        $grade->mark_from = $request->mark_from;
        $grade->mark_to = $request->mark_to;
        $grade->remark = $request->remark;
        $grade->save();
        return redirect()->back()->with('success','Grade Point created successfully.');
    }
     
    public function  grade_update(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:50',
            'gpa' => 'required|string|max:50',
            'mark_from' => 'required|integer|max:100',
            'mark_to' => 'required|integer|max:100',
            'remark' => 'max:100',
        ]);
        $grade = Grade::findOrFail($request->id);
        $grade->name = $request->name;
        $grade->gpa = $request->gpa;
        $grade->mark_from = $request->mark_from;
        $grade->mark_to = $request->mark_to;
        $grade->remark = $request->remark;
        $grade->save();
        return redirect()->back()
                         ->with('success','Grade Point updated successfully.');
    }

    public function  grade_destroy(Grade $grade)
    {
        $grade->delete();
        return redirect()->back()->with('success','Grade Point deleted successfully.');
    }

    public function exam_store(Request $request)
    {
        $validatedData = $request->validate([
            'exam_name' => 'required',
            'year' => 'required|numeric',
            'exam_start_date' => 'required|date',
            'exam_end_date' => 'required|date',
            'is_published' => 'required|boolean',
        ]);
        $exam = Exam::create([
            'exam_name' => $validatedData['exam_name'],
            'year' => $validatedData['year'],
            'exam_start_date' => $validatedData['exam_start_date'],
            'exam_end_date' => $validatedData['exam_end_date'],
            'is_published' => $validatedData['is_published'],
        ]);
        if ($validatedData['is_published']) {
            //update all exam as not current exam
            Exam::where('id', '!=', $exam->id)->update(['is_published' => false]);
        }
        return redirect()->back()->with('success', 'Exam created successfully');
    }

    public function exam_update(Request $request)
    {
        $request->validate([
            'id' => 'required',
            'exam_name' => 'required',
            'year' => 'required|numeric',
            'exam_start_date' => 'required|date',
            'exam_end_date' => 'required|date',
            'is_published' => 'required|boolean',
        ]);

        $exam = Exam::findOrFail($request->id);
        $exam->exam_name = $request->exam_name;
        $exam->year = $request->year;
        $exam->exam_start_date = store_date_format($request->exam_start_date);
        $exam->exam_end_date = store_date_format($request->exam_end_date);
        $exam->is_published = $request->is_published;
        $exam->save();
        if ($request->is_published) {
            Exam::where('id', '!=', $exam->id)->update(['is_published' => false]);
        }
        return redirect()->back()->with('success', 'Exam updated successfully');
    }

    public function exam_destroy(Exam $exam)
    {
        if (
            $exam->examPublishes()->exists() ||
            $exam->examRecords()->exists() ||
            $exam->examRoutines()->exists() ||
            $exam->markHeadAssigns()->exists() ||
            $exam->lessons()->exists()
        ) {
            return redirect()->back()->with('error', 'Cannot delete this exam. It is linked to other records.');
        }
        $exam->delete();
        return redirect()->back()->with('success', 'Exam deleted successfully');
    }

    public function mark_head_store(Request $request)
    {
        $request->validate([
            'head_name' => 'required|string|max:250',
            'short_name' => 'required|string|max:250',
        ]);
        $mark = new MarkHead();
        $mark->head_name = $request->head_name;
        $mark->short_name = $request->short_name;
        $mark->save();
        return redirect()->back()
            ->with('success', 'Mark Head created successfully.');
    }

    public function mark_head_update(Request $request)
    {
        $request->validate([
            'head_name' => 'required|string|max:250',
            'short_name' => 'required|string|max:250',
        ]);
        $mark = MarkHead::findOrFail($request->id);
        $mark->head_name = $request->head_name;
        $mark->short_name = $request->short_name;
        $mark->save();
        return redirect()->back()
            ->with('success', 'Mark Head updated successfully.');
    }

    public function mark_head_destroy(MarkHead $mark)
    {
        $markHeadId = $mark->id;
        $records = DB::select("SELECT * FROM exam_records WHERE mark_head_id LIKE ?", ['%[' . $markHeadId . ']%']);
        $mark_head_assigns = DB::select("SELECT * FROM mark_head_assigns WHERE head_marks LIKE ?", ['%"' . $markHeadId . '":%']);

        if (!empty($records) || !empty($mark_head_assigns)) {
            return back()->with('error', 'Cannot delete. This Mark Head is used in exam records or assigned in mark_head_assigns.');
        }
        $mark->delete();
        return redirect()->back()->with('success', 'Mark Head deleted successfully.');
    }

    public function storePublish(Request $request)
    {
        // Validate input
        $validatedData = $request->validate([
            'publish_date' => 'required',
            'exam_id' => 'required',
        ]);

        $exam_id = $validatedData['exam_id'];

        $exam = Exam::find($exam_id);
        if (!$exam) {
            return redirect()->back()->with('error', 'Invalid Exam ID.');
        }
        $academic_year = $exam->year;

        $branch_id = auth()->user()->branch_id;

        try {
            // Check if the exam is already published
            $check_publish_exam = ExamPublish::where('exam_id', $exam_id)
                ->where('branch_id', $branch_id)
                ->where('academic_year_id', $academic_year)
                ->where('is_published', 1)->exists();

            if ($check_publish_exam) {
                return redirect()->back()->with('success', 'Exam already published.');
            }

            // Create exam to published
            ExamPublish::create([
                'branch_id' => $branch_id,
                'exam_id' => $exam_id,
                'academic_year_id' => $academic_year,
                'publish_date' => store_date_format($validatedData['publish_date']),
                'is_published' => 1,
            ]);

            if ($request->has('publish_and_send_sms')) {
                // Dispatch job to process SMS sending in the background
                ProcessExamResultJob::dispatch($exam_id, $academic_year, $branch_id);

                return redirect()->back()
                    ->with('success', 'Exam published successfully. SMS sending has been queued and will be processed in the background.');
            }

            return redirect()->back()
                ->with('success', 'Exam successfully published.');
        } catch (\Exception $e) {
            Log::error('Failed to publish exam: ' . $e->getMessage());
            return redirect()->back()
                ->with('error', 'Failed to publish exam.');
        }
    }
}