<?php

namespace App\Models;

use App\Support\AdminProjectPermissionRegistry;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Schema;

class Admin extends Authenticatable
{
    use Notifiable;

    protected $guard = 'admin';

    protected $fillable = [
        'name',
        'email',
        'password',
        'is_super_admin',
        'project_permissions',
    ];

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

    protected $casts = [
        'is_super_admin' => 'boolean',
        'project_permissions' => 'array',
    ];

    public function isSuperAdmin(): bool
    {
        if (!self::hasColumn('is_super_admin')) {
            return true;
        }

        return (bool) $this->getAttribute('is_super_admin');
    }

    public function assignedProjectPermissions(): array
    {
        if ($this->isSuperAdmin() || !self::hasColumn('project_permissions')) {
            return [];
        }

        $permissions = $this->getAttribute('project_permissions');

        if (is_string($permissions) && $permissions !== '') {
            $decoded = json_decode($permissions, true);
            $permissions = is_array($decoded) ? $decoded : [];
        }

        if (!is_array($permissions)) {
            $permissions = [];
        }

        return AdminProjectPermissionRegistry::sanitizeProjectKeys($permissions);
    }

    public function hasProjectPermission(string $projectKey): bool
    {
        if ($this->isSuperAdmin()) {
            return true;
        }

        return in_array($projectKey, $this->assignedProjectPermissions(), true);
    }

    public function hasAnyProjectPermission(array $projectKeys): bool
    {
        if ($this->isSuperAdmin()) {
            return true;
        }

        $assigned = $this->assignedProjectPermissions();
        foreach ($projectKeys as $projectKey) {
            if (is_string($projectKey) && in_array($projectKey, $assigned, true)) {
                return true;
            }
        }

        return false;
    }

    public function setProjectPermissions(array $permissions): void
    {
        $this->setAttribute(
            'project_permissions',
            AdminProjectPermissionRegistry::sanitizeProjectKeys($permissions)
        );
    }

    public static function supportsRolePermissions(): bool
    {
        return self::hasColumn('is_super_admin') && self::hasColumn('project_permissions');
    }

    protected static function hasColumn(string $column): bool
    {
        static $cache = [];

        if (array_key_exists($column, $cache)) {
            return $cache[$column];
        }

        try {
            $cache[$column] = Schema::hasColumn((new static)->getTable(), $column);
        } catch (\Throwable) {
            $cache[$column] = false;
        }

        return $cache[$column];
    }
}
