<?php

namespace App\Http\Controllers\Training;

use App\Http\Controllers\Controller;
use App\Models\TrainingPackage;
use App\Models\TrainingCategory;
use App\Services\TrainingService;
use App\Http\Requests\Training\StoreTrainingPackageRequest;
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Storage;
use Illuminate\View\View;

/**
 * TrainingController
 *
 * Handles training package management for authenticated users.
 *
 * @package App\Http\Controllers\Training
 */
class TrainingController extends Controller
{
    /**
     * TrainingService instance.
     *
     * @var \App\Services\TrainingService
     */
    protected TrainingService $trainingService;

    /**
     * Create a new TrainingController instance.
     *
     * @param \App\Services\TrainingService $trainingService
     */
    public function __construct(TrainingService $trainingService)
    {
        $this->trainingService = $trainingService;
    }

    /**
     * Display a listing of training packages.
     *
     * @return \Illuminate\View\View
     */
    public function index(): View
    {
        abort_unless(auth()->user()->can('view training packages'), 403);
        
        $packages = TrainingPackage::with(['category', 'creator'])
            ->withCount(['sessions', 'registrations'])
            ->when(request('search'), function ($query, $search) {
                $query->where('name', 'like', "%{$search}%");
            })
            ->when(request('status'), function ($query, $status) {
                $query->where('status', $status);
            })
            ->when(request('category'), function ($query, $categoryId) {
                $query->where('category_id', $categoryId);
            })
            ->latest()
            ->paginate(15);
        
        $categories = TrainingCategory::active()->ordered()->get();
        
        $statistics = $this->getStatistics();
        
        return view('training.packages.index', compact('packages', 'categories', 'statistics'));
    }

    /**
     * Show the form for creating a new training package.
     *
     * @return \Illuminate\View\View
     */
    public function create(): View
    {
        abort_unless(auth()->user()->can('create training packages'), 403);
        
        $categories = TrainingCategory::active()->ordered()->get();
        
        return view('training.packages.create', compact('categories'));
    }

    /**
     * Store a newly created training package.
     *
     * @param \App\Http\Requests\Training\StoreTrainingPackageRequest $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function store(StoreTrainingPackageRequest $request): RedirectResponse
    {
        try {
            $package = $this->trainingService->createPackage($request->validated());
            
            // Handle file upload
            if ($request->hasFile('featured_image')) {
                $path = $request->file('featured_image')->store('training/packages', 'public');
                $package->update(['featured_image' => $path]);
            }
            
            return redirect()
                ->route('training.packages.show', $package)
                ->with('success', 'Training package created successfully!');
                
        } catch (\Exception $e) {
            return back()
                ->withInput()
                ->with('error', 'Failed to create training package: ' . $e->getMessage());
        }
    }

    /**
     * Display the specified training package.
     *
     * @param \App\Models\TrainingPackage $package
     * @return \Illuminate\View\View
     */
    public function show(TrainingPackage $package): View
    {
        abort_unless(auth()->user()->can('view training packages'), 403);
        
        $package->load([
            'category',
            'creator',
            'sessions' => function ($query) {
                $query->with(['trainers'])->orderBy('session_date')->orderBy('start_time');
            },
        ]);
        
        $registrations = $package->registrations()
            ->with('user')
            ->latest()
            ->paginate(10, ['*'], 'registrations');
        
        return view('training.packages.show', compact('package', 'registrations'));
    }

    /**
     * Show the form for editing the specified training package.
     *
     * @param \App\Models\TrainingPackage $package
     * @return \Illuminate\View\View
     */
    public function edit(TrainingPackage $package): View
    {
        abort_unless(auth()->user()->can('edit training packages'), 403);
        
        $categories = TrainingCategory::active()->ordered()->get();
        
        return view('training.packages.edit', compact('package', 'categories'));
    }

    /**
     * Update the specified training package.
     *
     * @param \App\Http\Requests\Training\StoreTrainingPackageRequest $request
     * @param \App\Models\TrainingPackage $package
     * @return \Illuminate\Http\RedirectResponse
     */
    public function update(StoreTrainingPackageRequest $request, TrainingPackage $package): RedirectResponse
    {
        try {
            $this->trainingService->updatePackage($package, $request->validated());
            
            // Handle file upload
            if ($request->hasFile('featured_image')) {
                // Delete old image if it exists
                if ($package->featured_image) {
                    \Storage::disk('public')->delete($package->featured_image);
                }
                $path = $request->file('featured_image')->store('training/packages', 'public');
                $package->update(['featured_image' => $path]);
            }
            
            return redirect()
                ->route('training.packages.show', $package)
                ->with('success', 'Training package updated successfully!');
                
        } catch (\Exception $e) {
            return back()
                ->withInput()
                ->with('error', 'Failed to update training package: ' . $e->getMessage());
        }
    }

    /**
     * Remove the specified training package.
     *
     * @param \App\Models\TrainingPackage $package
     * @return \Illuminate\Http\RedirectResponse
     */
    public function destroy(TrainingPackage $package): RedirectResponse
    {
        abort_unless(auth()->user()->can('delete training packages'), 403);
        
        try {
            $this->trainingService->deletePackage($package);
            
            return redirect()
                ->route('training.packages.index')
                ->with('success', 'Training package deleted successfully!');
                
        } catch (\Exception $e) {
            return back()
                ->with('error', 'Failed to delete training package: ' . $e->getMessage());
        }
    }

    /**
     * Activate the specified training package.
     *
     * @param \App\Models\TrainingPackage $package
     * @return \Illuminate\Http\RedirectResponse
     */
    public function activate(TrainingPackage $package): RedirectResponse
    {
        abort_unless(auth()->user()->can('edit training packages'), 403);
        
        $package->activate();
        
        return back()->with('success', 'Training package activated successfully!');
    }

    /**
     * Deactivate the specified training package.
     *
     * @param \App\Models\TrainingPackage $package
     * @return \Illuminate\Http\RedirectResponse
     */
    public function deactivate(TrainingPackage $package): RedirectResponse
    {
        abort_unless(auth()->user()->can('edit training packages'), 403);
        
        $package->deactivate();
        
        return back()->with('success', 'Training package deactivated successfully!');
    }

    /**
     * API endpoint: get statistics for a specific package.
     *
     * @param \App\Models\TrainingPackage $package
     * @return \Illuminate\Http\JsonResponse
     */
    public function apiStats(TrainingPackage $package): \Illuminate\Http\JsonResponse
    {
        abort_unless(auth()->user()->can('view training packages'), 403);

        return response()->json([
            'total_registrations'  => $package->registrations()->count(),
            'pending'              => $package->registrations()->where('status', 'pending')->count(),
            'approved'             => $package->registrations()->where('status', 'approved')->count(),
            'completed'            => $package->registrations()->where('status', 'completed')->count(),
            'capacity_remaining'   => $package->getRemainingCapacity(),
            'sessions_count'       => $package->sessions()->count(),
            'upcoming_sessions'    => $package->sessions()->where('session_date', '>=', now()->toDateString())->where('status', 'scheduled')->count(),
        ]);
    }

    /**
     * Get statistics for the dashboard.
     *
     * @return array
     */
    protected function getStatistics(): array
    {
        return [
            'total' => TrainingPackage::count(),
            'active' => TrainingPackage::active()->count(),
            'draft' => TrainingPackage::where('status', 'draft')->count(),
            'inactive' => TrainingPackage::where('status', 'inactive')->count(),
            'free' => TrainingPackage::free()->count(),
            'paid' => TrainingPackage::paid()->count(),
        ];
    }
}
