<?php

namespace App\Http\Controllers;

use App\Models\AdmissionApplication;
use App\Models\AdmissionSeat;
use App\Models\AdmissionTest;
use App\Models\Classes;
use App\Models\Payment;
use App\Models\SmsLog;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use Barryvdh\DomPDF\Facade\Pdf;

class AdmissionController extends Controller
{
    /**
     * Display admission dashboard
     */
    public function index()
    {
        $currentYear = date('Y');
        
        $stats = [
            'total_applications' => AdmissionApplication::where('academic_year', $currentYear)->count(),
            'pending' => AdmissionApplication::where('academic_year', $currentYear)->where('status', 'pending')->count(),
            'selected' => AdmissionApplication::where('academic_year', $currentYear)->where('status', 'selected')->count(),
            'waiting' => AdmissionApplication::where('academic_year', $currentYear)->where('status', 'waiting')->count(),
            'total_seats' => AdmissionSeat::where('academic_year', $currentYear)->sum('total_seats'),
            'available_seats' => AdmissionSeat::where('academic_year', $currentYear)->sum('available_seats')
        ];

        $classWise = AdmissionSeat::with('class')
                                  ->where('academic_year', $currentYear)
                                  ->get();

        $recentApplications = AdmissionApplication::with('class')
                                                 ->where('academic_year', $currentYear)
                                                 ->orderBy('submitted_at', 'desc')
                                                 ->limit(10)
                                                 ->get();

        return view('admission.index', compact('stats', 'classWise', 'recentApplications'));
    }

    /**
     * Show online admission form
     */
    public function showForm(Request $request)
    {
        $classId = $request->class_id;
        
        // Check if admissions are open
        if ($classId) {
            $seat = AdmissionSeat::where('class_id', $classId)
                                 ->where('academic_year', date('Y'))
                                 ->first();
            
            if (!$seat || !$seat->isOpen()) {
                return redirect()->route('admission.apply')
                               ->with('error', 'এই শ্রেণিতে ভর্তি চলছে না');
            }

            if (!$seat->hasSeats()) {
                return redirect()->route('admission.apply')
                               ->with('error', 'এই শ্রেণিতে আসন সংখ্যা পূর্ণ হয়েছে');
            }
        }

        $classes = Classes::where('status', 1)->get();
        
        return view('admission.form', compact('classes', 'classId'));
    }

