<?php
// app/Models/User.php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use App\Services\PermissionService;
use App\Traits\HotelScopeTrait;
use Illuminate\Support\Facades\Auth;

class User extends Authenticatable
{
    use Notifiable, HotelScopeTrait;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'hotel_id',
        'first_name',
        'last_name',
        'email',
        'phone',
        'role',
        'password',
        'email_verified_at',
        'last_login_at',
        'last_login_ip',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
        'last_login_at' => 'datetime',
    ];

    /**
     * Boot the model - FIXED to prevent recursion
     */
    protected static function boot()
    {
        parent::boot();
        
        // Apply hotel scope ONLY if we're not in a recursive call
        static::addGlobalScope('hotel', function ($builder) {
            // Check if we're already in a request context to prevent recursion
            if (app()->runningInConsole()) {
                return;
            }
            
            try {
                if (Auth::hasUser()) {
                    $user = Auth::user();
                    if ($user && $user->role !== 'super_admin' && $user->hotel_id) {
                        $builder->where('hotel_id', $user->hotel_id);
                    }
                }
            } catch (\Exception $e) {
                // If there's an error, just continue without the scope
                \Log::warning('Could not apply hotel scope: ' . $e->getMessage());
            }
        });

        static::creating(function ($user) {
            // Only set hotel_id if not super_admin and not already set
            if (Auth::hasUser()) {
                $currentUser = Auth::user();
                if ($currentUser && $currentUser->role !== 'super_admin' && !$user->hotel_id) {
                    $user->hotel_id = $currentUser->hotel_id ?? ($currentUser->hotel ? $currentUser->hotel->id : null);
                }
            }
        });
    }

    /**
     * Get the hotel that the user belongs to.
     */
    public function hotel()
    {
        return $this->belongsTo(Hotel::class);
    }

    /**
     * Get the audit logs for the user - LIMITED
     */
    public function auditLogs()
    {
        return $this->hasMany(AuditLog::class)->limit(50);
    }

    /**
     * Get the subscriptions created by this user (for super admin).
     */
    public function createdSubscriptions()
    {
        return $this->hasMany(Admin\AdminHotelSubscription::class, 'created_by')->limit(50);
    }

    /**
     * Get the payments received by this user (for super admin).
     */
    public function receivedPayments()
    {
        return $this->hasMany(Admin\AdminHotelPayment::class, 'received_by')->limit(50);
    }

    /**
     * Get the invoices created by this user (for super admin).
     */
    public function createdInvoices()
    {
        return $this->hasMany(Admin\AdminHotelInvoice::class, 'created_by')->limit(50);
    }

    /**
     * Get the subscription history performed by this user.
     */
    public function subscriptionHistory()
    {
        return $this->hasMany(Admin\AdminHotelSubscriptionHistory::class, 'performed_by')->limit(50);
    }

    /**
     * Get the reports generated by this user.
     */
    public function generatedReports()
    {
        return $this->hasMany(Admin\AdminRevenueReport::class, 'generated_by')->limit(50);
    }

    /**
     * Get the user's full name.
     *
     * @return string
     */
    public function getFullNameAttribute(): string
    {
        return "{$this->first_name} {$this->last_name}";
    }

    /**
     * Get the user's role display name.
     *
     * @return string
     */
    public function getRoleDisplayNameAttribute(): string
    {
        return ucfirst(str_replace('_', ' ', $this->role));
    }

    /**
     * Get the hotel name for display.
     *
     * @return string
     */
    public function getHotelNameAttribute(): string
    {
        return $this->hotel?->name ?? 'No Hotel Assigned';
    }

    /**
     * Check if user is verified.
     *
     * @return bool
     */
    public function isVerified(): bool
    {
        return !is_null($this->email_verified_at);
    }

    /**
     * Check if user has a specific permission.
     *
     * @param string $permission
     * @return bool
     */
    public function hasPermission(string $permission): bool
    {
        return PermissionService::hasPermission($this, $permission);
    }

    /**
     * Check if user has any of the given permissions.
     *
     * @param array $permissions
     * @return bool
     */
    public function hasAnyPermission(array $permissions): bool
    {
        foreach ($permissions as $permission) {
            if ($this->hasPermission($permission)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Check if user has all of the given permissions.
     *
     * @param array $permissions
     * @return bool
     */
    public function hasAllPermissions(array $permissions): bool
    {
        foreach ($permissions as $permission) {
            if (!$this->hasPermission($permission)) {
                return false;
            }
        }
        return true;
    }

    /**
     * Get all permissions for this user.
     *
     * @return array
     */
    public function getPermissionsAttribute(): array
    {
        return PermissionService::getRolePermissions($this->role);
    }

    /**
     * Check if user is super admin.
     *
     * @return bool
     */
    public function isSuperAdmin(): bool
    {
        return $this->role === 'super_admin';
    }

    /**
     * Check if user is a director.
     *
     * @return bool
     */
    public function isDirector(): bool
    {
        return $this->role === 'director';
    }

    /**
     * Check if user is a manager.
     *
     * @return bool
     */
    public function isManager(): bool
    {
        return $this->role === 'manager';
    }

    /**
     * Check if user is front desk staff.
     *
     * @return bool
     */
    public function isFrontDesk(): bool
    {
        return $this->role === 'front_desk';
    }

    /**
     * Check if user is housekeeping staff.
     *
     * @return bool
     */
    public function isHousekeeping(): bool
    {
        return $this->role === 'housekeeping';
    }

    /**
     * Check if user is food & beverage staff.
     *
     * @return bool
     */
    public function isFoodBeverage(): bool
    {
        return $this->role === 'food_beverage';
    }

    /**
     * Check if user is maintenance staff.
     *
     * @return bool
     */
    public function isMaintenance(): bool
    {
        return $this->role === 'maintenance';
    }

    /**
     * Check if user is accountant.
     *
     * @return bool
     */
    public function isAccountant(): bool
    {
        return $this->role === 'accountant';
    }

    /**
     * Scope a query to only include users from a specific hotel.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param int $hotelId
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeFromHotel($query, $hotelId)
    {
        return $query->where('hotel_id', $hotelId);
    }

    /**
     * Scope a query to only include users with a specific role.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param string $role
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeWithRole($query, $role)
    {
        return $query->where('role', $role);
    }

    /**
     * Scope a query to only include verified users.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeVerified($query)
    {
        return $query->whereNotNull('email_verified_at');
    }

    /**
     * Scope a query to only include unverified users.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeUnverified($query)
    {
        return $query->whereNull('email_verified_at');
    }
}