<?php

namespace App\Http\Controllers;

use App\Models\Exam;
use App\Models\ExamRoutine;
use App\Models\ExamSeatPlan;
use App\Models\AdmitCard;
use App\Models\Classes;
use App\Models\Student;
use App\Models\Teacher;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use Barryvdh\DomPDF\Facade\Pdf;

class ExamController extends Controller
{
    /**
     * Display exam management page
     */
    public function index()
    {
        $exams = Exam::with('class')
                    ->orderBy('start_date', 'desc')
                    ->paginate(15);
        
        $classes = Classes::where('status', 1)->get();
        $examTypes = Exam::getExamTypes();

        return view('exams.index', compact('exams', 'classes', 'examTypes'));
    }

    /**
     * Store exam
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'exam_name' => 'required|string|max:255',
            'exam_type' => 'required|string',
            'exam_year' => 'required|integer|min:2020|max:2030',
            'class_id' => 'required|exists:classes,id',
            'start_date' => 'required|date',
            'end_date' => 'required|date|after_or_equal:start_date',
            'description' => 'nullable|string'
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                           ->withErrors($validator)
                           ->withInput();
        }

        try {
            Exam::create([
                'exam_name' => $request->exam_name,
                'exam_type' => $request->exam_type,
                'exam_year' => $request->exam_year,
                'class_id' => $request->class_id,
                'start_date' => $request->start_date,
                'end_date' => $request->end_date,
                'description' => $request->description,
                'created_by' => auth()->id()
            ]);

            return redirect()->route('exams.index')
                           ->with('success', 'পরীক্ষা সফলভাবে তৈরি করা হয়েছে');

        } catch (\Exception $e) {
            return redirect()->back()
                           ->with('error', 'পরীক্ষা তৈরি করতে সমস্যা হয়েছে')
                           ->withInput();
        }
    }

    /**
     * Show exam details
     */
    public function show($id)
    {
        $exam = Exam::with('class', 'routines.invigilator')
                   ->findOrFail($id);
        
        $routines = $exam->routines()->orderBy('exam_date')->orderBy('start_time')->get();
        
        $teachers = Teacher::active()->get();
        $subjects = \App\Models\Result::getSubjects($exam->class_id);

        return view('exams.show', compact('exam', 'routines', 'teachers', 'subjects'));
    }

