<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Spatie\Permission\Traits\HasRoles;
use App\Models\Portal;
use App\Notifications\ResetPasswordNotification;

class User extends Authenticatable
{
    use HasFactory, Notifiable, HasApiTokens, HasRoles;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'name',
        'email',
        'username',
        'password',
        'email_verified_at',
        'first_name',
        'last_name',
        'phone',
        'address',
        'avatar',
        'user_category',
        'user_type',
        'user_category_id',
        'user_type_id',
        'license_number',
        'student_id_number',
        'student_id_file',
        'preferred_language',
        'status',
        'is_active',
        'rcic_email',
        'rcic_email_verified_at',
        'rcic_email_verification_token',
        'stripe_customer_id',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'rcic_email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }

    /**
     * Get all portals this user has access to.
     */
    public function portals()
    {
        return $this->belongsToMany(Portal::class, 'portal_user')
            ->withPivot('role_scope')
            ->withTimestamps();
    }

    /**
     * Get the user's category.
     */
    public function userCategory()
    {
        return $this->belongsTo(UserCategory::class, 'user_category_id');
    }

    /**
     * Get the user's type.
     */
    public function userType()
    {
        return $this->belongsTo(UserType::class, 'user_type_id');
    }

    /**
     * Get the avatar URL attribute.
     */
    public function getAvatarUrlAttribute()
    {
        if ($this->avatar) {
            return url('storage/' . $this->avatar);
        }
        return null;
    }

    /**
     * Backward compatibility alias for portals
     */
    public function modules()
    {
        return $this->portals();
    }

    /**
     * Check if user has access to a specific portal.
     */
    public function hasPortalAccess(string $portalKey): bool
    {
        // Super admin has access to everything
        if ($this->hasRole('super_admin')) {
            return true;
        }

        return $this->portals()
            ->where('key', $portalKey)
            ->where('enabled', true)
            ->exists();
    }

    /**
     * Backward compatibility alias
     */
    public function hasModuleAccess(string $moduleKey): bool
    {
        return $this->hasPortalAccess($moduleKey);
    }

    /**
     * Check if user has admin access to a specific portal.
     */
    public function isPortalAdmin(string $portalKey): bool
    {
        // Super admin has admin access to everything
        if ($this->hasRole('super_admin')) {
            return true;
        }

        return $this->portals()
            ->where('key', $portalKey)
            ->wherePivot('role_scope', 'portal_admin')
            ->where('enabled', true)
            ->exists();
    }

    /**
     * Backward compatibility alias
     */
    public function isModuleAdmin(string $moduleKey): bool
    {
        return $this->isPortalAdmin($moduleKey);
    }

    /**
     * Get user's role scope for a specific portal.
     */
    public function getPortalRoleScope(string $portalKey): ?string
    {
        if ($this->hasRole('super_admin')) {
            return 'portal_admin';
        }

        $portal = $this->portals()
            ->where('key', $portalKey)
            ->first();

        return $portal ? $portal->pivot->role_scope : null;
    }

    /**
     * Backward compatibility alias
     */
    public function getModuleRoleScope(string $moduleKey): ?string
    {
        return $this->getPortalRoleScope($moduleKey);
    }

    /**
     * CMS clients created by this user.
     */
    public function createdCmsClients()
    {
        return $this->hasMany(\App\Models\Cms\Client::class, 'created_by');
    }

    /**
     * CMS clients assigned to this user.
     */
    public function assignedCmsClients()
    {
        return $this->hasMany(\App\Models\Cms\Client::class, 'assigned_to');
    }

    /**
     * User's invoices.
     */
    public function invoices()
    {
        return $this->hasMany(Invoice::class);
    }

    /**
     * User's transactions.
     */
    public function transactions()
    {
        return $this->hasMany(Transaction::class);
    }

    /**
     * User's subscriptions.
     */
    public function subscriptions()
    {
        return $this->hasMany(Subscription::class);
    }

    /**
     * Send the password reset notification.
     *
     * @param  string  $token
     * @return void
     */
    public function sendPasswordResetNotification($token)
    {
        $this->notify(new ResetPasswordNotification($token));
    }
}
