<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\FeePayment;
use App\Models\User;
use App\Models\Course;
use App\Models\CourseOffering;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Database\QueryException;

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

    /**
     * Display a listing of fee payments.
     *
     * @return \Illuminate\View\View
     */
    public function index(Request $request)
    {
        $query = FeePayment::with(['student', 'course', 'courseOffering', 'recordedBy']);

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

        // Filter by date range
        if ($request->has('date_from') && $request->date_from) {
            $query->where('payment_date', '>=', $request->date_from);
        }

        if ($request->has('date_to') && $request->date_to) {
            $query->where('payment_date', '<=', $request->date_to);
        }

        // Filter by payment method
        if ($request->has('payment_method') && $request->payment_method) {
            $query->where('payment_method', $request->payment_method);
        }

        // Filter by payment status
        if ($request->has('payment_status') && $request->payment_status) {
            $query->where('payment_status', $request->payment_status);
        }

        $payments = $query->orderBy('payment_date', 'desc')->paginate(50);
        
        $totalAmount = $payments->sum('amount');
        $actualMoneyAtHand = $payments->where('payment_status', 'regular')->sum('amount');
        $students = User::where('role', 'student')->orderBy('name')->get();
        $courses = Course::where('is_active', true)->orderBy('name')->get();
        $offerings = CourseOffering::orderBy('start_date', 'desc')->get();

        return view('admin.fee-payments.index', compact('payments', 'totalAmount', 'actualMoneyAtHand', 'students', 'courses', 'offerings'));
    }

    /**
     * Store a newly created fee payment.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function store(Request $request)
    {
        try {
            $validated = $request->validate([
                'student_id' => 'required|exists:users,id',
                'course_id' => 'nullable|exists:courses,id',
                'course_offering_id' => 'nullable|exists:course_offerings,id',
                'amount' => 'required|numeric|min:0.01',
                'payment_date' => 'required|date',
                'payment_method' => 'required|in:cash,bank_transfer,card,online',
                'payment_status' => 'required|in:regular,scholarship,refunded',
                'transaction_reference' => 'nullable|string|max:255',
                'notes' => 'nullable|string',
            ]);

            // Get course_id - prioritize form value, otherwise get from offering
            $courseId = $validated['course_id'] ?? null;
            if (!$courseId && $validated['course_offering_id']) {
                $offering = CourseOffering::find($validated['course_offering_id']);
                $courseId = $offering ? $offering->course_id : null;
            }

            FeePayment::create([
                'student_id' => $validated['student_id'],
                'course_id' => $courseId,
                'course_offering_id' => $validated['course_offering_id'] ?? null,
                'amount' => $validated['amount'],
                'payment_date' => $validated['payment_date'],
                'payment_method' => $validated['payment_method'],
                'payment_status' => $validated['payment_status'],
                'transaction_reference' => $validated['transaction_reference'] ?? null,
                'notes' => $validated['notes'] ?? null,
                'recorded_by' => auth()->id(),
            ]);

            $redirectRoute = $validated['course_offering_id'] 
                ? route('admin.course-offerings.show', $validated['course_offering_id'])
                : route('admin.student-finances.index');

            return redirect($redirectRoute)
                ->with('success', 'Payment recorded successfully!');
        } catch (\Illuminate\Validation\ValidationException $e) {
            return back()->withErrors($e->errors())->withInput();
        } catch (QueryException $e) {
            Log::error('Fee payment store database error: ' . $e->getMessage());
            return back()->withErrors(['error' => 'Database error occurred. Please check logs.'])->withInput();
        } catch (\Exception $e) {
            Log::error('Fee payment store error: ' . $e->getMessage() . ' | File: ' . $e->getFile() . ' | Line: ' . $e->getLine());
            return back()->withErrors(['error' => 'An error occurred while recording the payment. Please try again.'])->withInput();
        }
    }

    /**
     * Show the form for editing the specified fee payment.
     *
     * @param  int  $id
     * @return \Illuminate\View\View
     */
    public function edit($id)
    {
        $payment = FeePayment::findOrFail($id);
        $students = User::where('role', 'student')->orderBy('name')->get();
        $courses = Course::where('is_active', true)->orderBy('name')->get();
        $offerings = CourseOffering::orderBy('start_date', 'desc')->get();
        return view('admin.fee-payments.edit', compact('payment', 'students', 'courses', 'offerings'));
    }

    /**
     * Update the specified fee payment.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function update(Request $request, $id)
    {
        try {
            $payment = FeePayment::findOrFail($id);

            $validated = $request->validate([
                'student_id' => 'required|exists:users,id',
                'course_id' => 'nullable|exists:courses,id',
                'course_offering_id' => 'nullable|exists:course_offerings,id',
                'amount' => 'required|numeric|min:0.01',
                'payment_date' => 'required|date',
                'payment_method' => 'required|in:cash,bank_transfer,card,online',
                'payment_status' => 'required|in:regular,scholarship,refunded',
                'transaction_reference' => 'nullable|string|max:255',
                'notes' => 'nullable|string',
            ]);

            // Get course_id - prioritize form value, otherwise get from offering
            $courseId = $validated['course_id'] ?? null;
            if (!$courseId && $validated['course_offering_id']) {
                $offering = CourseOffering::find($validated['course_offering_id']);
                $courseId = $offering ? $offering->course_id : null;
            }

            // Update fields individually to avoid mass assignment issues
            $payment->student_id = $validated['student_id'];
            $payment->course_id = $courseId;
            $payment->course_offering_id = $validated['course_offering_id'] ?? null;
            $payment->amount = $validated['amount'];
            $payment->payment_date = $validated['payment_date'];
            $payment->payment_method = $validated['payment_method'];
            $payment->payment_status = $validated['payment_status'];
            $payment->transaction_reference = $validated['transaction_reference'] ?? null;
            $payment->notes = $validated['notes'] ?? null;
            
            $payment->save();

            return redirect()->route('admin.fee-payments.index')
                ->with('success', 'Payment updated successfully!');
        } catch (\Illuminate\Validation\ValidationException $e) {
            return back()->withErrors($e->errors())->withInput();
        } catch (QueryException $e) {
            Log::error('Fee payment update database error: ' . $e->getMessage() . ' | SQL: ' . ($e->getSql() ?? 'N/A'));
            return back()->withErrors(['error' => 'Database error occurred. Please check logs.'])->withInput();
        } catch (\Exception $e) {
            Log::error('Fee payment update error: ' . $e->getMessage() . ' | File: ' . $e->getFile() . ' | Line: ' . $e->getLine());
            return back()->withErrors(['error' => 'An error occurred while updating the payment. Please try again.'])->withInput();
        }
    }

    /**
     * Remove the specified fee payment.
     *
     * @param  int  $id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function destroy($id)
    {
        $payment = FeePayment::findOrFail($id);
        $payment->delete();

        return redirect()->route('admin.fee-payments.index')
            ->with('success', 'Payment deleted successfully!');
    }
}
