<?php

namespace Modules\Students\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
use Illuminate\Http\RedirectResponse;
use Modules\Students\Models\Student;
use Modules\Students\Http\Requests\StoreStudentRequest;
use Modules\Students\Http\Requests\UpdateStudentRequest;
use Modules\Students\Services\StudentService;
use Modules\Academic\Models\AcademicYear;
use Modules\Academic\Models\Classroom;
use Modules\Guardians\Models\Guardian;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\DB;

class StudentsController extends Controller
{
    private StudentService $studentService;

    public function __construct(StudentService $studentService)
    {
        $this->studentService = $studentService;
        $this->authorizeResource(Student::class, 'student');
    }

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

        // Build query based on user role
        $query = Student::with(['user', 'enrollments.classroom', 'guardians']);

        switch ($user->role) {
            case 'admin':
                // Admin can see all students
                break;

            case 'teacher':
                // Teachers can see students in their classrooms
                $query->whereHas('enrollments.classroom.subjects', function ($q) use ($user) {
                    $q->where('teacher_id', $user->id);
                });
                break;

            case 'student':
                // Students can only see themselves
                $query->where('user_id', $user->id);
                break;

            case 'guardian':
                // Guardians can see their students
                $query->whereHas('guardians', function ($q) use ($user) {
                    $q->where('guardian_id', $user->guardian->id);
                });
                break;
        }

        // Apply filters
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('student_id', 'like', "%{$search}%")
                  ->orWhereHas('user', function ($userQuery) use ($search) {
                      $userQuery->where('first_name', 'like', "%{$search}%")
                               ->orWhere('last_name', 'like', "%{$search}%")
                               ->orWhere('email', 'like', "%{$search}%");
                  });
            });
        }

        if ($request->filled('classroom_id')) {
            $query->whereHas('enrollments', function ($q) use ($request) {
                $q->where('classroom_id', $request->classroom_id)
                  ->where('is_active', true);
            });
        }

        if ($request->filled('academic_year_id')) {
            $query->whereHas('enrollments', function ($q) use ($request) {
                $q->where('academic_year_id', $request->academic_year_id);
            });
        }

        if ($request->filled('status')) {
            $query->where('is_active', $request->status === 'active');
        } else {
            // By default, only show active students
            $query->where('is_active', true);
        }

        $students = $query->latest()->paginate(20);

        // Get filter options
        $academicYears = AcademicYear::orderBy('start_date', 'desc')->get();
        $classrooms = $this->getAccessibleClassrooms($user);

        return Inertia::render('Students/Index', [
            'students' => $students,
            'filters' => [
                'search' => $request->search,
                'classroom_id' => $request->classroom_id,
                'academic_year_id' => $request->academic_year_id,
                'status' => $request->status,
            ],
            'academicYears' => $academicYears,
            'classrooms' => $classrooms,
        ]);
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create(): Response
    {
        $academicYears = AcademicYear::where('is_active', true)->get();
        $guardians = Guardian::with('user')->where('is_active', true)->get();

        return Inertia::render('Students/Create', [
            'academicYears' => $academicYears,
            'guardians' => $guardians,
        ]);
    }

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

        try {
            DB::beginTransaction();

            $student = $this->studentService->createStudent($validated);

            DB::commit();

            return redirect()
                ->route('students.show', $student)
                ->with('success', 'Student created successfully.');

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

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

    /**
     * Show the specified resource.
     */
    public function show(Student $student): Response
    {
        $student->load([
            'user',
            'guardians.user',
            'enrollments' => function ($query) {
                $query->with(['classroom', 'academicYear'])
                      ->orderBy('enrolled_at', 'desc');
            },
            'results' => function ($query) {
                $query->with(['subject', 'examType', 'classroom'])
                      ->latest('entered_at')
                      ->limit(20);
            }
        ]);

        // Get current enrollment
        $currentEnrollment = $student->enrollments()
            ->whereHas('academicYear', function ($query) {
                $query->where('is_active', true);
            })
            ->where('is_active', true)
            ->with(['classroom', 'academicYear'])
            ->first();

        // Get academic performance summary
        $performanceSummary = null;
        if ($currentEnrollment) {
            $performanceSummary = $this->studentService->getPerformanceSummary(
                $student->id,
                $currentEnrollment->academic_year_id
            );
        }

        return Inertia::render('Students/Show', [
            'student' => $student,
            'currentEnrollment' => $currentEnrollment,
            'performanceSummary' => $performanceSummary,
        ]);
    }

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

        $academicYears = AcademicYear::where('is_active', true)->get();
        $guardians = Guardian::with('user')->where('is_active', true)->get();

        return Inertia::render('Students/Edit', [
            'student' => $student,
            'academicYears' => $academicYears,
            'guardians' => $guardians,
        ]);
    }

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

        try {
            DB::beginTransaction();

            $this->studentService->updateStudent($student, $validated);

            DB::commit();

            return redirect()
                ->route('students.show', $student)
                ->with('success', 'Student updated successfully.');

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

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

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

            // Soft delete by deactivating
            $student->update(['is_active' => false]);
            $student->user->update(['is_active' => false]);

            // Deactivate current enrollments
            $student->enrollments()->where('is_active', true)->update(['is_active' => false]);

            DB::commit();

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

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

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

    /**
     * Get accessible classrooms based on user role
     */
    private function getAccessibleClassrooms($user)
    {
        switch ($user->role) {
            case 'admin':
                return Classroom::with('academicYear')->get();

            case 'teacher':
                return Classroom::whereHas('subjects', function ($query) use ($user) {
                    $query->where('teacher_id', $user->id);
                })->with('academicYear')->get();

            default:
                return collect();
        }
    }

    /**
     * Get student results for a specific academic year
     */
    public function results(Student $student, Request $request): Response
    {
        $this->authorize('view', $student);

        $academicYearId = $request->get('academic_year_id');
        $examTypeId = $request->get('exam_type_id');

        $results = $student->getResults($academicYearId, $examTypeId);

        $academicYears = AcademicYear::orderBy('start_date', 'desc')->get();
        $examTypes = \Modules\Academic\Models\ExamType::where('is_active', true)->get();

        return Inertia::render('Students/Results', [
            'student' => $student,
            'results' => $results,
            'academicYears' => $academicYears,
            'examTypes' => $examTypes,
            'filters' => [
                'academic_year_id' => $academicYearId,
                'exam_type_id' => $examTypeId,
            ],
        ]);
    }

    /**
     * Manage student guardians
     */
    public function guardians(Student $student): Response
    {
        $this->authorize('update', $student);

        $student->load(['guardians.user']);
        $availableGuardians = Guardian::with('user')
            ->where('is_active', true)
            ->whereNotIn('id', $student->guardians->pluck('id'))
            ->get();

        return Inertia::render('Students/Guardians', [
            'student' => $student,
            'availableGuardians' => $availableGuardians,
        ]);
    }

    /**
     * Assign guardian to student
     */
    public function assignGuardian(Student $student, Request $request): RedirectResponse
    {
        $this->authorize('update', $student);

        $request->validate([
            'guardian_id' => 'required|exists:guardians,id',
            'relationship' => 'required|string|in:father,mother,guardian,other',
        ]);

        $student->guardians()->attach($request->guardian_id, [
            'relationship' => $request->relationship,
        ]);

        return back()->with('success', 'Guardian assigned successfully.');
    }

    /**
     * Remove guardian from student
     */
    public function removeGuardian(Student $student, Guardian $guardian): RedirectResponse
    {
        $this->authorize('update', $student);

        $student->guardians()->detach($guardian->id);

        return back()->with('success', 'Guardian removed successfully.');
    }
}
