<?php

namespace App\Http\Controllers\Api\V1\Student;

use App\Http\Controllers\Api\V1\BaseController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Log;
use App\Models\Assignment;
use App\Models\AssignmentSubmission;

class AssignmentController extends BaseController
{
    /**
     * Get list of assignments.
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function index(Request $request)
    {
        try {
            $user = Auth::user();
            
            $query = Assignment::whereHas('course', function($q) use ($user) {
                $q->whereHas('enrollments', function($eq) use ($user) {
                    $eq->where('student_id', $user->id);
                });
            })->with(['course', 'course.instructor']);
            
            // Filter by status
            if ($request->has('status')) {
                if ($request->status === 'pending') {
                    $query->whereDoesntHave('submissions', function($q) use ($user) {
                        $q->where('student_id', $user->id);
                    });
                } elseif ($request->status === 'submitted') {
                    $query->whereHas('submissions', function($q) use ($user) {
                        $q->where('student_id', $user->id)
                          ->whereNull('grade');
                    });
                } elseif ($request->status === 'graded') {
                    $query->whereHas('submissions', function($q) use ($user) {
                        $q->where('student_id', $user->id)
                          ->whereNotNull('grade');
                    });
                }
            }
            
            // Filter by course
            if ($request->has('course_id')) {
                $query->where('course_id', $request->course_id);
            }
            
            $assignments = $query->orderBy('due_date', 'desc')
                ->paginate($request->get('per_page', 20));
            
            $data = $assignments->map(function($assignment) use ($user) {
                $submission = AssignmentSubmission::where('assignment_id', $assignment->id)
                    ->where('student_id', $user->id)
                    ->first();
                
                return [
                    'id' => $assignment->id,
                    'title' => $assignment->title,
                    'description' => $assignment->description,
                    'due_date' => $assignment->due_date,
                    'course' => [
                        'id' => $assignment->course->id ?? null,
                        'title' => $assignment->course->name ?? 'N/A',
                    ],
                    'instructor' => [
                        'id' => $assignment->course->instructor->id ?? null,
                        'name' => $assignment->course->instructor->name ?? 'N/A',
                    ],
                    'status' => $submission ? ($submission->status ?? ($submission->grade ? 'graded' : 'submitted')) : 'pending',
                    'submitted_at' => $submission->submitted_at ?? null,
                    'score' => $submission->score ?? null,
                    'grade_percentage' => $submission->grade_percentage ?? null,
                    'feedback' => $submission->instructor_feedback ?? null,
                ];
            });
            
            return $this->paginated($data, $assignments);
        } catch (\Exception $e) {
            \Illuminate\Support\Facades\Log::error('Student Assignments API error: ' . $e->getMessage());
            return $this->error('An error occurred while fetching assignments.', null, 500);
        }
    }
    
    /**
     * Get assignment details.
     *
     * @param int $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function show($id)
    {
        try {
            $user = Auth::user();
            
            $assignment = Assignment::whereHas('course', function($q) use ($user) {
                $q->whereHas('enrollments', function($eq) use ($user) {
                    $eq->where('student_id', $user->id);
                });
            })->with(['course', 'course.instructor'])->findOrFail($id);
            
            $submission = AssignmentSubmission::where('assignment_id', $assignment->id)
                ->where('student_id', $user->id)
                ->first();
            
            // Get instructor from course
            $instructor = $assignment->course->instructor ?? null;
            
            return $this->success([
                'id' => $assignment->id,
                'title' => $assignment->title,
                'description' => $assignment->description,
                'instructions' => $assignment->instructions,
                'due_date' => $assignment->due_date,
                'due_time' => $assignment->due_time,
                'total_points' => $assignment->total_points,
                'course' => [
                    'id' => $assignment->course->id ?? null,
                    'title' => $assignment->course->name ?? 'N/A',
                ],
                'instructor' => $instructor ? [
                    'id' => $instructor->id,
                    'name' => $instructor->name,
                ] : null,
                'submission' => $submission ? [
                    'id' => $submission->id,
                    'submission_text' => $submission->submission_text,
                    'submission_file' => $submission->submission_file ? url('storage/' . $submission->submission_file) : null,
                    'submitted_at' => $submission->submitted_at,
                    'status' => $submission->status,
                    'score' => $submission->score,
                    'grade_percentage' => $submission->grade_percentage,
                    'feedback' => $submission->instructor_feedback,
                    'graded_at' => $submission->graded_at,
                    'is_late' => $submission->is_late,
                ] : null,
            ]);
        } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
            return $this->error('Assignment not found.', null, 404);
        } catch (\Exception $e) {
            \Illuminate\Support\Facades\Log::error('Student Assignment API error: ' . $e->getMessage());
            return $this->error('An error occurred while fetching assignment details.', null, 500);
        }
    }
    
    /**
     * Submit assignment.
     *
     * @param Request $request
     * @param int $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function submit(Request $request, $id)
    {
        try {
            $user = Auth::user();
            
            // Verify assignment exists and student is enrolled
            $assignment = Assignment::whereHas('course', function($q) use ($user) {
                $q->whereHas('enrollments', function($eq) use ($user) {
                    $eq->where('student_id', $user->id);
                });
            })->findOrFail($id);
            
            $validated = $request->validate([
                'submission_text' => 'nullable|string',
                'submission_file' => 'nullable|file|max:10240', // 10MB max
            ]);
            
            // Check if submission already exists
            $existingSubmission = AssignmentSubmission::where('assignment_id', $assignment->id)
                ->where('student_id', $user->id)
                ->first();
            
            // Prevent resubmission if already graded
            if ($existingSubmission && $existingSubmission->status == 'graded') {
                return $this->error('This assignment has already been graded. Resubmission is not allowed.', null, 403);
            }
            
            // Ensure at least one submission field is provided (for new submissions)
            // For updates, allow if existing submission already has content
            if (!$existingSubmission) {
                // For new submissions, require at least one field
                if (empty($validated['submission_text']) && !$request->hasFile('submission_file')) {
                    return $this->error('You must provide either submission text or a file.', null, 422);
                }
            } else {
                // For updates, ensure at least one field is provided or existing submission has content
                $hasNewContent = !empty($validated['submission_text']) || $request->hasFile('submission_file');
                $hasExistingContent = !empty($existingSubmission->submission_text) || !empty($existingSubmission->submission_file);
                
                if (!$hasNewContent && !$hasExistingContent) {
                    return $this->error('You must provide either submission text or a file.', null, 422);
                }
            }
            
            // Check if assignment is past due and if late submissions are allowed
            $dueDateTime = $assignment->due_date;
            if ($assignment->due_time) {
                // Handle due_time as string (H:i format) or as time
                $dueTimeStr = is_string($assignment->due_time) ? $assignment->due_time : (is_object($assignment->due_time) ? $assignment->due_time->format('H:i') : $assignment->due_time);
                $dueDateTime = \Carbon\Carbon::parse($assignment->due_date->format('Y-m-d') . ' ' . $dueTimeStr);
            } else {
                $dueDateTime = $assignment->due_date->endOfDay();
            }
            
            $isLate = \Carbon\Carbon::now()->greaterThan($dueDateTime);
            
            // Check if late submission is allowed
            if ($isLate && !$assignment->allow_late_submission) {
                return $this->error('This assignment does not allow late submissions.', null, 403);
            }
            
            // Handle file upload
            $filePath = null;
            if ($request->hasFile('submission_file')) {
                $file = $request->file('submission_file');
                // Delete old file if exists and a new file is being uploaded
                if ($existingSubmission && $existingSubmission->submission_file) {
                    Storage::disk('public')->delete($existingSubmission->submission_file);
                }
                $filePath = $file->store('assignments/submissions', 'public');
            } else {
                // Keep existing file if no new file is uploaded
                $filePath = $existingSubmission ? $existingSubmission->submission_file : null;
            }
            
            // Prepare submission text
            // If updating, preserve existing text if new text is not provided
            $submissionText = null;
            if (!empty($validated['submission_text'])) {
                $submissionText = $validated['submission_text'];
            } elseif ($existingSubmission) {
                $submissionText = $existingSubmission->submission_text;
            }
            
            if ($existingSubmission) {
                // Update existing submission
                $existingSubmission->update([
                    'submission_text' => $submissionText,
                    'submission_file' => $filePath,
                    'submitted_at' => now(),
                    'is_late' => $isLate,
                    'status' => 'submitted',
                ]);
                $submission = $existingSubmission;
            } else {
                // Create new submission
                $submission = AssignmentSubmission::create([
                    'assignment_id' => $assignment->id,
                    'student_id' => $user->id,
                    'course_id' => $assignment->course_id,
                    'submission_text' => $submissionText,
                    'submission_file' => $filePath,
                    'submitted_at' => now(),
                    'status' => 'submitted',
                    'is_late' => $isLate,
                ]);
            }
            
            return $this->success([
                'submission_id' => $submission->id,
                'submitted_at' => $submission->submitted_at,
            ], 'Assignment submitted successfully', 201);
        } catch (\Illuminate\Validation\ValidationException $e) {
            return $this->error('Validation failed', $e->errors(), 422);
        } catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
            return $this->error('Assignment not found.', null, 404);
        } catch (\Exception $e) {
            \Illuminate\Support\Facades\Log::error('Student Assignment Submit API error: ' . $e->getMessage());
            return $this->error('An error occurred while submitting assignment.', null, 500);
        }
    }
}

