<?php

namespace Modules\Academic\Http\Controllers;

use App\Http\Controllers\Controller;
use Modules\Academic\Models\AcademicYear;
use Modules\Academic\Http\Requests\StoreAcademicYearRequest;
use Modules\Academic\Http\Requests\UpdateAcademicYearRequest;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\DB;

class AcademicYearController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
        $this->authorizeResource(AcademicYear::class, 'academic_year');
    }

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

        // Apply search filter
        if ($request->search) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('description', 'like', "%{$search}%");
            });
        }

        // Apply status filter
        if ($request->status !== null) {
            $query->where('is_active', $request->status === 'active');
        }

        $academicYears = $query->withCount(['classrooms', 'gradingRules', 'divisionRules'])
            ->orderBy('start_date', 'desc')
            ->paginate(20);

        // Get statistics
        $statistics = [
            'total' => AcademicYear::count(),
            'active' => AcademicYear::where('is_active', true)->count(),
            'inactive' => AcademicYear::where('is_active', false)->count(),
            'current' => AcademicYear::where('is_active', true)->where('start_date', '<=', now())->where('end_date', '>=', now())->count(),
        ];

        return Inertia::render('Academic/AcademicYears/Index', [
            'academicYears' => $academicYears,
            'statistics' => $statistics,
            'filters' => [
                'search' => $request->search,
                'status' => $request->status,
            ],
        ]);
    }

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

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

        try {
            DB::beginTransaction();

            // If setting as active, deactivate other academic years
            if ($validated['is_active'] ?? false) {
                AcademicYear::where('is_active', true)->update(['is_active' => false]);
            }

            $academicYear = AcademicYear::create($validated);

            DB::commit();

            return redirect()
                ->route('academic-years.show', $academicYear)
                ->with('success', 'Academic year created successfully.');

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

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

    /**
     * Display the specified resource.
     */
    public function show(AcademicYear $academicYear): Response
    {
        $academicYear->load([
            'classrooms.subjects',
            'gradingRules',
            'divisionRules'
        ]);

        // Load teachers for each classroom-subject combination
        foreach ($academicYear->classrooms as $classroom) {
            $classroom->load(['subjects' => function ($query) {
                $query->withPivot('teacher_id');
            }]);

            // Load teacher information for each subject
            foreach ($classroom->subjects as $subject) {
                if ($subject->pivot->teacher_id) {
                    $subject->teacher = \App\Models\User::find($subject->pivot->teacher_id);
                }
            }
        }

        // Get enrollment statistics
        $enrollmentStats = DB::table('enrollments')
            ->join('classrooms', 'enrollments.classroom_id', '=', 'classrooms.id')
            ->where('classrooms.academic_year_id', $academicYear->id)
            ->where('enrollments.is_active', true)
            ->selectRaw('
                COUNT(*) as total_enrollments,
                COUNT(DISTINCT enrollments.student_id) as unique_students,
                COUNT(DISTINCT enrollments.classroom_id) as active_classrooms
            ')
            ->first();

        // Get recent activities
        $recentActivities = collect();

        return Inertia::render('Academic/AcademicYears/Show', [
            'academicYear' => $academicYear,
            'enrollmentStats' => $enrollmentStats,
            'recentActivities' => $recentActivities,
        ]);
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(AcademicYear $academicYear): Response
    {
        return Inertia::render('Academic/AcademicYears/Edit', [
            'academicYear' => $academicYear,
        ]);
    }

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

        try {
            DB::beginTransaction();

            // If setting as active, deactivate other academic years
            if (($validated['is_active'] ?? false) && !$academicYear->is_active) {
                AcademicYear::where('is_active', true)->update(['is_active' => false]);
            }

            $academicYear->update($validated);

            DB::commit();

            return redirect()
                ->route('academic-years.show', $academicYear)
                ->with('success', 'Academic year updated successfully.');

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

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

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

            // Check if academic year has associated data
            $hasClassrooms = $academicYear->classrooms()->exists();
            $hasEnrollments = DB::table('enrollments')
                ->join('classrooms', 'enrollments.classroom_id', '=', 'classrooms.id')
                ->where('classrooms.academic_year_id', $academicYear->id)
                ->exists();

            if ($hasClassrooms || $hasEnrollments) {
                return back()
                    ->withErrors(['error' => 'Cannot delete academic year with associated classrooms or enrollments.']);
            }

            $academicYear->delete();

            DB::commit();

            return redirect()
                ->route('academic-years.index')
                ->with('success', 'Academic year deleted successfully.');

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

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

    /**
     * Toggle academic year status
     */
    public function toggleStatus(AcademicYear $academicYear): RedirectResponse
    {
        $this->authorize('update', $academicYear);

        try {
            DB::beginTransaction();

            if (!$academicYear->is_active) {
                // Deactivate other academic years when activating this one
                AcademicYear::where('is_active', true)->update(['is_active' => false]);
                $academicYear->update(['is_active' => true]);
                $message = 'Academic year activated successfully.';
            } else {
                $academicYear->update(['is_active' => false]);
                $message = 'Academic year deactivated successfully.';
            }

            DB::commit();

            return back()->with('success', $message);

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

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

    /**
     * Set as current academic year
     */
    public function setCurrent(AcademicYear $academicYear): RedirectResponse
    {
        $this->authorize('update', $academicYear);

        try {
            DB::beginTransaction();

            // Deactivate all other academic years
            AcademicYear::where('is_active', true)->update(['is_active' => false]);

            // Activate this academic year
            $academicYear->update(['is_active' => true]);

            DB::commit();

            return back()->with('success', 'Academic year set as current successfully.');

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

            return back()
                ->withErrors(['error' => 'Failed to set current academic year: ' . $e->getMessage()]);
        }
    }

    /**
     * Get academic year statistics
     */
    public function statistics(AcademicYear $academicYear): \Illuminate\Http\JsonResponse
    {
        $this->authorize('view', $academicYear);

        $stats = [
            'classrooms_count' => $academicYear->classrooms()->count(),
            'subjects_count' => DB::table('subjects')
                ->join('classrooms', 'subjects.classroom_id', '=', 'classrooms.id')
                ->where('classrooms.academic_year_id', $academicYear->id)
                ->count(),
            'enrollments_count' => DB::table('enrollments')
                ->join('classrooms', 'enrollments.classroom_id', '=', 'classrooms.id')
                ->where('classrooms.academic_year_id', $academicYear->id)
                ->where('enrollments.is_active', true)
                ->count(),
            'students_count' => DB::table('enrollments')
                ->join('classrooms', 'enrollments.classroom_id', '=', 'classrooms.id')
                ->where('classrooms.academic_year_id', $academicYear->id)
                ->where('enrollments.is_active', true)
                ->distinct('enrollments.student_id')
                ->count(),
            'grading_rules_count' => $academicYear->gradingRules()->count(),
            'division_rules_count' => $academicYear->divisionRules()->count(),
        ];

        return response()->json($stats);
    }
}
