<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Student;
use App\Models\Vehicle;
use Illuminate\Http\Request;

/**
 * Transport — cars with their driver details (name, photo, national id, licence,
 * guarantee form فورم ضمانت, car photo) and the students assigned to each car.
 * Opening a car lists its students grouped by shift / pickup time.
 */
class TransportController extends Controller
{
    private array $fields = [
        'branch_id', 'name', 'number_plate', 'capacity', 'status', 'shift', 'area', 'notes',
        'driver_name', 'driver_phone', 'driver_photo', 'driver_national_id', 'driver_license',
        'guarantee_form', 'car_photo',
    ];

    public function index(Request $request)
    {
        $branchId = $request->header('X-Branch-Id') ?: $request->query('branch_id');
        $vehicles = Vehicle::when($branchId, fn ($q) => $q->where('branch_id', $branchId))
            ->orderBy('name')->get()
            ->map(fn ($v) => $this->card($v));

        return response()->json(['data' => $vehicles]);
    }

    public function store(Request $request)
    {
        $data = $request->only($this->fields);
        $data['branch_id'] = $data['branch_id'] ?? ($request->header('X-Branch-Id') ?: null);
        $vehicle = Vehicle::create($data);

        return response()->json($this->card($vehicle), 201);
    }

    public function update(Request $request, $id)
    {
        $vehicle = Vehicle::findOrFail($id);
        $vehicle->update($request->only($this->fields));

        return response()->json($this->card($vehicle->fresh()));
    }

    public function destroy($id)
    {
        Vehicle::findOrFail($id)->delete();

        return response()->json(['ok' => true]);
    }

    /** Full car view: driver details + students grouped by shift and pickup time. */
    public function show($id)
    {
        $vehicle = Vehicle::with(['students' => fn ($q) => $q->orderBy('first_name')])->findOrFail($id);

        $groups = [];
        foreach ($vehicle->students as $s) {
            $shift = $s->pivot->shift ?: ($vehicle->shift ?: 'unset');
            $groups[$shift]['shift'] = $shift;
            $groups[$shift]['students'][] = [
                'id' => $s->id,
                'name' => $s->full_name ?? trim("$s->first_name $s->last_name"),
                'photo' => $s->photo,
                'gender' => $s->gender,
                'class_id' => $s->class_id,
                'pickup_time' => $s->pivot->pickup_time,
                'drop_time' => $s->pivot->drop_time,
                'stop' => $s->pivot->stop,
                'side' => $s->pivot->side,
            ];
        }

        return response()->json([
            'vehicle' => $vehicle->makeHidden(['students']),
            'groups' => array_values($groups),
            'total' => $vehicle->students->count(),
        ]);
    }

    /** Assign a student to this car (idempotent per shift). */
    public function assign(Request $request, $id)
    {
        $vehicle = Vehicle::findOrFail($id);
        $data = $request->validate([
            'student_id' => 'required|exists:students,id',
            'shift' => 'nullable|string',
            'pickup_time' => 'nullable|string',
            'drop_time' => 'nullable|string',
            'stop' => 'nullable|string',
            'side' => 'nullable|string',
        ]);
        $shift = $data['shift'] ?? ($vehicle->shift ?: 'morning');

        // Capacity guard — never seat more students than the car holds. Already
        // assigned students (re-assigns) don't count against a full car.
        if ($vehicle->capacity > 0) {
            $alreadyOn = $vehicle->students()->where('students.id', $data['student_id'])->exists();
            if (! $alreadyOn && $vehicle->students()->count() >= $vehicle->capacity) {
                return response()->json([
                    'ok' => false,
                    'message' => "This car is full ({$vehicle->capacity} seats).",
                ], 422);
            }
        }

        $vehicle->students()->syncWithoutDetaching([
            $data['student_id'] => [
                'shift' => $shift,
                'pickup_time' => $data['pickup_time'] ?? null,
                'drop_time' => $data['drop_time'] ?? null,
                'stop' => $data['stop'] ?? null,
                'side' => $data['side'] ?? null,
            ],
        ]);

        return response()->json(['ok' => true, 'assigned_count' => $vehicle->students()->count()]);
    }

    public function unassign(Request $request, $id)
    {
        $vehicle = Vehicle::findOrFail($id);
        $studentId = $request->query('student_id') ?: $request->input('student_id');
        $vehicle->students()->detach($studentId);

        return response()->json(['ok' => true, 'assigned_count' => $vehicle->students()->count()]);
    }

    /** Students not yet on any car — candidates for assignment. */
    public function unassigned(Request $request)
    {
        $branchId = $request->header('X-Branch-Id') ?: $request->query('branch_id');
        $q = trim((string) $request->query('q', ''));
        $students = Student::where('status', 'active')
            ->when($branchId, fn ($qq) => $qq->where('branch_id', $branchId))
            ->when($q !== '', fn ($qq) => $qq->where(fn ($w) => $w
                ->where('first_name', 'like', "%$q%")
                ->orWhere('last_name', 'like', "%$q%")
                ->orWhere('admission_number', 'like', "%$q%")))
            ->orderBy('first_name')->limit(40)
            ->get(['id', 'first_name', 'last_name', 'photo', 'gender', 'class_id', 'shift'])
            ->map(fn ($s) => [
                'id' => $s->id,
                'name' => trim("$s->first_name $s->last_name"),
                'photo' => $s->photo,
                'gender' => $s->gender,
                'shift' => $s->shift,
            ]);

        return response()->json(['data' => $students]);
    }

    private function card(Vehicle $v): array
    {
        return [
            'id' => $v->id,
            'name' => $v->name,
            'number_plate' => $v->number_plate,
            'capacity' => (int) $v->capacity,
            'status' => $v->status,
            'shift' => $v->shift,
            'area' => $v->area,
            'notes' => $v->notes,
            'driver_name' => $v->driver_name,
            'driver_phone' => $v->driver_phone,
            'driver_photo' => $v->driver_photo,
            'driver_national_id' => $v->driver_national_id,
            'driver_license' => $v->driver_license,
            'guarantee_form' => $v->guarantee_form,
            'car_photo' => $v->car_photo,
            'assigned_count' => $v->students()->count(),
        ];
    }
}
