<?php

namespace Modules\Guardians\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
use Illuminate\Http\RedirectResponse;
use Modules\Guardians\Models\Guardian;
use Modules\Guardians\Http\Requests\StoreGuardianRequest;
use Modules\Guardians\Http\Requests\UpdateGuardianRequest;
use Modules\Guardians\Services\GuardianService;
use Modules\Students\Models\Student;
use Modules\Academic\Models\AcademicYear;
use Modules\Academic\Models\ExamType;
use App\Models\User;
use Illuminate\Support\Facades\DB;

class GuardiansController extends Controller
{
    private GuardianService $guardianService;

    public function __construct(GuardianService $guardianService)
    {
        $this->guardianService = $guardianService;
        $this->authorizeResource(Guardian::class, 'guardian');
    }

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

        // Build query based on user role
        $query = Guardian::with(['user', 'students']);

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

            case 'teacher':
                // Teachers can see guardians of their students
                $query->whereHas('students.enrollments', function ($enrollmentQuery) use ($user) {
                    $enrollmentQuery->whereHas('classroom.subjects', function ($subjectQuery) use ($user) {
                        $subjectQuery->where('teacher_id', $user->id);
                    })->where('is_active', true);
                });
                break;

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

            default:
                // Students cannot access guardian list
                abort(403);
        }

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

        if ($request->filled('status')) {
            $query->where('is_active', $request->status === 'active');
        }

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

        return Inertia::render('Guardians/Index', [
            'guardians' => $guardians,
            'filters' => [
                'search' => $request->search,
                'status' => $request->status,
            ],
        ]);
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create(): Response
    {
        return Inertia::render('Guardians/Create');
    }

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

        try {
            DB::beginTransaction();

            $guardian = $this->guardianService->createGuardian($validated);

            DB::commit();

            return redirect()
                ->route('guardians.show', $guardian)
                ->with('success', 'Guardian created successfully.');

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

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

    /**
     * Show the specified resource.
     */
    public function show(Guardian $guardian): Response
    {
        $guardian->load([
            'user',
            'students.user',
            'students.enrollments.classroom',
            'students.enrollments.academicYear'
        ]);

        $currentAcademicYear = AcademicYear::where('is_active', true)->first();

        // Get guardian's students' performance summary
        $studentsPerformance = [];
        if ($currentAcademicYear) {
            foreach ($guardian->students as $student) {
                $performance = $this->guardianService->getStudentPerformanceSummary(
                    $student->id,
                    $currentAcademicYear->id
                );
                $studentsPerformance[$student->id] = $performance;
            }
        }

        // Get recent activities
        $recentActivities = $this->guardianService->getRecentActivities($guardian->id);

        return Inertia::render('Guardians/Show', [
            'guardian' => $guardian,
            'studentsPerformance' => $studentsPerformance,
            'recentActivities' => $recentActivities,
            'currentAcademicYear' => $currentAcademicYear,
        ]);
    }

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

        return Inertia::render('Guardians/Edit', [
            'guardian' => $guardian,
        ]);
    }

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

        try {
            DB::beginTransaction();

            $this->guardianService->updateGuardian($guardian, $validated);

            DB::commit();

            return redirect()
                ->route('guardians.show', $guardian)
                ->with('success', 'Guardian updated successfully.');

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

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

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

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

            // Remove student relationships
            $guardian->students()->detach();

            DB::commit();

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

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

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

    /**
     * Show guardian's students
     */
    public function students(Guardian $guardian): Response
    {
        $this->authorize('view', $guardian);

        $guardian->load([
            'students.user',
            'students.enrollments.classroom',
            'students.enrollments.academicYear'
        ]);

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

    /**
     * Show student results for guardian
     */
    public function studentResults(Guardian $guardian, Request $request): Response
    {
        $this->authorize('view', $guardian);

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

        $currentAcademicYear = AcademicYear::where('is_active', true)->first();

        if (!$academicYearId && $currentAcademicYear) {
            $academicYearId = $currentAcademicYear->id;
        }

        // Get students with their results
        $studentsWithResults = $this->guardianService->getStudentsResults(
            $guardian->id,
            $academicYearId,
            $examTypeId,
            $studentId
        );

        // Get filter options
        $academicYears = AcademicYear::orderBy('start_date', 'desc')->get();
        $examTypes = ExamType::where('is_active', true)->get();
        $students = $guardian->students()->get();

        return Inertia::render('Guardians/StudentResults', [
            'guardian' => $guardian,
            'studentsWithResults' => $studentsWithResults,
            'academicYears' => $academicYears,
            'examTypes' => $examTypes,
            'students' => $students,
            'filters' => [
                'academic_year_id' => $academicYearId,
                'exam_type_id' => $examTypeId,
                'student_id' => $studentId,
            ],
        ]);
    }

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

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

        // Check if student is active
        $student = Student::findOrFail($request->student_id);
        if (!$student->is_active) {
            return back()->withErrors(['error' => 'Cannot assign inactive student.']);
        }

        // Check if already assigned
        if ($guardian->students()->where('student_id', $request->student_id)->exists()) {
            return back()->withErrors(['error' => 'Student already assigned to this guardian.']);
        }

        $guardian->students()->attach($request->student_id, [
            'relationship' => $request->relationship,
        ]);

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

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

        if (!$guardian->students()->where('student_id', $student->id)->exists()) {
            return back()->withErrors(['error' => 'Student is not assigned to this guardian.']);
        }

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

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

    /**
     * Get guardian dashboard data
     */
    public function dashboard(Guardian $guardian): Response
    {
        $this->authorize('view', $guardian);

        $currentAcademicYear = AcademicYear::where('is_active', true)->first();

        // Get dashboard statistics
        $statistics = $this->guardianService->getDashboardStatistics($guardian->id, $currentAcademicYear?->id);

        // Get recent activities
        $recentActivities = $this->guardianService->getRecentActivities($guardian->id, 15);

        // Get upcoming events/exams (if implemented)
        $upcomingEvents = [];

        return Inertia::render('Guardians/Dashboard', [
            'guardian' => $guardian,
            'statistics' => $statistics,
            'recentActivities' => $recentActivities,
            'upcomingEvents' => $upcomingEvents,
            'currentAcademicYear' => $currentAcademicYear,
        ]);
    }
}
