<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class ClientAdmin extends Authenticatable
{
    use HasFactory, Notifiable;

    /**
     * The guard for client admin authentication.
     *
     * @var string
     */
    protected $guard = 'client_admin';

    /**
     * Role constants.
     */
    const ROLE_OWNER = 'owner';
    const ROLE_MANAGER = 'manager';

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'client_id',
        'name',
        'email',
        'phone',
        'password',
        'role',
        'is_active',
        'last_login_at',
    ];

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

    /**
     * The attributes that should be cast.
     *
     * @var array<string, string>
     */
    protected $casts = [
        'password' => 'hashed',
        'is_active' => 'boolean',
        'last_login_at' => 'datetime',
    ];

    // ============ RELATIONSHIPS ============

    /**
     * Get the client this admin belongs to.
     */
    public function client()
    {
        return $this->belongsTo(Client::class);
    }

    /**
     * Get users created by this client admin.
     */
    public function createdUsers()
    {
        return $this->hasMany(User::class, 'created_by_client_admin');
    }

    /**
     * Get templates created by this client admin.
     */
    public function createdTemplates()
    {
        return $this->hasMany(MessageTemplate::class, 'created_by_client_admin');
    }

    /**
     * Get individual permission overrides for this client admin.
     */
    public function permissionOverrides()
    {
        return $this->hasMany(ClientAdminPermission::class);
    }

    // ============ ROLE CHECKS ============

    /**
     * Check if client admin is owner.
     */
    public function isOwner(): bool
    {
        return $this->role === self::ROLE_OWNER;
    }

    /**
     * Check if client admin is manager.
     */
    public function isManager(): bool
    {
        return $this->role === self::ROLE_MANAGER;
    }

    // ============ PERMISSION CHECKS (Dynamic RBAC) ============

    /**
     * Check if this client admin has a specific permission.
     * Resolution order: Individual override → Role default → Deny
     *
     * NOTE: Unlike Admin (where SuperAdmin bypasses all), Owner does NOT
     * have a hardcoded bypass. Permissions are fully dynamic and configurable
     * by SuperAdmin through individual overrides.
     */
    public function hasPermission(string $permissionKey): bool
    {
        // 1. Check individual override first
        $override = $this->permissionOverrides()
            ->where('permission_key', $permissionKey)
            ->first();

        if ($override) {
            return $override->is_allowed;
        }

        // 2. Fall back to role defaults
        $roleKey = $this->role === self::ROLE_OWNER
            ? RolePermission::ROLE_CLIENT_OWNER
            : RolePermission::ROLE_CLIENT_MANAGER;

        $rolePermission = RolePermission::where('role', $roleKey)
            ->where('permission_key', $permissionKey)
            ->first();

        if ($rolePermission) {
            return $rolePermission->is_allowed;
        }

        // 3. Default: deny
        return false;
    }

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

    /**
     * Get all permissions with their effective status.
     * Returns array of ['permission_key' => bool]
     */
    public function getAllPermissions(): array
    {
        $clientPermissions = collect(Permission::getClientScopePermissions())
            ->pluck('permission_key')
            ->toArray();

        $result = [];
        foreach ($clientPermissions as $key) {
            $result[$key] = $this->hasPermission($key);
        }
        return $result;
    }

    /**
     * Check if can manage other client admins.
     * @deprecated Use hasPermission('client.admins.view') instead
     */
    public function canManageClientAdmins(): bool
    {
        return $this->hasPermission('client.admins.view');
    }

    /**
     * Check if can manage users.
     * @deprecated Use hasPermission('client.users.view') instead
     */
    public function canManageUsers(): bool
    {
        return $this->hasPermission('client.users.view');
    }

    /**
     * Check if can manage templates.
     * @deprecated Use hasPermission('client.templates.view') instead
     */
    public function canManageTemplates(): bool
    {
        return $this->hasPermission('client.templates.view');
    }

    // ============ CLIENT CHECKS ============

    /**
     * Check if client subscription is active.
     */
    public function hasActiveClientSubscription(): bool
    {
        return $this->client && $this->client->hasActiveSubscription();
    }

    /**
     * Check if this admin can login (active + client active + subscription active).
     */
    public function canLogin(): bool
    {
        if (!$this->is_active) {
            return false;
        }

        if (!$this->client || !$this->client->is_active) {
            return false;
        }

        return $this->client->hasActiveSubscription();
    }

    /**
     * Get login denial reason.
     */
    public function getLoginDenialReason(): ?string
    {
        if (!$this->is_active) {
            return 'Your account has been disabled. Please contact your organization administrator.';
        }

        if (!$this->client) {
            return 'Organization not found.';
        }

        if (!$this->client->is_active) {
            return 'Your organization has been disabled. Please contact support.';
        }

        if (!$this->client->is_subscription_active) {
            return 'Your organization\'s subscription has been paused. Please contact support.';
        }

        if ($this->client->isSubscriptionExpired()) {
            return 'Your organization\'s subscription has expired. Please contact support for renewal.';
        }

        return null;
    }

    // ============ ACTIONS ============

    /**
     * Record login.
     */
    public function recordLogin(): void
    {
        $this->update(['last_login_at' => now()]);
    }

    // ============ SCOPES ============

    /**
     * Scope for active client admins.
     */
    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }

    /**
     * Scope for owners only.
     */
    public function scopeOwners($query)
    {
        return $query->where('role', self::ROLE_OWNER);
    }

    /**
     * Scope for managers only.
     */
    public function scopeManagers($query)
    {
        return $query->where('role', self::ROLE_MANAGER);
    }

    /**
     * Scope for client admins of a specific client.
     */
    public function scopeForClient($query, $clientId)
    {
        return $query->where('client_id', $clientId);
    }
}
