<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Enrollment;
use App\Models\FeePayment;
use App\Models\User;
use App\Models\Course;
use App\Models\CourseOffering;
use Illuminate\Http\Request;

class StudentFinanceController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware(['auth', 'role:admin']);
    }

    /**
     * Display a listing of all student finances.
     *
     * @return \Illuminate\View\View
     */
    public function index(Request $request)
    {
        // Get all students with their enrollments
        $query = User::where('role', 'student')
            ->with(['enrollments.course', 'enrollments.courseOffering']);

        // Search by student name or school ID
        if ($request->has('search') && $request->search) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('school_id', 'like', "%{$search}%");
            });
        }

        $students = $query->orderBy('name')->get();

        // Build student finances data
        $studentFinances = [];
        $grandTotalFees = 0;
        $grandTotalPaid = 0;
        $grandTotalActualMoney = 0;

        foreach ($students as $student) {
            $studentTotalFees = 0;
            $studentTotalPaid = 0;
            $studentTotalActualMoney = 0;
            $courseFinances = [];

            foreach ($student->enrollments as $enrollment) {
                if ($enrollment->course) {
                    $courseFee = $enrollment->course->fees;
                    $studentTotalFees += $courseFee;

                    // Get payments for this enrollment (all payments count toward balance)
                    // Match by course_id or by course_offering_id if both match
                    $paid = FeePayment::where('student_id', $student->id)
                        ->where(function($q) use ($enrollment) {
                            $q->where('course_id', $enrollment->course_id);
                            if ($enrollment->course_offering_id) {
                                $q->orWhere(function($q2) use ($enrollment) {
                                    $q2->where('course_offering_id', $enrollment->course_offering_id)
                                       ->whereNull('course_id');
                                });
                            }
                        })
                        ->sum('amount');
                    
                    // Get actual money at hand (only regular payments)
                    $actualPaid = FeePayment::where('student_id', $student->id)
                        ->where('payment_status', 'regular')
                        ->where(function($q) use ($enrollment) {
                            $q->where('course_id', $enrollment->course_id);
                            if ($enrollment->course_offering_id) {
                                $q->orWhere(function($q2) use ($enrollment) {
                                    $q2->where('course_offering_id', $enrollment->course_offering_id)
                                       ->whereNull('course_id');
                                });
                            }
                        })
                        ->sum('amount');
                    
                    $studentTotalPaid += $paid;
                    $studentTotalActualMoney += $actualPaid;

                    $courseFinances[] = [
                        'enrollment' => $enrollment,
                        'course' => $enrollment->course,
                        'offering' => $enrollment->courseOffering,
                        'fee' => $courseFee,
                        'paid' => $paid,
                        'actual_paid' => $actualPaid,
                        'balance' => $courseFee - $paid,
                    ];
                }
            }

            $grandTotalFees += $studentTotalFees;
            $grandTotalPaid += $studentTotalPaid;
            $grandTotalActualMoney += $studentTotalActualMoney;

            $studentFinances[] = [
                'student' => $student,
                'total_fees' => $studentTotalFees,
                'total_paid' => $studentTotalPaid,
                'total_actual_money' => $studentTotalActualMoney,
                'total_balance' => $studentTotalFees - $studentTotalPaid,
                'courses' => $courseFinances,
            ];
        }

        // Filter by payment status if provided
        if ($request->has('status') && $request->status !== '') {
            $status = $request->status;
            $studentFinances = array_filter($studentFinances, function($finance) use ($status) {
                if ($status == 'paid' && $finance['total_balance'] <= 0) return true;
                if ($status == 'partial' && $finance['total_balance'] > 0 && $finance['total_paid'] > 0) return true;
                if ($status == 'pending' && $finance['total_paid'] == 0 && $finance['total_balance'] > 0) return true;
                if ($status == 'overpaid' && $finance['total_balance'] < 0) return true;
                return false;
            });
        }

        // Filter by course if provided
        if ($request->has('course_id') && $request->course_id) {
            $courseId = $request->course_id;
            foreach ($studentFinances as $key => $finance) {
                $studentFinances[$key]['courses'] = array_filter($finance['courses'], function($course) use ($courseId) {
                    return $course['course']->id == $courseId;
                });
                // Remove students with no courses after filtering
                if (empty($studentFinances[$key]['courses'])) {
                    unset($studentFinances[$key]);
                }
            }
            $studentFinances = array_values($studentFinances);
        }

        $courses = Course::where('is_active', true)->orderBy('name')->get();
        $offerings = CourseOffering::orderBy('start_date', 'desc')->get();

        return view('admin.student-finances.index', compact('studentFinances', 'courses', 'offerings', 'grandTotalFees', 'grandTotalPaid', 'grandTotalActualMoney'));
    }
}

