<?php

namespace Modules\VetStaffPortal\Entities;

use App\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Str;

class VsStaffToken extends Model
{
    protected $table = 'vet_staff_tokens';

    protected $fillable = [
        'user_id', 'business_id', 'token_hash', 'user_agent', 'ip',
        'last_used_at', 'expires_at',
    ];

    protected $hidden = ['token_hash'];

    protected $casts = [
        'last_used_at' => 'datetime',
        'expires_at'   => 'datetime',
    ];

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id');
    }

    /**
     * Issue a fresh token for a staff user. Returns the PLAINTEXT token to hand
     * to the PWA; only its sha256 hash is persisted.
     */
    public static function issue(User $user, ?string $userAgent, ?string $ip, ?int $ttlDays = null): string
    {
        $ttlDays = $ttlDays ?? (int) config('vetstaffportal.token_ttl_days', 30);
        $plain   = 'staff-' . Str::random(40);
        self::create([
            'user_id'    => $user->id,
            'business_id'=> $user->business_id,
            'token_hash' => hash('sha256', $plain),
            'user_agent' => $userAgent,
            'ip'         => $ip,
            'expires_at' => $ttlDays ? now()->addDays($ttlDays) : null,
        ]);
        return $plain;
    }

    /** Resolve a bearer token back to its user, touching last_used_at. */
    public static function lookup(string $plain): ?User
    {
        if ($plain === '') return null;
        $row = self::where('token_hash', hash('sha256', $plain))->first();
        if (! $row) return null;
        if ($row->expires_at && $row->expires_at->isPast()) return null;
        $row->forceFill(['last_used_at' => now()])->save();
        return $row->user;
    }

    /** Revoke a single bearer token (logout). */
    public static function revoke(string $plain): void
    {
        if ($plain === '') return;
        self::where('token_hash', hash('sha256', $plain))->delete();
    }
}
