<?php

namespace App\Http\Controllers\Mentorship;

use App\Http\Controllers\Controller;
use App\Models\Mentorship\Programme;
use App\Models\Mentorship\Category;
use App\Models\Mentorship\Application;
use App\Services\Mentorship\ProgrammeService;
use App\Services\Mentorship\RegistrationService;
use App\Http\Requests\Mentorship\ApplicationRequest;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;

class PublicController extends Controller
{
    protected ProgrammeService $programmeService;
    protected RegistrationService $registrationService;

    public function __construct(
        ProgrammeService $programmeService,
        RegistrationService $registrationService
    ) {
        $this->programmeService = $programmeService;
        $this->registrationService = $registrationService;
    }

    /**
     * Display the public mentorship page.
     */
    public function index(Request $request)
    {
        // Get active categories
        $categories = Category::active()
            ->withCount(['activeProgrammes'])
            ->ordered()
            ->get();

        // Get featured programmes
        $featuredProgrammes = $this->programmeService->getFeatured(6);

        // Get all active programmes with filtering
        $filters = [
            'category_id' => $request->get('category'),
            'search' => $request->get('search'),
            'is_free' => $request->get('is_free'),
        ];

        $programmes = Programme::with(['category'])
            ->active()
            ->openForRegistration()
            ->when($filters['category_id'], fn($q) => $q->where('category_id', $filters['category_id']))
            ->when($filters['search'], function ($q) use ($filters) {
                $q->where('title', 'like', '%' . $filters['search'] . '%')
                    ->orWhere('description', 'like', '%' . $filters['search'] . '%');
            })
            ->when(isset($filters['is_free']), fn($q) => $q->where('is_free', $filters['is_free']))
            ->orderBy('is_featured', 'desc')
            ->orderBy('created_at', 'desc')
            ->paginate(12);

        return view('mentorship.public.index', compact('categories', 'programmes', 'featuredProgrammes', 'filters'));
    }

    /**
     * Display a specific programme.
     */
    public function programme(Programme $programme)
    {
        if (!$programme->is_active) {
            abort(404);
        }

        $programme->load(['category']);

        // Check if user can apply
        $canApply = $programme->canApply(auth()->user());

        // Get related programmes
        $relatedProgrammes = Programme::active()
            ->where('id', '!=', $programme->id)
            ->when($programme->category_id, fn($q) => $q->where('category_id', $programme->category_id))
            ->limit(4)
            ->get();

        return view('mentorship.public.programme', compact('programme', 'canApply', 'relatedProgrammes'));
    }

    /**
     * Show the application form.
     */
    public function apply(Request $request)
    {
        $programmeId = $request->get('programme_id');
        $programme = $programmeId ? Programme::active()->find($programmeId) : null;

        if (!$programme) {
            return redirect()->route('mentorship.public.index')
                ->withErrors(['error' => 'Please select a programme to apply.']);
        }

        if (!$programme->canApply(auth()->user())) {
            return redirect()->route('mentorship.public.programme', $programme)
                ->withErrors(['error' => 'This programme is not accepting applications at this time.']);
        }

        $categories = Category::active()->ordered()->get();

        return view('mentorship.public.apply', compact('programme', 'categories'));
    }

    /**
     * Store a new application.
     */
    public function submitApplication(ApplicationRequest $request)
    {
        try {
            $application = $this->registrationService->submitApplication($request->validated());

            // If payment is required, redirect to payment page
            if ($application->payment_required) {
                return redirect()
                    ->route('mentorship.payments.create', ['application_id' => $application->id])
                    ->with('success', 'Application submitted! Please complete payment to proceed.');
            }

            return redirect()
                ->route('mentorship.public.status', $application)
                ->with('success', 'Application submitted successfully! We will review and get back to you.');
        } catch (\Exception $e) {
            return back()
                ->withInput()
                ->withErrors(['error' => $e->getMessage()]);
        }
    }

    /**
     * Display application status.
     */
    public function status(Application $application)
    {
        // Allow viewing if the user is the applicant (by email) or an admin
        $canView = auth()->user()?->can('view mentorship applications') ||
            $application->email === auth()->user()?->email ||
            session('application_email') === $application->email;

        if (!$canView) {
            // Store email in session for verification
            if (request()->has('email') && request()->email === $application->email) {
                session(['application_email' => $application->email]);
            } else {
                return view('mentorship.public.verify-status', compact('application'));
            }
        }

        $application->load(['programme', 'category', 'payments']);

        return view('mentorship.public.status', compact('application'));
    }

