<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;

/**
 * Token authentication for the mobile app (Laravel Sanctum personal access tokens).
 */
class AuthController extends Controller
{
    /** POST /api/login — exchange credentials for a bearer token. */
    public function login(Request $request): JsonResponse
    {
        $data = $request->validate([
            'email' => ['required', 'email'],
            'password' => ['required', 'string'],
            'device_name' => ['nullable', 'string', 'max:120'],
        ]);

        $user = User::where('email', $data['email'])->first();

        if (! $user || ! Hash::check($data['password'], $user->password) || ! $user->is_active) {
            throw ValidationException::withMessages([
                'email' => ['These credentials do not match our records.'],
            ]);
        }

        // Every active user with a role may sign in (parents, students and staff).
        if ($user->getRoleNames()->isEmpty()) {
            throw ValidationException::withMessages([
                'email' => ['Your account has no role assigned. Please contact the school.'],
            ]);
        }

        $user->forceFill(['last_login_at' => now()])->saveQuietly();

        $device = $data['device_name'] ?? 'mobile';
        $token = $user->createToken($device)->plainTextToken;

        return response()->json([
            'token' => $token,
            'user' => $this->userPayload($user),
        ]);
    }

    /** GET /api/me — the authenticated user. */
    public function me(Request $request): JsonResponse
    {
        return response()->json(['user' => $this->userPayload($request->user())]);
    }

    /** POST /api/logout — revoke the current token. */
    public function logout(Request $request): JsonResponse
    {
        $request->user()->currentAccessToken()->delete();

        return response()->json(['message' => 'Logged out.']);
    }

    /** Abilities the mobile app uses to show/hide staff features. */
    private const APP_ABILITIES = [
        'dashboard.view', 'students.view', 'families.view',
        'fees.view', 'fees.collect',
        'attendance.view', 'attendance.create', 'attendance.update',
    ];

    private function userPayload(User $user): array
    {
        $role = $user->getRoleNames()->first();
        $isParent = $role === 'Parent';
        $isStudent = $role === 'Student';

        return [
            'id' => $user->id,
            'name' => $user->name,
            'email' => $user->email,
            'role' => $role,
            'is_parent' => $isParent,
            'is_student' => $isStudent,
            'is_staff' => ! $isParent && ! $isStudent,
            'branch_id' => $user->branch_id,
            // Only the app-relevant abilities the user actually has.
            'permissions' => collect(self::APP_ABILITIES)
                ->filter(fn ($a) => $user->can($a))
                ->values()
                ->all(),
        ];
    }
}
