<?php

namespace Modules\Bms\Http\Controllers\Api;

use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Modules\Bms\Database\Seeders\BmsTestStaffSeeder;
use Modules\Bms\Entities\BmsApiToken;

/**
 * Employee (P2) authentication — username/password yields an employee bearer
 * token. Reuses the ERP's user store; only active, login-allowed users pass.
 */
class EmployeeAuthController extends ApiController
{
    /** Every BMS ability — the response reports which ones the user holds. */
    public const BMS_PERMS = [
        'bms.access', 'bms.dashboard.view', 'bms.leads.view', 'bms.leads.manage',
        'bms.bookings.view', 'bms.bookings.manage', 'bms.bookings.cancel', 'bms.bookings.override_penalty',
        'bms.halls.view', 'bms.assets.view', 'bms.maintenance.view', 'bms.maintenance.manage',
        'bms.qc.view', 'bms.qc.manage', 'bms.ai.use', 'bms.settings.access',
    ];

    public function login(Request $request)
    {
        $data = $request->validate([
            'username' => 'required|string',
            'password' => 'required|string',
        ]);

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

        if (! $user || ! Hash::check($data['password'], $user->password)) {
            return $this->fail('Invalid credentials.', 401);
        }
        if ($user->status !== 'active' || ! $user->allow_login) {
            return $this->fail('This account cannot sign in.', 403);
        }

        return $this->issueFor($user);
    }

    /** Build the auth payload (token + user + the BMS abilities they hold). */
    protected function issueFor(User $user)
    {
        $token = BmsApiToken::issue((int) $user->business_id, 'employee', $user->id);

        return $this->ok([
            'token' => $token->token,
            'user'  => [
                'id'          => $user->id,
                'name'        => trim(($user->first_name ?? '') . ' ' . ($user->surname ?? '')) ?: $user->username,
                'username'    => $user->username,
                'business_id' => $user->business_id,
            ],
            // Respects Gate::before (admins get all) — drives client-side nav gating.
            'permissions' => array_values(array_filter(self::BMS_PERMS, fn ($p) => $user->can($p))),
        ]);
    }

    public function logout(Request $request)
    {
        optional($request->attributes->get('bms_token'))->delete();
        return $this->ok(['signed_out' => true]);
    }

    /** True when test sign-in is allowed (config flag or debug). */
    protected function testLoginEnabled(): bool
    {
        return (bool) (config('bms.test_login') || config('app.debug'));
    }

    /** List the seeded demo roles for one-tap test sign-in. */
    public function devStaff(Request $request)
    {
        if (! $this->testLoginEnabled()) {
            abort(404);
        }
        $roles = BmsTestStaffSeeder::ensure($this->publicBusinessId($request));
        return $this->ok(['roles' => collect($roles)->map(fn ($r, $key) => [
            'role' => $key, 'name' => $r['name'], 'name_ar' => $r['name_ar'], 'username' => $r['username'],
        ])->values()]);
    }

    /** One-tap sign-in as a seeded demo staff member (testing only). */
    public function devStaffLogin(Request $request)
    {
        if (! $this->testLoginEnabled()) {
            abort(404);
        }
        $businessId = $this->publicBusinessId($request);
        BmsTestStaffSeeder::ensure($businessId);

        $role = $request->input('role', 'manager');
        $username = 'bms_' . preg_replace('/[^a-z]/', '', strtolower((string) $role));
        $user = User::where('username', $username)->where('business_id', $businessId)->first();
        if (! $user) {
            return $this->fail('Unknown demo role.', 404);
        }

        return $this->issueFor($user);
    }
}