    /**
     * Show the check-status form page (GET).
     */
    public function checkStatusForm()
    {
        return view('mentorship.public.check-status');
    }

    /**
     * Check application status by email.
     */
    public function checkStatus(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
        ]);

        $applications = Application::with(['programme', 'category'])
            ->where('email', $request->email)
            ->orderBy('created_at', 'desc')
            ->get();

        if ($applications->isEmpty()) {
            return back()->withErrors(['email' => 'No applications found with this email address.']);
        }

        session(['application_email' => $request->email]);

        return view('mentorship.public.applications', compact('applications'));
    }

    /**
     * Get programmes by category (AJAX).
     */
    public function getByCategory(Category $category): JsonResponse
    {
        $programmes = $this->programmeService->getByCategory($category);

        return response()->json([
            'success' => true,
            'data' => $programmes,
        ]);
    }

    /**
     * Search programmes (AJAX).
     */
    public function search(Request $request): JsonResponse
    {
        $query = $request->get('q', '');
        $categoryId = $request->get('category_id');
        $isFree = $request->get('is_free');
        $sessionType = $request->get('session_type');

        $programmes = Programme::with(['category'])
            ->active()
            ->when($query, function ($q) use ($query) {
                $q->where(function ($inner) use ($query) {
                    $inner->where('title', 'like', '%' . $query . '%')
                        ->orWhere('description', 'like', '%' . $query . '%')
                        ->orWhere('objectives', 'like', '%' . $query . '%');
                });
            })
            ->when($categoryId, fn($q) => $q->where('category_id', $categoryId))
            ->when($isFree !== null && $isFree !== '', fn($q) => $q->where('is_free', (bool) $isFree))
            ->when($sessionType, fn($q) => $q->where('session_type', $sessionType))
            ->orderBy('is_featured', 'desc')
            ->limit(20)
            ->get()
            ->map(function ($programme) {
                return [
                    'id'                 => $programme->id,
                    'title'              => $programme->title,
                    'description'        => \Illuminate\Support\Str::limit(strip_tags($programme->description), 120),
                    'category'           => $programme->category?->name ?? 'General',
                    'is_free'            => $programme->is_free,
                    'fee_amount'         => $programme->fee_amount,
                    'formatted_fee'      => $programme->formatted_fee ?? number_format($programme->fee_amount, 0) . ' ' . $programme->currency,
                    'currency'           => $programme->currency,
                    'duration_text'      => $programme->duration_text,
                    'session_type'       => $programme->session_type,
                    'session_type_label' => ucfirst(str_replace('_', ' ', $programme->session_type)),
                    'url'                => route('mentorship.public.programme', $programme),
                    'apply_url'          => route('mentorship.public.apply', ['programme_id' => $programme->id]),
                ];
            });

        return response()->json([
            'success' => true,
            'data' => $programmes,
        ]);
    }

    /**
     * Get programme details (AJAX).
     */
    public function getProgrammeDetails(Programme $programme): JsonResponse
    {
        $programme->load(['category']);

        return response()->json([
            'success' => true,
            'data' => [
                'id' => $programme->id,
                'title' => $programme->title,
                'description' => $programme->description,
                'is_free' => $programme->is_free,
                'fee_amount' => $programme->fee_amount,
                'formatted_fee' => $programme->formatted_fee,
                'currency' => $programme->currency,
                'duration_text' => $programme->duration_text,
                'sessions_count' => $programme->sessions_count,
                'programme_type' => $programme->programme_type,
                'session_type' => $programme->session_type,
                'category' => $programme->category?->name,
                'can_apply' => $programme->canApply(auth()->user()),
            ],
        ]);
    }

    /**
     * Get categories for filter (AJAX).
     */
    public function getCategories(): JsonResponse
    {
        $categories = Category::active()
            ->withCount(['activeProgrammes'])
            ->ordered()
            ->get();

        return response()->json([
            'success' => true,
            'data' => $categories,
        ]);
    }

    /**
     * Display mentorship programmes in a specific category.
     */
    public function category(Category $category)
    {
        if (!$category->is_active) {
            abort(404);
        }

        $programmes = Programme::active()
            ->openForRegistration()
            ->where('category_id', $category->id)
            ->orderBy('is_featured', 'desc')
            ->orderBy('created_at', 'desc')
            ->paginate(12);

        $categories = Category::active()
            ->withCount(['activeProgrammes'])
            ->ordered()
            ->get();

        return view('mentorship.public.category', compact('category', 'programmes', 'categories'));
    }
}