    /**
     * Submit admission form
     */
    public function submitForm(Request $request)
    {
        $validator = Validator::make($request->all(), [
            // Personal Info
            'class_id' => 'required|exists:classes,id',
            'applicant_name_bn' => 'required|string|max:255',
            'applicant_name_en' => 'required|string|max:255',
            'date_of_birth' => 'required|date|before:' . now()->subYears(5)->format('Y-m-d'),
            'birth_certificate_no' => 'required|string|unique:admission_applications',
            'gender' => 'required|in:male,female,other',
            'blood_group' => 'nullable|in:A+,A-,B+,B-,O+,O-,AB+,AB-',
            'religion' => 'required|string|max:50',
            'nationality' => 'required|string|max:50',
            
            // Contact Info
            'present_address' => 'required|string',
            'permanent_address' => 'required|string',
            'phone' => 'required|string|max:20',
            'email' => 'nullable|email|max:255',
            
            // Father's Info
            'father_name_bn' => 'required|string|max:255',
            'father_name_en' => 'required|string|max:255',
            'father_phone' => 'required|string|max:20',
            'father_occupation' => 'nullable|string|max:255',
            'father_education' => 'nullable|string|max:255',
            
            // Mother's Info
            'mother_name_bn' => 'required|string|max:255',
            'mother_name_en' => 'required|string|max:255',
            'mother_phone' => 'required|string|max:20',
            'mother_occupation' => 'nullable|string|max:255',
            'mother_education' => 'nullable|string|max:255',
            
            // Previous School
            'previous_school' => 'nullable|string|max:255',
            'previous_class' => 'nullable|string|max:50',
            'previous_result' => 'nullable|string|max:50',
            
            // Files
            'photo' => 'required|image|mimes:jpeg,png,jpg|max:2048',
            'signature' => 'required|image|mimes:jpeg,png,jpg|max:1024',
            'birth_certificate' => 'required|file|mimes:pdf,jpg,jpeg,png|max:5120',
            'transfer_certificate' => 'nullable|file|mimes:pdf,jpg,jpeg,png|max:5120',
            
            // Additional
            'has_siblings' => 'boolean',
            'is_minority' => 'boolean',
            'is_disabled' => 'boolean',
            'agreement' => 'required|accepted'
        ]);

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

        DB::beginTransaction();

        try {
            // Check seat availability
            $seat = AdmissionSeat::where('class_id', $request->class_id)
                                 ->where('academic_year', date('Y'))
                                 ->first();

            if (!$seat || !$seat->hasSeats($request->gender)) {
                return redirect()->back()
                               ->with('error', 'দুঃখিত, এই শ্রেণিতে আর আসন নেই')
                               ->withInput();
            }

            // Upload files
            $data = $request->except('_token', 'agreement');
            $data['application_no'] = AdmissionApplication::generateApplicationNo();
            $data['form_no'] = AdmissionApplication::generateFormNo();
            $data['academic_year'] = date('Y');
            $data['submitted_at'] = now();
            $data['status'] = 'pending';

            // Upload photo
            if ($request->hasFile('photo')) {
                $file = $request->file('photo');
                $filename = 'photo_' . $data['application_no'] . '.' . $file->getClientOriginalExtension();
                $file->move(public_path('uploads/admission/photos'), $filename);
                $data['photo'] = 'uploads/admission/photos/' . $filename;
            }

            // Upload signature
            if ($request->hasFile('signature')) {
                $file = $request->file('signature');
                $filename = 'sig_' . $data['application_no'] . '.' . $file->getClientOriginalExtension();
                $file->move(public_path('uploads/admission/signatures'), $filename);
                $data['signature'] = 'uploads/admission/signatures/' . $filename;
            }

            // Upload birth certificate
            if ($request->hasFile('birth_certificate')) {
                $file = $request->file('birth_certificate');
                $filename = 'birth_' . $data['application_no'] . '.' . $file->getClientOriginalExtension();
                $file->move(public_path('uploads/admission/documents'), $filename);
                $data['birth_certificate'] = 'uploads/admission/documents/' . $filename;
            }

            // Upload transfer certificate
            if ($request->hasFile('transfer_certificate')) {
                $file = $request->file('transfer_certificate');
                $filename = 'tc_' . $data['application_no'] . '.' . $file->getClientOriginalExtension();
                $file->move(public_path('uploads/admission/documents'), $filename);
                $data['transfer_certificate'] = 'uploads/admission/documents/' . $filename;
            }

            // Set boolean values
            $data['has_siblings'] = $request->has('has_siblings');
            $data['is_minority'] = $request->has('is_minority');
            $data['is_disabled'] = $request->has('is_disabled');

            // Create application
            $application = AdmissionApplication::create($data);

            // Send confirmation SMS
            $this->sendConfirmationSms($application);

            DB::commit();

            return redirect()->route('admission.success', $application->application_no)
                           ->with('success', 'আপনার ভর্তি ফর্ম সফলভাবে জমা দেওয়া হয়েছে');

        } catch (\Exception $e) {
            DB::rollBack();
            \Log::error('Admission submission failed: ' . $e->getMessage());
            
            return redirect()->back()
                           ->with('error', 'ফর্ম জমা দিতে সমস্যা হয়েছে। আবার চেষ্টা করুন।')
                           ->withInput();
        }
    }

    /**
     * Show application success page
     */
    public function success($applicationNo)
    {
        $application = AdmissionApplication::where('application_no', $applicationNo)->firstOrFail();
        
        return view('admission.success', compact('application'));
    }

    /**
     * Download application form
     */
    public function downloadForm($id)
    {
        $application = AdmissionApplication::with('class')->findOrFail($id);
        
        $pdf = Pdf::loadView('admission.application-pdf', compact('application'));
        
        return $pdf->download('application_' . $application->application_no . '.pdf');
    }

