<?php

namespace Modules\Enrollment\Http\Controllers;

use App\Http\Controllers\Controller;
use Modules\Enrollment\Models\Enrollment;
use Modules\Academic\Models\Classroom;
use Modules\Academic\Models\AcademicYear;
use Modules\Students\Models\Student;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
use Illuminate\Http\RedirectResponse;
use Modules\Enrollment\Http\Requests\StoreEnrollmentRequest;
use Modules\Enrollment\Http\Requests\UpdateEnrollmentRequest;
use Modules\Enrollment\Services\EnrollmentService;
use Illuminate\Support\Facades\DB;

class EnrollmentController extends Controller
{
    private EnrollmentService $enrollmentService;

    public function __construct(EnrollmentService $enrollmentService)
    {
        $this->enrollmentService = $enrollmentService;
        $this->authorizeResource(Enrollment::class, 'enrollment');
    }

    /**
     * Display a listing of the resource.
     */
    public function index(Request $request): Response
    {
        $user = $request->user();

        // Build filters based on user role
        $filters = [
            'academic_year_id' => $request->academic_year_id,
            'classroom_id' => $request->classroom_id,
            'status' => $request->status,
            'search' => $request->search,
            'enrolled_from' => $request->enrolled_from,
            'enrolled_to' => $request->enrolled_to,
        ];

        // Role-based filtering
        if ($user->role === 'teacher') {
            // Teachers can only see enrollments for classrooms they teach
            $teacherClassrooms = $user->teacher?->subjects()
                ->with('classroom')
                ->get()
                ->pluck('classroom.id')
                ->unique()
                ->filter();

            if ($teacherClassrooms->isEmpty()) {
                $enrollments = new \Illuminate\Pagination\LengthAwarePaginator(
                    collect(),
                    0,
                    20,
                    1,
                    ['path' => request()->url(), 'pageName' => 'page']
                );
            } else {
                if (!$filters['classroom_id'] || !$teacherClassrooms->contains($filters['classroom_id'])) {
                    $filters['classroom_id'] = $teacherClassrooms->first();
                }
                $enrollments = $this->enrollmentService->getEnrollments($filters);
            }
        } else {
            $enrollments = $this->enrollmentService->getEnrollments($filters);
        }

        // Get dropdown data
        $academicYears = AcademicYear::orderBy('start_date', 'desc')->get();
        $classrooms = Classroom::with('academicYear')->orderBy('name')->get();

        // Get statistics
        $currentAcademicYear = AcademicYear::where('is_active', true)->first();
        $statistics = $this->enrollmentService->getEnrollmentStatistics($currentAcademicYear?->id);

        return Inertia::render('Enrollment/Index', [
            'enrollments' => $enrollments,
            'academicYears' => $academicYears,
            'classrooms' => $classrooms,
            'statistics' => $statistics,
            'filters' => $filters,
        ]);
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create(): Response
    {
        $academicYears = AcademicYear::orderBy('start_date', 'desc')->get();
        $classrooms = Classroom::with('academicYear')->orderBy('name')->get();
        $students = Student::where('is_active', true)
            ->with('user')
            ->orderBy('first_name')
            ->get();

        return Inertia::render('Enrollment/Create', [
            'academicYears' => $academicYears,
            'classrooms' => $classrooms,
            'students' => $students,
        ]);
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(StoreEnrollmentRequest $request): RedirectResponse
    {
        $validated = $request->validated();

        try {
            DB::beginTransaction();

            $enrollment = $this->enrollmentService->createEnrollment($validated);

            DB::commit();

            return redirect()
                ->route('enrollment.show', $enrollment)
                ->with('success', 'Student enrolled successfully.');

        } catch (\Exception $e) {
            DB::rollBack();

            return back()
                ->withInput()
                ->withErrors(['error' => 'Failed to create enrollment: ' . $e->getMessage()]);
        }
    }

    /**
     * Show the specified resource.
     */
    public function show(Enrollment $enrollment): Response
    {
        $enrollment->load([
            'student.user',
            'student.guardians.user',
            'classroom.subjects',
            'academicYear'
        ]);

        // Get student's other enrollments
        $enrollmentHistory = $this->enrollmentService->getStudentEnrollmentHistory($enrollment->student_id);

        // Get student's recent results in this classroom
        $recentResults = $enrollment->student->results()
            ->where('classroom_id', $enrollment->classroom_id)
            ->with(['subject', 'examType'])
            ->latest('entered_at')
            ->limit(10)
            ->get();

        return Inertia::render('Enrollment/Show', [
            'enrollment' => $enrollment,
            'enrollmentHistory' => $enrollmentHistory,
            'recentResults' => $recentResults,
        ]);
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(Enrollment $enrollment): Response
    {
        $enrollment->load(['student.user', 'classroom', 'academicYear']);

        $academicYears = AcademicYear::orderBy('start_date', 'desc')->get();
        $classrooms = Classroom::with('academicYear')->orderBy('name')->get();

        return Inertia::render('Enrollment/Edit', [
            'enrollment' => $enrollment,
            'academicYears' => $academicYears,
            'classrooms' => $classrooms,
        ]);
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(UpdateEnrollmentRequest $request, Enrollment $enrollment): RedirectResponse
    {
        $validated = $request->validated();

        try {
            DB::beginTransaction();

            $this->enrollmentService->updateEnrollment($enrollment, $validated);

            DB::commit();

            return redirect()
                ->route('enrollment.show', $enrollment)
                ->with('success', 'Enrollment updated successfully.');

        } catch (\Exception $e) {
            DB::rollBack();

            return back()
                ->withInput()
                ->withErrors(['error' => 'Failed to update enrollment: ' . $e->getMessage()]);
        }
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(Enrollment $enrollment): RedirectResponse
    {
        try {
            DB::beginTransaction();

            // Soft delete by deactivating
            $this->enrollmentService->deactivateEnrollment($enrollment, 'Deleted by admin');

            DB::commit();

            return redirect()
                ->route('enrollment.index')
                ->with('success', 'Enrollment deactivated successfully.');

        } catch (\Exception $e) {
            DB::rollBack();

            return back()
                ->withErrors(['error' => 'Failed to deactivate enrollment: ' . $e->getMessage()]);
        }
    }

    /**
     * Transfer student to different classroom
     */
    public function transfer(Request $request, Enrollment $enrollment): RedirectResponse
    {
        $this->authorize('update', $enrollment);

        $request->validate([
            'new_classroom_id' => 'required|exists:classrooms,id',
            'reason' => 'nullable|string|max:500',
        ]);

        try {
            DB::beginTransaction();

            $newEnrollment = $this->enrollmentService->transferStudent(
                $enrollment->student_id,
                $request->new_classroom_id,
                $enrollment->academic_year_id,
                $request->reason
            );

            DB::commit();

            return redirect()
                ->route('enrollment.show', $newEnrollment)
                ->with('success', 'Student transferred successfully.');

        } catch (\Exception $e) {
            DB::rollBack();

            return back()
                ->withErrors(['error' => 'Transfer failed: ' . $e->getMessage()]);
        }
    }

    /**
     * Toggle enrollment status
     */
    public function toggleStatus(Enrollment $enrollment): RedirectResponse
    {
        $this->authorize('update', $enrollment);

        try {
            DB::beginTransaction();

            if ($enrollment->is_active) {
                $this->enrollmentService->deactivateEnrollment($enrollment, 'Deactivated by admin');
                $message = 'Enrollment deactivated successfully.';
            } else {
                $this->enrollmentService->reactivateEnrollment($enrollment);
                $message = 'Enrollment reactivated successfully.';
            }

            DB::commit();

            return back()->with('success', $message);

        } catch (\Exception $e) {
            DB::rollBack();

            return back()
                ->withErrors(['error' => 'Failed to update enrollment status: ' . $e->getMessage()]);
        }
    }

    /**
     * Bulk enrollment page
     */
    public function bulkEnroll(): Response
    {
        $this->authorize('create', Enrollment::class);

        $academicYears = AcademicYear::orderBy('start_date', 'desc')->get();
        $classrooms = Classroom::with('academicYear')->orderBy('name')->get();

        return Inertia::render('Enrollment/BulkEnroll', [
            'academicYears' => $academicYears,
            'classrooms' => $classrooms,
        ]);
    }

    /**
     * Process bulk enrollment
     */
    public function processBulkEnroll(Request $request): RedirectResponse
    {
        $this->authorize('create', Enrollment::class);

        $request->validate([
            'classroom_id' => 'required|exists:classrooms,id',
            'academic_year_id' => 'required|exists:academic_years,id',
            'student_ids' => 'required|array|min:1',
            'student_ids.*' => 'exists:students,id',
        ]);

        try {
            DB::beginTransaction();

            $results = $this->enrollmentService->bulkEnrollStudents(
                $request->student_ids,
                $request->classroom_id,
                $request->academic_year_id
            );

            DB::commit();

            $message = "{$results['success']} students enrolled successfully.";
            if (!empty($results['errors'])) {
                $message .= " " . count($results['errors']) . " errors occurred.";
            }

            return redirect()
                ->route('enrollment.index')
                ->with('success', $message)
                ->with('bulk_errors', $results['errors']);

        } catch (\Exception $e) {
            DB::rollBack();

            return back()
                ->withInput()
                ->withErrors(['error' => 'Bulk enrollment failed: ' . $e->getMessage()]);
        }
    }

    /**
     * Get available students for a classroom
     */
    public function availableStudents(Request $request): \Illuminate\Http\JsonResponse
    {
        $request->validate([
            'classroom_id' => 'required|exists:classrooms,id',
            'academic_year_id' => 'required|exists:academic_years,id',
        ]);

        $students = $this->enrollmentService->getAvailableStudents(
            $request->classroom_id,
            $request->academic_year_id
        );

        return response()->json($students);
    }
}
