<?php

namespace App\Http\Controllers\SelfPaced\Dashboard;

use App\Http\Controllers\Controller;
use App\Models\SelfPaced\Course;
use App\Models\SelfPaced\Enrollment;
use App\Models\User;
use App\Services\SelfPacedService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Response;

class EnrollmentController extends Controller
{
    public function __construct(protected SelfPacedService $selfPacedService)
    {
        //
    }

    // =========================================================================
    // LIST
    // =========================================================================

    public function index(Request $request)
    {
        $query = Enrollment::with(['user', 'course']);

        // Real-time search by trainee name, email, or course title
        if ($search = $request->get('search')) {
            $query->where(function ($q) use ($search) {
                $q->whereHas('user', fn ($u) => $u->where('name', 'like', "%{$search}%")
                                                   ->orWhere('email', 'like', "%{$search}%"))
                  ->orWhereHas('course', fn ($c) => $c->where('title', 'like', "%{$search}%"))
                  ->orWhere('payment_reference', 'like', "%{$search}%");
            });
        }

        // Filter by status
        if ($status = $request->get('status')) {
            $query->where('status', $status);
        }

        // Filter by course
        if ($courseId = $request->get('course_id')) {
            $query->where('course_id', $courseId);
        }

        // Filter by date range
        if ($from = $request->get('date_from')) {
            $query->whereDate('created_at', '>=', $from);
        }
        if ($to = $request->get('date_to')) {
            $query->whereDate('created_at', '<=', $to);
        }

        $enrollments = $query->latest()->paginate(20)->withQueryString();
        $courses     = Course::orderBy('title')->get(['id', 'title']);

        if ($request->ajax()) {
            return response()->json([
                'html' => view('self-paced.dashboard.enrollments.partials.table', compact('enrollments'))->render(),
            ]);
        }

        return view('self-paced.dashboard.enrollments.index', compact('enrollments', 'courses'));
    }

    // =========================================================================
    // DETAIL
    // =========================================================================

    public function show(Enrollment $enrollment)
    {
        $enrollment->load([
            'user',
            'course.topics',
            'examAttempts.result',
            'learningProgress',
            'topicTimers.topic',
            'certificate',
        ]);

        $progressPercentage = $enrollment->getProgressPercentage();
        $remainingAttempts  = $enrollment->getRemainingAttempts();
        $passedResult       = $enrollment->getPassedResult();

        return view('self-paced.dashboard.enrollments.show', compact(
            'enrollment',
            'progressPercentage',
            'remainingAttempts',
            'passedResult'
        ));
    }

    // =========================================================================
    // MANUAL ENROLLMENT (admin override / free course)
    // =========================================================================

    public function create()
    {
        $courses = Course::published()->orderBy('title')->get(['id', 'title', 'fee_amount', 'currency']);
        $users   = User::orderBy('name')->get(['id', 'name', 'email']);

        return view('self-paced.dashboard.enrollments.create', compact('courses', 'users'));
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'user_id'   => 'required|exists:users,id',
            'course_id' => 'required|exists:self_paced_courses,id',
        ]);

        $course = Course::findOrFail($validated['course_id']);

        try {
            $result = $this->selfPacedService->createEnrollment(
                userId: (int) $validated['user_id'],
                course: $course,
                phoneNumber: '',
                createdBy: Auth::id()
            );
        } catch (\RuntimeException $e) {
            return back()->withErrors(['user_id' => $e->getMessage()])->withInput();
        }

        $enrollment = $result['enrollment'];

        return redirect()
            ->route('self-paced.dashboard.enrollments.show', $enrollment)
            ->with('success', 'Enrollment created successfully.');
    }

    // =========================================================================
    // STATUS ACTIONS
    // =========================================================================

    /**
     * Manually activate a pending/failed enrollment (admin override).
     */
    public function activate(Enrollment $enrollment)
    {
        if ($enrollment->canAccess()) {
            return back()->with('info', 'Enrollment is already active or completed.');
        }

        $enrollment->update([
            'status'      => 'active',
            'enrolled_at' => $enrollment->enrolled_at ?? now(),
        ]);

        return back()->with('success', 'Enrollment activated successfully.');
    }

    /**
     * Cancel an enrollment.
     */
    public function cancel(Request $request, Enrollment $enrollment)
    {
        if ($enrollment->isCompleted()) {
            return back()->with('error', 'Cannot cancel a completed enrollment.');
        }

        $enrollment->update(['status' => 'cancelled']);

        if ($request->ajax()) {
            return response()->json(['success' => true, 'message' => 'Enrollment cancelled.']);
        }

        return back()->with('success', 'Enrollment cancelled.');
    }

    // =========================================================================
    // PAYMENT STATUS CHECK
    // =========================================================================

    public function checkPayment(Enrollment $enrollment)
    {
        $enrollment = $this->selfPacedService->checkPaymentStatus($enrollment);

        return back()->with('success', "Payment status refreshed. Current status: {$enrollment->status}");
    }

    // =========================================================================
    // EXPORT
    // =========================================================================

    public function export(Request $request)
    {
        $query = Enrollment::with(['user', 'course']);

        if ($status = $request->get('status')) {
            $query->where('status', $status);
        }
        if ($courseId = $request->get('course_id')) {
            $query->where('course_id', $courseId);
        }
        if ($from = $request->get('date_from')) {
            $query->whereDate('created_at', '>=', $from);
        }
        if ($to = $request->get('date_to')) {
            $query->whereDate('created_at', '<=', $to);
        }

        $enrollments = $query->latest()->get();
        $filename    = 'enrollments-' . now()->format('Y-m-d') . '.csv';

        $headers = [
            'Content-Type'        => 'text/csv',
            'Content-Disposition' => "attachment; filename=\"{$filename}\"",
        ];

        $callback = function () use ($enrollments) {
            $handle = fopen('php://output', 'w');

            fputcsv($handle, [
                'ID', 'Trainee Name', 'Trainee Email', 'Course', 'Status',
                'Payment Reference', 'Payment Method', 'Amount Paid', 'Currency',
                'Payment Date', 'Enrolled At', 'Completed At', 'Created At',
            ]);

            foreach ($enrollments as $e) {
                fputcsv($handle, [
                    $e->id,
                    $e->user->name ?? 'N/A',
                    $e->user->email ?? 'N/A',
                    $e->course->title ?? 'N/A',
                    $e->status,
                    $e->payment_reference ?? '',
                    $e->payment_method,
                    number_format((float) $e->amount_paid, 2),
                    $e->course->currency ?? 'UGX',
                    $e->payment_date?->format('Y-m-d H:i:s') ?? '',
                    $e->enrolled_at?->format('Y-m-d H:i:s') ?? '',
                    $e->completed_at?->format('Y-m-d H:i:s') ?? '',
                    $e->created_at->format('Y-m-d H:i:s'),
                ]);
            }

            fclose($handle);
        };

        return Response::stream($callback, 200, $headers);
    }
}
