<?php

namespace App\Http\Controllers\Mentorship;

use App\Http\Controllers\Controller;
use App\Models\Mentorship\Programme;
use App\Models\Mentorship\Category;
use App\Services\Mentorship\ProgrammeService;
use App\Http\Requests\Mentorship\ProgrammeRequest;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;

class ProgrammeController extends Controller
{
    protected ProgrammeService $programmeService;

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

    /**
     * Display a listing of programmes.
     */
    public function index(Request $request)
    {
        abort_unless(auth()->user()->can('view mentorship programmes'), 403);

        $filters = [
            'is_active' => $request->get('is_active'),
            'is_featured' => $request->get('is_featured'),
            'is_free' => $request->get('is_free'),
            'category_id' => $request->get('category_id'),
            'programme_type' => $request->get('programme_type'),
            'session_type' => $request->get('session_type'),
            'search' => $request->get('search'),
            'sort_by' => $request->get('sort_by', 'created_at'),
            'sort_order' => $request->get('sort_order', 'desc'),
        ];

        $programmes = $this->programmeService->getPaginated($filters);

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

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

    /**
     * Show the form for creating a new programme.
     */
    public function create()
    {
        abort_unless(auth()->user()->can('create mentorship programmes'), 403);

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

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

    /**
     * Store a newly created programme.
     */
    public function store(ProgrammeRequest $request)
    {
        abort_unless(auth()->user()->can('create mentorship programmes'), 403);

        try {
            $programme = $this->programmeService->create($request->validated());

            return redirect()
                ->route('mentorship.programmes.show', $programme)
                ->with('success', 'Programme created successfully.');
        } catch (\Exception $e) {
            return back()
                ->withInput()
                ->withErrors(['error' => $e->getMessage()]);
        }
    }

    /**
     * Display the specified programme.
     */
    public function show(Programme $programme)
    {
        abort_unless(auth()->user()->can('view mentorship programmes'), 403);

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

        $statistics = $this->programmeService->getStatistics($programme);

        // Get recent applications
        $recentApplications = $programme->applications()
            ->latest()
            ->limit(10)
            ->get();

        // Get active assignments
        $activeAssignments = $programme->assignments()
            ->active()
            ->with(['mentor', 'mentee'])
            ->latest()
            ->limit(10)
            ->get();

        return view('mentorship.programmes.show', compact(
            'programme',
            'statistics',
            'recentApplications',
            'activeAssignments'
        ));
    }

    /**
     * Show the form for editing the specified programme.
     */
    public function edit(Programme $programme)
    {
        abort_unless(auth()->user()->can('edit mentorship programmes'), 403);

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

        return view('mentorship.programmes.edit', compact('programme', 'categories'));
    }

    /**
     * Update the specified programme.
     */
    public function update(ProgrammeRequest $request, Programme $programme)
    {
        abort_unless(auth()->user()->can('edit mentorship programmes'), 403);

        try {
            $this->programmeService->update($programme, $request->validated());

            return redirect()
                ->route('mentorship.programmes.show', $programme)
                ->with('success', 'Programme updated successfully.');
        } catch (\Exception $e) {
            return back()
                ->withInput()
                ->withErrors(['error' => $e->getMessage()]);
        }
    }

    /**
     * Remove the specified programme.
     */
    public function destroy(Programme $programme)
    {
        abort_unless(auth()->user()->can('delete mentorship programmes'), 403);

        try {
            $this->programmeService->delete($programme);

            return redirect()
                ->route('mentorship.programmes.index')
                ->with('success', 'Programme deleted successfully.');
        } catch (\Exception $e) {
            return back()->withErrors(['error' => $e->getMessage()]);
        }
    }

    /**
     * Activate a programme.
     */
    public function activate(Programme $programme): JsonResponse
    {
        abort_unless(auth()->user()->can('edit mentorship programmes'), 403);

        $this->programmeService->activate($programme);

        return response()->json([
            'success' => true,
            'message' => 'Programme activated successfully.',
        ]);
    }

    /**
     * Deactivate a programme.
     */
    public function deactivate(Programme $programme): JsonResponse
    {
        abort_unless(auth()->user()->can('edit mentorship programmes'), 403);

        $this->programmeService->deactivate($programme);

        return response()->json([
            'success' => true,
            'message' => 'Programme deactivated successfully.',
        ]);
    }

    /**
     * Feature a programme.
     */
    public function feature(Programme $programme): JsonResponse
    {
        abort_unless(auth()->user()->can('edit mentorship programmes'), 403);

        $this->programmeService->feature($programme);

        return response()->json([
            'success' => true,
            'message' => 'Programme featured successfully.',
        ]);
    }

    /**
     * Unfeature a programme.
     */
    public function unfeature(Programme $programme): JsonResponse
    {
        abort_unless(auth()->user()->can('edit mentorship programmes'), 403);

        $this->programmeService->unfeature($programme);

        return response()->json([
            'success' => true,
            'message' => 'Programme unfeatured successfully.',
        ]);
    }

    /**
     * Get programme statistics (AJAX).
     */
    public function statistics(Programme $programme): JsonResponse
    {
        abort_unless(auth()->user()->can('view mentorship programmes'), 403);

        $statistics = $this->programmeService->getStatistics($programme);

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

    /**
     * Get programmes for select dropdown (AJAX).
     */
    public function getForSelect(Request $request): JsonResponse
    {
        $query = Programme::active();

        if ($request->has('category_id')) {
            $query->where('category_id', $request->category_id);
        }

        if ($request->has('open_for_registration')) {
            $query->openForRegistration();
        }

        $programmes = $query->orderBy('title')->get(['id', 'title', 'is_free', 'fee_amount', 'currency']);

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

    /**
     * Duplicate a programme.
     */
    public function duplicate(Programme $programme)
    {
        abort_unless(auth()->user()->can('create mentorship programmes'), 403);

        DB::beginTransaction();
        try {
            $newProgramme = $programme->replicate();
            $newProgramme->title = $programme->title . ' (Copy)';
            $newProgramme->slug = null;
            $newProgramme->is_active = false;
            $newProgramme->is_featured = false;
            $newProgramme->applications_count = 0;
            $newProgramme->assignments_count = 0;
            $newProgramme->completions_count = 0;
            $newProgramme->created_by = auth()->id();
            $newProgramme->save();

            DB::commit();

            return redirect()
                ->route('mentorship.programmes.edit', $newProgramme)
                ->with('success', 'Programme duplicated successfully. Please review and activate.');
        } catch (\Exception $e) {
            DB::rollBack();
            return back()->withErrors(['error' => $e->getMessage()]);
        }
    }
}
