<?php

namespace App\Http\Controllers\Api\Admin;

use App\Http\Controllers\Api\ApiController;
use App\Models\Student;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;

class StudentController extends ApiController
{
    /**
     * Display a listing of students with pagination and search
     */
    public function index(Request $request)
    {
        $perPage = $request->get('per_page', 15);
        $search = $request->get('search');
        $sortBy = $request->get('sort_by', 'created_at');
        $sortOrder = $request->get('sort_order', 'desc');

        $query = Student::with(['school', 'academicYear', 'class', 'section']);

        // Apply search
        if ($search) {
            $query->search($search);
        }

        // Apply filters
        if ($request->has('class_id') && $request->class_id) {
            $query->forClass($request->class_id);
        }

        if ($request->has('section_id') && $request->section_id) {
            $query->forSection($request->section_id);
        }

        if ($request->has('gender') && $request->gender) {
            $query->byGender($request->gender);
        }

        if ($request->has('is_active')) {
            $query->where('is_active', $request->boolean('is_active'));
        }

        // Apply sorting
        $query = $this->applySorting($query, $sortBy, $sortOrder);

        return $this->paginatedResponse($query, $perPage);
    }

    /**
     * Store a newly created student
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'school_id' => 'required|exists:schools,id',
            'academic_year_id' => 'required|exists:academic_years,id',
            'class_id' => 'required|exists:school_classes,id',
            'section_id' => 'required|exists:sections,id',
            'admission_number' => 'required|unique:students,admission_number',
            'roll_number' => 'nullable|string',
            'first_name' => 'required|string|max:255',
            'last_name' => 'required|string|max:255',
            'date_of_birth' => 'required|date',
            'gender' => 'required|in:male,female,other',
            'blood_group' => 'nullable|string',
            'religion' => 'nullable|string',
            'caste' => 'nullable|string',
            'category' => 'nullable|string',
            'mother_tongue' => 'nullable|string',
            'email' => 'nullable|email|unique:students,email',
            'password' => 'required|string|min:8',
            'phone' => 'nullable|string',
            'address' => 'nullable|string',
            'city' => 'nullable|string',
            'state' => 'nullable|string',
            'country' => 'nullable|string',
            'pincode' => 'nullable|string',
            'photo' => 'nullable|string',
            'admission_date' => 'required|date',
            'previous_school' => 'nullable|string',
            'medical_history' => 'nullable|string',
            'allergies' => 'nullable|string',
            'emergency_contact_name' => 'required|string',
            'emergency_contact_phone' => 'required|string',
            'father_name' => 'nullable|string',
            'father_phone' => 'nullable|string',
            'father_occupation' => 'nullable|string',
            'father_email' => 'nullable|email',
            'mother_name' => 'nullable|string',
            'mother_phone' => 'nullable|string',
            'mother_occupation' => 'nullable|string',
            'mother_email' => 'nullable|email',
            'guardian_name' => 'nullable|string',
            'guardian_phone' => 'nullable|string',
            'guardian_relation' => 'nullable|string',
            'is_active' => 'boolean',
        ]);

        if ($validator->fails()) {
            return $this->errorResponse('Validation failed', 422, $validator->errors());
        }

        $data = $request->all();
        $data['password'] = Hash::make($request->password);

        $student = Student::create($data);

        return $this->successResponse(
            $student->load(['school', 'academicYear', 'class', 'section']),
            'Student created successfully',
            201
        );
    }

    /**
     * Display the specified student
     */
    public function show($id)
    {
        $student = Student::with([
            'school',
            'academicYear',
            'class',
            'section',
            'parents',
            'busAssignment',
            'hostelAllocation'
        ])->find($id);

        if (!$student) {
            return $this->errorResponse('Student not found', 404);
        }

        return $this->successResponse($student);
    }

    /**
     * Update the specified student
     */
    public function update(Request $request, $id)
    {
        $student = Student::find($id);

        if (!$student) {
            return $this->errorResponse('Student not found', 404);
        }

        $validator = Validator::make($request->all(), [
            'school_id' => 'sometimes|exists:schools,id',
            'academic_year_id' => 'sometimes|exists:academic_years,id',
            'class_id' => 'sometimes|exists:school_classes,id',
            'section_id' => 'sometimes|exists:sections,id',
            'admission_number' => 'sometimes|unique:students,admission_number,' . $id,
            'roll_number' => 'nullable|string',
            'first_name' => 'sometimes|string|max:255',
            'last_name' => 'sometimes|string|max:255',
            'date_of_birth' => 'sometimes|date',
            'gender' => 'sometimes|in:male,female,other',
            'email' => 'nullable|email|unique:students,email,' . $id,
            'password' => 'nullable|string|min:8',
            'phone' => 'nullable|string',
            'is_active' => 'boolean',
        ]);

        if ($validator->fails()) {
            return $this->errorResponse('Validation failed', 422, $validator->errors());
        }

        $data = $request->except('password');

        if ($request->has('password') && $request->password) {
            $data['password'] = Hash::make($request->password);
        }

        $student->update($data);

        return $this->successResponse(
            $student->load(['school', 'academicYear', 'class', 'section']),
            'Student updated successfully'
        );
    }

    /**
     * Remove the specified student
     */
    public function destroy($id)
    {
        $student = Student::find($id);

        if (!$student) {
            return $this->errorResponse('Student not found', 404);
        }

        $student->delete();

        return $this->successResponse(null, 'Student deleted successfully');
    }

    /**
     * Get student attendance records
     */
    public function attendance(Request $request, $id)
    {
        $student = Student::find($id);

        if (!$student) {
            return $this->errorResponse('Student not found', 404);
        }

        $perPage = $request->get('per_page', 15);
        $startDate = $request->get('start_date');
        $endDate = $request->get('end_date');

        $query = $student->attendances();

        if ($startDate) {
            $query->where('date', '>=', $startDate);
        }

        if ($endDate) {
            $query->where('date', '<=', $endDate);
        }

        $query->orderBy('date', 'desc');

        $attendancePercentage = $student->calculateAttendancePercentage($startDate, $endDate);

        $data = $query->paginate($perPage);

        return response()->json([
            'success' => true,
            'data' => $data->items(),
            'attendance_percentage' => $attendancePercentage,
            'pagination' => [
                'total' => $data->total(),
                'per_page' => $data->perPage(),
                'current_page' => $data->currentPage(),
                'last_page' => $data->lastPage(),
            ],
        ]);
    }

    /**
     * Get student marks/results
     */
    public function marks(Request $request, $id)
    {
        $student = Student::find($id);

        if (!$student) {
            return $this->errorResponse('Student not found', 404);
        }

        $perPage = $request->get('per_page', 15);
        $examId = $request->get('exam_id');

        $query = $student->marks()->with(['exam', 'subject']);

        if ($examId) {
            $query->where('exam_id', $examId);
        }

        $query->orderBy('created_at', 'desc');

        return $this->paginatedResponse($query, $perPage);
    }
}
