<?php

namespace App\Http\Controllers\Admin;

use App\Enums\StudyMode;
use App\Http\Controllers\Controller;
use App\Models\Department;
use App\Models\Programme;
use App\Models\School;
use App\Services\AuditLogger;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class ProgrammeAdminController extends Controller
{
    public function __construct(protected AuditLogger $audit) {}

    public function index(Request $request): View
    {
        return view('admin.programmes.index', [
            'programmes' => Programme::query()
                ->with(['school:id,name', 'department:id,name'])
                ->withCount('requirements')
                ->search($request->string('q')->toString() ?: null)
                ->forSchool($request->integer('school') ?: null)
                ->ordered()
                ->paginate(25)
                ->withQueryString(),
            'schools' => School::active()->ordered()->get(['id', 'name']),
            'filters' => $request->only(['q', 'school']),
        ]);
    }

    public function edit(Programme $programme): View
    {
        return view('admin.programmes.edit', [
            'programme' => $programme->load('requirements'),
            'schools' => School::active()->ordered()->get(['id', 'name']),
            'departments' => Department::active()->orderBy('name')->get(['id', 'name', 'school_id']),
            'modes' => StudyMode::options(),
        ]);
    }

    public function update(Request $request, Programme $programme): RedirectResponse
    {
        $data = $request->validate([
            'name' => ['required', 'string', 'max:190'],
            'code' => ['required', 'string', 'max:40', 'unique:programmes,code,'.$programme->id],
            'award' => ['required', 'string', 'max:190'],
            'level' => ['required', 'string', 'max:40'],
            'school_id' => ['required', 'integer', 'exists:schools,id'],
            'department_id' => ['nullable', 'integer', 'exists:departments,id'],
            'description' => ['nullable', 'string', 'max:2000'],
            'overview' => ['nullable', 'string'],
            'career_opportunities' => ['nullable', 'string'],
            'duration' => ['required', 'integer', 'min:1', 'max:10'],
            'duration_unit' => ['required', 'string', 'in:years,semesters,months'],
            'study_modes' => ['nullable', 'array'],
            'study_modes.*' => ['string', 'max:30'],
            'campuses' => ['nullable', 'array'],
            'campuses.*' => ['string', 'max:100'],
            'tuition_amount' => ['nullable', 'numeric', 'min:0'],
            'application_fee' => ['nullable', 'numeric', 'min:0'],
            'status' => ['required', 'string', 'in:active,inactive'],
            'is_featured' => ['nullable', 'boolean'],
        ]);

        $original = $programme->only(array_keys($data));

        $programme->update($data + ['is_featured' => $request->boolean('is_featured')]);

        $this->audit->log(AuditLogger::PROGRAMME_CHANGED, $programme, $original, $programme->getChanges());

        return redirect()->route('admin.programmes.index')
            ->with('status', "{$programme->name} updated.");
    }
}
