<?php

namespace App\Http\Controllers;

use App\Models\Course;
use App\Models\Category;
use App\Services\UserCourseStatusService;
use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Auth;

class CourseController extends Controller
{
    protected UserCourseStatusService $userCourseStatusService;

    public function __construct(UserCourseStatusService $userCourseStatusService)
    {
        $this->userCourseStatusService = $userCourseStatusService;

        // You can adjust permission names to your DB
        $this->middleware('permission:courses view',   ['only' => ['index','show']]);
        $this->middleware('permission:courses create', ['only' => ['create','store']]);
        $this->middleware('permission:courses update', ['only' => ['edit','update','approve','reject']]);
        $this->middleware('permission:courses delete', ['only' => ['destroy']]);
    }

    /**
     * Master Admin: all courses
     * Teacher: only own courses
     */
    public function index()
    {
        $user = Auth::user();

        $query = Course::with(['category', 'teacher'])->latest();

        if ($user->hasRole('teacher')) {
            $query->where('teacher_id', $user->id);
        }

        $courses = $query->get();

        audit_log(
            'courses',
            null,
            'listed',
            'Courses list viewed',
            ['count' => $courses->count()]
        );

        return view('courses.index', compact('courses'));
    }

    public function create()
    {
        // Teacher will select category; CRUD of categories is admin only
        $categories = Category::orderBy('name')->get();

         $teachers = User::role('teacher')
        ->select('id','name')
        ->orderBy('name')
        ->get();

        audit_log(
            'courses',
            null,
            'create_form',
            'Course create form opened',
            []
        );

        return view('courses.create', compact('categories','teachers'));
    }

    public function store(Request $request)
    {
        $user = Auth::user();
        
        // Teacher only creates as pending
        $validated = $request->validate([
            'teacher_id' =>'required',
            'title'       => ['required', 'string', 'max:255'],
            'description' => ['nullable', 'string'],
            'category_id' => ['required', 'exists:categories,id'],
            'status' => 'required|in:pending,approved,rejected',
            'start_date' => ['required', 'date'],
            'expire_date' => ['required', 'date', 'after_or_equal:start_date'],
        ]);

        $course = Course::create([
            'title'       => $validated['title'],
            'description' => $validated['description'] ?? null,
            'category_id' => $validated['category_id'],
            'teacher_id'  => $validated['teacher_id'],
            'status'      => $validated['status'],
            'start_date'  => $validated['start_date'],
            'expire_date' => $validated['expire_date'],
        ]);

        $this->userCourseStatusService->syncCourseParticipants($course);

        audit_log(
            'courses',
            $course->id,
            'created',
            'Course created successfully (pending)',
            $course->toArray()
        );

        return redirect()
            ->route('courses.index')
            ->with('success', 'Course created successfully and sent for approval.');
    }

    public function show(Course $course)
    {
        $this->authorizeCourseAccess($course);

        $course->load(['category', 'teacher']);

        audit_log(
            'courses',
            $course->id,
            'viewed',
            'Course viewed successfully',
            $course->toArray()
        );

        return view('courses.show', compact('course'));
    }

    public function edit(Course $course)
    {
        $this->authorizeCourseAccess($course);

        $categories = Category::orderBy('name')->get();

        $teachers = User::role('teacher')
        ->select('id','name')
        ->orderBy('name')
        ->get();

        audit_log(
            'courses',
            $course->id,
            'edit_form',
            'Course edit form opened',
            $course->toArray()
        );

        return view('courses.edit', compact('course', 'categories','teachers'));
    }

    public function update(Request $request, Course $course)
    {
        $this->authorizeCourseAccess($course);

        $validated = $request->validate([
             'teacher_id' =>'required',
            'title'       => ['required', 'string', 'max:255'],
            'description' => ['nullable', 'string'],
            'category_id' => ['required', 'exists:categories,id'],
            'status' => 'required|in:pending,approved,rejected',
            'start_date' => ['required', 'date'],
            'expire_date' => ['required', 'date', 'after_or_equal:start_date'],
        ]);

        $before = $course->toArray();
        $previousTeacherId = $course->teacher_id;

        $course->update([
             'teacher_id'  => $validated['teacher_id'],
            'title'       => $validated['title'],
            'description' => $validated['description'] ?? null,
            'category_id' => $validated['category_id'],
             'status' => $validated['status'],
            'start_date'  => $validated['start_date'],
            'expire_date' => $validated['expire_date'],
        ]);

        $this->userCourseStatusService->syncCourseParticipants($course->fresh(), [$previousTeacherId]);

        audit_log(
            'courses',
            $course->id,
            'updated',
            'Course updated successfully',
            [
                'before' => $before,
                'after'  => $course->fresh()->toArray(),
            ]
        );

        return redirect()
            ->route('courses.index')
            ->with('success', 'Course updated successfully.');
    }

    public function destroy(Course $course)
    {
        $this->authorizeCourseAccess($course);

        $data = $course->toArray();
        $id = $course->id;
        $participantIds = $course->enrollments()->pluck('student_id')->push($course->teacher_id)->all();

        $course->delete();

        $this->userCourseStatusService->syncUsersByIds($participantIds);

        audit_log(
            'courses',
            $id,
            'deleted',
            'Course deleted successfully',
            $data
        );

        return redirect()
            ->route('courses.index')
            ->with('success', 'Course deleted successfully.');
    }

    /**
     * Master Admin: approve
     */
    public function approve(Course $course)
    {
        if (!Auth::user()->hasRole('master-admin')) {
            abort(403);
        }

        $before = $course->toArray();

        $course->update(['status' => 'approved']);

        audit_log(
            'courses',
            $course->id,
            'approved',
            'Course approved',
            ['before' => $before, 'after' => $course->fresh()->toArray()]
        );

        return back()->with('success', 'Course approved.');
    }

    /**
     * Master Admin: reject
     */
    public function reject(Course $course)
    {
        if (!Auth::user()->hasRole('master-admin')) {
            abort(403);
        }

        $before = $course->toArray();

        $course->update(['status' => 'rejected']);

        audit_log(
            'courses',
            $course->id,
            'rejected',
            'Course rejected',
            ['before' => $before, 'after' => $course->fresh()->toArray()]
        );

        return back()->with('success', 'Course rejected.');
    }

    /**
     * Teacher can only access own course.
     * Master admin can access all.
     */
    private function authorizeCourseAccess(Course $course): void
    {
        $user = Auth::user();

        if ($user->hasRole('master-admin')) {
            return;
        }

        if ($user->hasRole('teacher') && $course->teacher_id === $user->id) {
            return;
        }

        // abort(403);
    }
}