    /**
     * Add exam routine
     */
    public function addRoutine(Request $request, $examId)
    {
        $validator = Validator::make($request->all(), [
            'subject' => 'required|string|max:255',
            'subject_code' => 'required|string|max:50',
            'exam_date' => 'required|date',
            'start_time' => 'required',
            'end_time' => 'required|after:start_time',
            'total_marks' => 'required|integer|min:10|max:200',
            'pass_marks' => 'required|integer|lt:total_marks',
            'room_number' => 'required|string|max:50',
            'building' => 'nullable|string|max:100',
            'invigilator_id' => 'required|exists:teachers,id'
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                           ->withErrors($validator)
                           ->withInput();
        }

        try {
            $exam = Exam::findOrFail($examId);
            
            // Calculate duration
            $start = \Carbon\Carbon::parse($request->start_time);
            $end = \Carbon\Carbon::parse($request->end_time);
            $duration = $start->diffInMinutes($end);

            ExamRoutine::create([
                'exam_id' => $examId,
                'class_id' => $exam->class_id,
                'subject' => $request->subject,
                'subject_code' => $request->subject_code,
                'exam_date' => $request->exam_date,
                'start_time' => $request->start_time,
                'end_time' => $request->end_time,
                'duration_minutes' => $duration,
                'total_marks' => $request->total_marks,
                'pass_marks' => $request->pass_marks,
                'room_number' => $request->room_number,
                'building' => $request->building,
                'invigilator_id' => $request->invigilator_id,
                'additional_notes' => $request->additional_notes
            ]);

            return redirect()->route('exams.show', $examId)
                           ->with('success', 'পরীক্ষার রুটিন যোগ করা হয়েছে');

        } catch (\Exception $e) {
            return redirect()->back()
                           ->with('error', 'রুটিন যোগ করতে সমস্যা হয়েছে')
                           ->withInput();
        }
    }

    /**
     * Show seat plan page
     */
    public function seatPlan($examId, $routineId = null)
    {
        $exam = Exam::findOrFail($examId);
        
        if ($routineId) {
            $routine = ExamRoutine::findOrFail($routineId);
            $students = Student::where('class_id', $exam->class_id)
                              ->where('status', 1)
                              ->orderBy('roll_number')
                              ->get();
            
            $existingSeats = ExamSeatPlan::where('exam_id', $examId)
                                        ->where('exam_routine_id', $routineId)
                                        ->get()
                                        ->keyBy('student_id');

            return view('exams.seat-plan', compact('exam', 'routine', 'students', 'existingSeats'));
        }

        $routines = ExamRoutine::where('exam_id', $examId)->get();
        
        return view('exams.seat-plan-select', compact('exam', 'routines'));
    }

    /**
     * Generate seat plan
     */
    public function generateSeatPlan(Request $request, $examId, $routineId)
    {
        $validator = Validator::make($request->all(), [
            'room_number' => 'required|string',
            'building' => 'required|string',
            'rows' => 'required|integer|min:1|max:20',
            'columns' => 'required|integer|min:1|max:10'
        ]);

        if ($validator->fails()) {
            return redirect()->back()
                           ->withErrors($validator)
                           ->withInput();
        }

        try {
            // Delete existing seat plan
            ExamSeatPlan::where('exam_id', $examId)
                       ->where('exam_routine_id', $routineId)
                       ->delete();

            // Get students
            $exam = Exam::findOrFail($examId);
            $students = Student::where('class_id', $exam->class_id)
                              ->where('status', 1)
                              ->orderBy('roll_number')
                              ->pluck('id')
                              ->toArray();

            // Generate new seat plan
            ExamSeatPlan::generateSeatPlan(
                $examId,
                $routineId,
                $request->room_number,
                $request->building,
                $request->rows,
                $request->columns,
                $students
            );

            return redirect()->route('exams.seat-plan.view', [$examId, $routineId])
                           ->with('success', 'সিট প্ল্যান জেনারেট করা হয়েছে');

        } catch (\Exception $e) {
            return redirect()->back()
                           ->with('error', 'সিট প্ল্যান জেনারেট করতে সমস্যা হয়েছে');
        }
    }

    /**
     * View seat plan
     */
    public function viewSeatPlan($examId, $routineId)
    {
        $exam = Exam::findOrFail($examId);
        $routine = ExamRoutine::findOrFail($routineId);
        
        $seatPlan = ExamSeatPlan::with('student')
                               ->where('exam_id', $examId)
                               ->where('exam_routine_id', $routineId)
                               ->orderBy('row_number')
                               ->orderBy('column_number')
                               ->get();

        $rows = $seatPlan->max('row_number');
        $columns = $seatPlan->max('column_number');

        return view('exams.view-seat-plan', compact('exam', 'routine', 'seatPlan', 'rows', 'columns'));
    }

    /**
     * Generate admit cards
     */
    public function generateAdmitCards($examId)
    {
        $exam = Exam::findOrFail($examId);
        
        // Check if routines exist
        if ($exam->routines->isEmpty()) {
            return redirect()->back()
                           ->with('error', 'প্রথমে পরীক্ষার রুটিন তৈরি করুন');
        }

        try {
            $students = Student::where('class_id', $exam->class_id)
                              ->where('status', 1)
                              ->get();

            foreach ($students as $student) {
                AdmitCard::updateOrCreate(
                    [
                        'exam_id' => $examId,
                        'student_id' => $student->id
                    ],
                    [
                        'admit_card_no' => AdmitCard::generateAdmitCardNo($examId, $student->id),
                        'issued_date' => now(),
                        'status' => true
                    ]
                );
            }

            return redirect()->route('exams.admit-cards', $examId)
                           ->with('success', 'প্রবেশপত্র জেনারেট করা হয়েছে');

        } catch (\Exception $e) {
            return redirect()->back()
                           ->with('error', 'প্রবেশপত্র জেনারেট করতে সমস্যা হয়েছে');
        }
    }

    /**
     * Show admit cards
     */
    public function admitCards($examId)
    {
        $exam = Exam::with('class')->findOrFail($examId);
        
        $admitCards = AdmitCard::with('student')
                               ->where('exam_id', $examId)
                               ->orderBy('id')
                               ->paginate(50);

        return view('exams.admit-cards', compact('exam', 'admitCards'));
    }

    /**
     * Download admit card
     */
    public function downloadAdmitCard($examId, $studentId)
    {
        $exam = Exam::findOrFail($examId);
        $student = Student::with('class')->findOrFail($studentId);
        
        $admitCard = AdmitCard::where('exam_id', $examId)
                              ->where('student_id', $studentId)
                              ->firstOrFail();

        $routines = ExamRoutine::where('exam_id', $examId)
                               ->orderBy('exam_date')
                               ->orderBy('start_time')
                               ->get();

        $pdf = Pdf::loadView('exams.admit-card-pdf', compact('exam', 'student', 'admitCard', 'routines'));
        
        return $pdf->download('admit_card_' . $student->student_id . '.pdf');
    }

    /**
     * Print exam routine
     */
    public function printRoutine($examId)
    {
        $exam = Exam::with('class')->findOrFail($examId);
        $routines = ExamRoutine::with('invigilator')
                              ->where('exam_id', $examId)
                              ->orderBy('exam_date')
                              ->orderBy('start_time')
                              ->get();

        return view('exams.print-routine', compact('exam', 'routines'));
    }

    /**
     * Teacher duty chart
     */
    public function dutyChart($examId)
    {
        $exam = Exam::findOrFail($examId);
        
        $duties = ExamRoutine::with('invigilator')
                            ->where('exam_id', $examId)
                            ->get()
                            ->groupBy('invigilator_id');

        return view('exams.duty-chart', compact('exam', 'duties'));
    }

    /**
     * Exam analytics
     */
    public function analytics($examId)
    {
        $exam = Exam::with('class')->findOrFail($examId);
        
        $totalStudents = Student::where('class_id', $exam->class_id)
                               ->where('status', 1)
                               ->count();

        $totalRoutines = $exam->routines->count();
        $totalSeats = ExamSeatPlan::where('exam_id', $examId)->count();
        $admitCardsGenerated = AdmitCard::where('exam_id', $examId)->count();

        $stats = [
            'total_students' => $totalStudents,
            'total_routines' => $totalRoutines,
            'total_seats' => $totalSeats,
            'admit_cards' => $admitCardsGenerated,
            'admit_cards_percentage' => $totalStudents > 0 ? round(($admitCardsGenerated / $totalStudents) * 100, 2) : 0,
            'rooms_used' => $exam->routines->pluck('room_number')->unique()->count(),
            'invigilators' => $exam->routines->pluck('invigilator_id')->unique()->count()
        ];

        return view('exams.analytics', compact('exam', 'stats'));
    }
}