<?php

namespace App\Http\Controllers\Instructor;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use App\Models\Assignment;
use App\Models\AssignmentSubmission;
use App\Models\Course;
use App\Models\CourseChapter;

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

    /**
     * Display a listing of assignments for instructor's courses.
     *
     * @return \Illuminate\View\View
     */
    public function index(Request $request)
    {
        $instructor = Auth::user();
        
        // Get instructor's course IDs
        $courseIds = Course::where('instructor_id', $instructor->id)
            ->where('is_active', true)
            ->pluck('id');
        
        $query = Assignment::whereIn('course_id', $courseIds)
            ->with(['course', 'chapter']);
        
        // Filter by course
        if ($request->has('course_id') && $request->course_id) {
            $query->where('course_id', $request->course_id);
        }
        
        // Filter by published status
        if ($request->has('published') && $request->published !== '') {
            $query->where('is_published', $request->published == '1');
        }
        
        $assignments = $query->orderBy('due_date', 'desc')->paginate(20);
        
        // Get courses for filter dropdown
        $courses = Course::where('instructor_id', $instructor->id)
            ->where('is_active', true)
            ->orderBy('name', 'asc')
            ->get();
        
        return view('instructor.assignments.index', compact('assignments', 'courses'));
    }

    /**
     * Show the form for creating a new assignment.
     *
     * @return \Illuminate\View\View
     */
    public function create()
    {
        $instructor = Auth::user();
        
        $courses = Course::where('instructor_id', $instructor->id)
            ->where('is_active', true)
            ->with('chapters')
            ->orderBy('name', 'asc')
            ->get();
        
        return view('instructor.assignments.create', compact('courses'));
    }

    /**
     * Store a newly created assignment.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function store(Request $request)
    {
        $instructor = Auth::user();
        
        // Verify the course belongs to this instructor
        $course = Course::where('id', $request->course_id)
            ->where('instructor_id', $instructor->id)
            ->firstOrFail();
        
        $validated = $request->validate([
            'course_id' => 'required|exists:courses,id',
            'chapter_id' => 'nullable|exists:course_chapters,id',
            'title' => 'required|string|max:255',
            'description' => 'nullable|string',
            'instructions' => 'nullable|string',
            'due_date' => 'required|date|after_or_equal:today',
            'due_time' => 'nullable|date_format:H:i',
            'total_points' => 'required|numeric|min:0|max:1000',
            'allow_late_submission' => 'boolean',
            'late_penalty_percentage' => 'nullable|integer|min:0|max:100',
            'is_published' => 'boolean',
        ]);
        
        $validated['allow_late_submission'] = $request->has('allow_late_submission');
        $validated['is_published'] = $request->has('is_published');
        
        // Verify chapter belongs to the course if provided
        if ($validated['chapter_id']) {
            $chapter = CourseChapter::where('id', $validated['chapter_id'])
                ->where('course_id', $validated['course_id'])
                ->firstOrFail();
        }
        
        Assignment::create($validated);
        
        return redirect()->route('instructor.assignments.index')
            ->with('success', 'Assignment created successfully!');
    }

    /**
     * Display the specified assignment.
     *
     * @param  int  $id
     * @return \Illuminate\View\View
     */
    public function show($id)
    {
        $instructor = Auth::user();
        
        $assignment = Assignment::where('id', $id)
            ->whereHas('course', function($q) use ($instructor) {
                $q->where('instructor_id', $instructor->id);
            })
            ->with(['course', 'chapter', 'submissions.student'])
            ->firstOrFail();
        
        // Get submission statistics
        $totalSubmissions = $assignment->submissions->count();
        $gradedSubmissions = $assignment->submissions->where('status', 'graded')->count();
        $pendingSubmissions = $assignment->submissions->where('status', 'submitted')->count();
        
        // Get enrolled students count
        $enrolledStudents = $assignment->course->enrollments->count();
        
        return view('instructor.assignments.show', compact('assignment', 'totalSubmissions', 'gradedSubmissions', 'pendingSubmissions', 'enrolledStudents'));
    }

    /**
     * Show the form for editing the specified assignment.
     *
     * @param  int  $id
     * @return \Illuminate\View\View
     */
    public function edit($id)
    {
        $instructor = Auth::user();
        
        $assignment = Assignment::where('id', $id)
            ->whereHas('course', function($q) use ($instructor) {
                $q->where('instructor_id', $instructor->id);
            })
            ->with(['course', 'chapter'])
            ->firstOrFail();
        
        $courses = Course::where('instructor_id', $instructor->id)
            ->where('is_active', true)
            ->with('chapters')
            ->orderBy('name', 'asc')
            ->get();
        
        return view('instructor.assignments.edit', compact('assignment', 'courses'));
    }

    /**
     * Update the specified assignment.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function update(Request $request, $id)
    {
        $instructor = Auth::user();
        
        $assignment = Assignment::where('id', $id)
            ->whereHas('course', function($q) use ($instructor) {
                $q->where('instructor_id', $instructor->id);
            })
            ->firstOrFail();
        
        $validated = $request->validate([
            'course_id' => 'required|exists:courses,id',
            'chapter_id' => 'nullable|exists:course_chapters,id',
            'title' => 'required|string|max:255',
            'description' => 'nullable|string',
            'instructions' => 'nullable|string',
            'due_date' => 'required|date',
            'due_time' => 'nullable|date_format:H:i',
            'total_points' => 'required|numeric|min:0|max:1000',
            'allow_late_submission' => 'boolean',
            'late_penalty_percentage' => 'nullable|integer|min:0|max:100',
            'is_published' => 'boolean',
        ]);
        
        $validated['allow_late_submission'] = $request->has('allow_late_submission');
        $validated['is_published'] = $request->has('is_published');
        
        // Verify chapter belongs to the course if provided
        if ($validated['chapter_id']) {
            $chapter = CourseChapter::where('id', $validated['chapter_id'])
                ->where('course_id', $validated['course_id'])
                ->firstOrFail();
        }
        
        $assignment->update($validated);
        
        return redirect()->route('instructor.assignments.show', $assignment->id)
            ->with('success', 'Assignment updated successfully!');
    }

    /**
     * Remove the specified assignment.
     *
     * @param  int  $id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function destroy($id)
    {
        $instructor = Auth::user();
        
        $assignment = Assignment::where('id', $id)
            ->whereHas('course', function($q) use ($instructor) {
                $q->where('instructor_id', $instructor->id);
            })
            ->firstOrFail();
        
        $assignment->delete();
        
        return redirect()->route('instructor.assignments.index')
            ->with('success', 'Assignment deleted successfully!');
    }

    /**
     * Display submissions for a specific assignment.
     *
     * @param  int  $id
     * @return \Illuminate\View\View
     */
    public function submissions($id)
    {
        $instructor = Auth::user();
        
        $assignment = Assignment::where('id', $id)
            ->whereHas('course', function($q) use ($instructor) {
                $q->where('instructor_id', $instructor->id);
            })
            ->with(['course', 'chapter'])
            ->firstOrFail();
        
        $submissions = AssignmentSubmission::where('assignment_id', $id)
            ->with(['student', 'gradedBy'])
            ->orderBy('submitted_at', 'desc')
            ->get();
        
        return view('instructor.assignments.submissions', compact('assignment', 'submissions'));
    }

    /**
     * Grade a submission.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\RedirectResponse
     */
    public function grade(Request $request, $id)
    {
        try {
            $instructor = Auth::user();
            
            // Load submission with assignment and course relationship
            $submission = AssignmentSubmission::with(['assignment.course'])
                ->where('id', $id)
                ->whereHas('assignment.course', function($q) use ($instructor) {
                    $q->where('instructor_id', $instructor->id);
                })
                ->firstOrFail();
            
            // Ensure assignment relationship is loaded
            if (!$submission->assignment) {
                return redirect()->back()
                    ->withErrors(['error' => 'Assignment not found for this submission.']);
            }
            
            $validated = $request->validate([
                'score' => 'required|numeric|min:0|max:' . $submission->assignment->total_points,
                'instructor_feedback' => 'nullable|string',
            ], [
                'score.required' => 'Score is required.',
                'score.numeric' => 'Score must be a number.',
                'score.min' => 'Score cannot be negative.',
                'score.max' => 'Score cannot exceed ' . number_format($submission->assignment->total_points, 2) . ' points.',
                'instructor_feedback.string' => 'Feedback must be text.',
            ]);
            
            // Calculate grade percentage
            $gradePercentage = ($validated['score'] / $submission->assignment->total_points) * 100;
            
            // Round to 2 decimal places
            $gradePercentage = round($gradePercentage, 2);
            
            $submission->update([
                'score' => $validated['score'],
                'grade_percentage' => $gradePercentage,
                'instructor_feedback' => $validated['instructor_feedback'] ?? null,
                'status' => 'graded',
                'graded_at' => now(),
                'graded_by' => $instructor->id,
            ]);
            
            return redirect()->route('instructor.assignments.submissions', $submission->assignment_id)
                ->with('success', 'Submission graded successfully!');
                
        } catch (\Illuminate\Validation\ValidationException $e) {
            return redirect()->back()
                ->withInput()
                ->withErrors($e->errors());
        } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
            return redirect()->route('instructor.assignments.index')
                ->withErrors(['error' => 'Submission not found or you do not have access to it.']);
        } catch (\Exception $e) {
            Log::error('Assignment grading error: ' . $e->getMessage(), [
                'submission_id' => $id,
                'instructor_id' => Auth::id(),
                'exception' => $e
            ]);
            
            return redirect()->back()
                ->withInput()
                ->withErrors(['error' => 'An error occurred while grading the submission. Please try again.']);
        }
    }
}