    /**
     * Process application payment
     */
    public function processPayment(Request $request, $id)
    {
        $application = AdmissionApplication::findOrFail($id);

        $validator = Validator::make($request->all(), [
            'payment_method' => 'required|in:cash,bKash,nagad,bank',
            'amount' => 'required|numeric|min:1'
        ]);

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

        DB::beginTransaction();

        try {
            // Create payment record
            $payment = Payment::create([
                'application_id' => $application->id,
                'amount' => $request->amount,
                'payment_method' => $request->payment_method,
                'transaction_id' => $request->transaction_id,
                'payment_date' => now(),
                'status' => 'completed'
            ]);

            // Update application
            $application->payment_id = $payment->id;
            $application->application_fee = $request->amount;
            $application->payment_status = 'paid';
            $application->save();

            DB::commit();

            return redirect()->route('admission.applications.show', $application->id)
                           ->with('success', 'পেমেন্ট সফল হয়েছে');

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

    /**
     * Schedule admission test
     */
    public function scheduleTest(Request $request, $id)
    {
        $application = AdmissionApplication::findOrFail($id);

        $validator = Validator::make($request->all(), [
            'test_date' => 'required|date|after:today',
            'test_time' => 'required',
            'room_number' => 'required|string|max:50'
        ]);

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

        try {
            $rollNumber = AdmissionTest::generateRollNumber($application->class_id);

            $test = AdmissionTest::create([
                'application_id' => $application->id,
                'roll_number' => $rollNumber,
                'test_date' => $request->test_date,
                'test_time' => $request->test_date . ' ' . $request->test_time,
                'room_number' => $request->room_number,
                'status' => 'scheduled'
            ]);

            $application->status = 'shortlisted';
            $application->interview_date = $request->test_date;
            $application->interview_time = $request->test_time;
            $application->save();

            // Send SMS notification
            $this->sendTestSms($application, $test);

            return redirect()->route('admission.applications.show', $application->id)
                           ->with('success', 'পরীক্ষার সময় নির্ধারণ করা হয়েছে');

        } catch (\Exception $e) {
            return redirect()->back()
                           ->with('error', 'সময় নির্ধারণে সমস্যা হয়েছে');
        }
    }

    /**
     * Submit test marks
     */
    public function submitMarks(Request $request, $id)
    {
        $test = AdmissionTest::findOrFail($id);

        $validator = Validator::make($request->all(), [
            'written_marks' => 'required|numeric|min:0|max:100',
            'mcq_marks' => 'required|numeric|min:0|max:100',
            'viva_marks' => 'required|numeric|min:0|max:50',
            'status' => 'required|in:completed,absent'
        ]);

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

        try {
            $total = $request->written_marks + $request->mcq_marks + $request->viva_marks;

            $test->written_marks = $request->written_marks;
            $test->mcq_marks = $request->mcq_marks;
            $test->viva_marks = $request->viva_marks;
            $test->total_marks = $total;
            $test->status = $request->status;
            $test->checked_by = auth()->id();
            $test->save();

            return redirect()->route('admission.applications.show', $test->application_id)
                           ->with('success', 'নম্বর সংরক্ষণ করা হয়েছে');

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

    /**
     * Generate merit list
     */
    public function generateMeritList(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'class_id' => 'required|exists:classes,id',
            'academic_year' => 'required|integer'
        ]);

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

        $seat = AdmissionSeat::where('class_id', $request->class_id)
                             ->where('academic_year', $request->academic_year)
                             ->first();

        if (!$seat) {
            return redirect()->back()
                           ->with('error', 'আসনের তথ্য পাওয়া যায়নি');
        }

        DB::beginTransaction();

        try {
            // Get all completed tests
            $tests = AdmissionTest::with('application')
                                 ->whereHas('application', function($q) use ($request) {
                                     $q->where('class_id', $request->class_id)
                                       ->where('academic_year', $request->academic_year);
                                 })
                                 ->where('status', 'completed')
                                 ->orderBy('total_marks', 'desc')
                                 ->get();

            $selected = 0;
            $waiting = 0;

            foreach ($tests as $index => $test) {
                $rank = $index + 1;
                $application = $test->application;

                if ($selected < $seat->total_seats) {
                    // Selected
                    $application->status = 'selected';
                    $application->selected_rank = $rank;
                    $selected++;
                    
                    // Decrease seat
                    $seat->decreaseSeats(
                        $application->gender,
                        $application->is_minority,
                        $application->is_disabled
                    );
                } else {
                    // Waiting list
                    $application->status = 'waiting';
                    $application->waiting_number = $waiting + 1;
                    $waiting++;
                }

                $application->save();
            }

            DB::commit();

            return redirect()->back()
                           ->with('success', 'মেরিট লিস্ট জেনারেট করা হয়েছে');

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

    /**
     * Applications list
     */
    public function applications(Request $request)
    {
        $query = AdmissionApplication::with('class');

        if ($request->class_id) {
            $query->where('class_id', $request->class_id);
        }

        if ($request->status) {
            $query->where('status', $request->status);
        }

        if ($request->academic_year) {
            $query->where('academic_year', $request->academic_year);
        }

        $applications = $query->orderBy('submitted_at', 'desc')->paginate(20);

        $classes = Classes::where('status', 1)->get();
        $statuses = AdmissionApplication::getStatusTypes();

        return view('admission.applications', compact('applications', 'classes', 'statuses', 'request'));
    }

    /**
     * View application details
     */
    public function showApplication($id)
    {
        $application = AdmissionApplication::with('class', 'payment')
                                          ->findOrFail($id);
        
        $test = AdmissionTest::where('application_id', $id)->first();

        return view('admission.show', compact('application', 'test'));
    }

    /**
     * Seat management
     */
    public function seats()
    {
        $academicYear = date('Y');
        $seats = AdmissionSeat::with('class')
                              ->where('academic_year', $academicYear)
                              ->get();
        
        $classes = Classes::where('status', 1)->get();

        return view('admission.seats', compact('seats', 'classes', 'academicYear'));
    }

    /**
     * Update seats
     */
    public function updateSeats(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'class_id' => 'required|exists:classes,id',
            'total_seats' => 'required|integer|min:1',
            'boy_seats' => 'required|integer|min:0',
            'girl_seats' => 'required|integer|min:0',
            'minority_quota' => 'required|integer|min:0',
            'disabled_quota' => 'required|integer|min:0',
            'application_start_date' => 'required|date',
            'application_end_date' => 'required|date|after:application_start_date',
            'result_date' => 'required|date|after:application_end_date'
        ]);

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

        try {
            $data = $request->all();
            $data['academic_year'] = date('Y');
            $data['available_seats'] = $request->total_seats;

            AdmissionSeat::updateOrCreate(
                [
                    'academic_year' => date('Y'),
                    'class_id' => $request->class_id
                ],
                $data
            );

            return redirect()->route('admission.seats')
                           ->with('success', 'আসনের তথ্য আপডেট করা হয়েছে');

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

    /**
     * Send confirmation SMS
     */
    private function sendConfirmationSms($application)
    {
        $message = "প্রিয় {$application->applicant_name_bn}, আপনার ভর্তি ফর্ম জমা দেওয়া হয়েছে। আপনার আবেদন নম্বর: {$application->application_no}। ভর্তি পরীক্ষার তারিখ জানতে অপেক্ষা করুন।";
        
        // Send SMS via SMS module
        // SmsController::send($application->phone, $message);
    }

    /**
     * Send test SMS
     */
    private function sendTestSms($application, $test)
    {
        $date = date('d-m-Y', strtotime($test->test_date));
        $time = date('h:i A', strtotime($test->test_time));
        
        $message = "প্রিয় {$application->applicant_name_bn}, আপনার ভর্তি পরীক্ষা {$date} তারিখ {$time} সময় রুম নম্বর {$test->room_number} এ অনুষ্ঠিত হবে। আপনার রোল নম্বর: {$test->roll_number}।";
        
        // Send SMS
    }
}