<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Storage;

/**
 * Thinkrax staff who operate the central panel.
 *
 * Authorisation here is a simple role ladder rather than a permission matrix:
 * the team is small, the surface is narrow, and a matrix would be ceremony
 * without benefit.
 */
class User extends Authenticatable
{
    use HasFactory, Notifiable, SoftDeletes;

    public const ROLES = [
        'super_admin' => 'Super Admin',
        'admin' => 'Admin',
        'accountant' => 'Accountant',
        'support' => 'Support',
    ];

    protected $fillable = [
        'name', 'email', 'phone', 'password', 'role', 'avatar_path', 'is_active',
    ];

    protected $hidden = ['password', 'remember_token'];

    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'last_login_at' => 'datetime',
            'password' => 'hashed',
            'is_active' => 'boolean',
        ];
    }

    public function scopeActive(Builder $query): Builder
    {
        return $query->where('is_active', true);
    }

    public function roleLabel(): string
    {
        return self::ROLES[$this->role] ?? ucfirst((string) $this->role);
    }

    public function isSuperAdmin(): bool
    {
        return $this->role === 'super_admin';
    }

    /** May approve, reject and refund money. */
    public function canVerifyPayments(): bool
    {
        return in_array($this->role, ['super_admin', 'admin', 'accountant'], true);
    }

    /** May create and edit plans, products and payment accounts. */
    public function canManageCatalog(): bool
    {
        return in_array($this->role, ['super_admin', 'admin'], true);
    }

    /** May suspend a shop or change its subscription by hand. */
    public function canManageTenants(): bool
    {
        return in_array($this->role, ['super_admin', 'admin'], true);
    }

    public function canManageStaff(): bool
    {
        return $this->isSuperAdmin();
    }

    protected function avatarUrl(): Attribute
    {
        return Attribute::get(fn () => $this->avatar_path ? Storage::url($this->avatar_path) : null);
    }

    protected function initials(): Attribute
    {
        return Attribute::get(function () {
            $parts = preg_split('/\s+/', trim((string) $this->name)) ?: [];

            return strtoupper(collect($parts)->take(2)->map(fn ($p) => mb_substr($p, 0, 1))->implode('')) ?: 'U';
        });
    }

    public function recordLogin(?string $ip): void
    {
        $this->forceFill(['last_login_at' => now(), 'last_login_ip' => $ip])->saveQuietly();
    }
}
