<?php

declare(strict_types=1);

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class SupportAccessGrant extends Model
{
    /** @use HasFactory<\Database\Factories\SupportAccessGrantFactory> */
    use HasFactory;

    public const SCOPE_AUDIT_VIEW = 'audit_view';

    public const SCOPE_WORKSPACE_RECOVERY = 'workspace_recovery';

    public const STATUS_REQUESTED = 'requested';

    public const STATUS_ACTIVE = 'active';

    public const STATUS_DENIED = 'denied';

    public const STATUS_EXPIRED = 'expired';

    public const STATUS_ENDED = 'ended';

    public const APPROVAL_MODE_AUTO = 'auto';

    public const APPROVAL_MODE_OWNER_REQUIRED = 'owner_required';

    public const APPROVAL_MODE_OWNERLESS_WAIVER = 'ownerless_waiver';

    protected $guarded = [];

    protected function casts(): array
    {
        return [
            'requested_at' => 'datetime',
            'approved_at' => 'datetime',
            'starts_at' => 'datetime',
            'expires_at' => 'datetime',
            'ended_at' => 'datetime',
            'denied_at' => 'datetime',
        ];
    }

    /**
     * @return BelongsTo<Workspace, $this>
     */
    public function workspace(): BelongsTo
    {
        return $this->belongsTo(Workspace::class);
    }

    /**
     * @return BelongsTo<PlatformUser, $this>
     */
    public function requester(): BelongsTo
    {
        return $this->belongsTo(PlatformUser::class, 'requested_by_platform_user_id');
    }

    /**
     * @return BelongsTo<User, $this>
     */
    public function approver(): BelongsTo
    {
        return $this->belongsTo(User::class, 'approved_by_user_id');
    }

    public function scopeOpen(Builder $query): Builder
    {
        return $query->whereIn('status', [
            self::STATUS_REQUESTED,
            self::STATUS_ACTIVE,
        ]);
    }

    public function isActive(): bool
    {
        return $this->status === self::STATUS_ACTIVE
            && $this->expires_at !== null
            && $this->expires_at->isFuture();
    }

    public function isPending(): bool
    {
        return $this->status === self::STATUS_REQUESTED;
    }

    public function needsBreakGlass(): bool
    {
        return $this->scope === self::SCOPE_WORKSPACE_RECOVERY;
    }

    /**
     * @return array<string, string>
     */
    public static function scopeLabels(): array
    {
        return [
            self::SCOPE_AUDIT_VIEW => 'Audit trail review',
            self::SCOPE_WORKSPACE_RECOVERY => 'Workspace recovery',
        ];
    }

    public static function scopeLabel(string $scope): string
    {
        return self::scopeLabels()[$scope] ?? str($scope)->replace('_', ' ')->title()->toString();
    }

    /**
     * @return array<string, string>
     */
    public static function statusLabels(): array
    {
        return [
            self::STATUS_REQUESTED => 'Pending approval',
            self::STATUS_ACTIVE => 'Active',
            self::STATUS_DENIED => 'Denied',
            self::STATUS_EXPIRED => 'Expired',
            self::STATUS_ENDED => 'Ended',
        ];
    }

    public static function statusLabel(string $status): string
    {
        return self::statusLabels()[$status] ?? str($status)->replace('_', ' ')->title()->toString();
    }

    /**
     * @return array<string, string>
     */
    public static function approvalModeLabels(): array
    {
        return [
            self::APPROVAL_MODE_AUTO => 'Auto-approved low-risk access',
            self::APPROVAL_MODE_OWNER_REQUIRED => 'Workspace owner approval required',
            self::APPROVAL_MODE_OWNERLESS_WAIVER => 'Ownerless recovery waiver',
        ];
    }

    public static function approvalModeLabel(string $approvalMode): string
    {
        return self::approvalModeLabels()[$approvalMode] ?? str($approvalMode)->replace('_', ' ')->title()->toString();
    }

    /**
     * @return list<string>
     */
    public static function scopes(): array
    {
        return [
            self::SCOPE_AUDIT_VIEW,
            self::SCOPE_WORKSPACE_RECOVERY,
        ];
    }

    /**
     * @return list<string>
     */
    public static function terminalStatuses(): array
    {
        return [
            self::STATUS_DENIED,
            self::STATUS_EXPIRED,
            self::STATUS_ENDED,
        ];
    }

    /**
     * @return list<string>
     */
    public static function supportAccessAuditActions(): array
    {
        return [
            \App\Support\Audit\AuditActionId::SupportAccessRequested->value,
            \App\Support\Audit\AuditActionId::SupportAccessActivated->value,
            \App\Support\Audit\AuditActionId::SupportAccessApproved->value,
            \App\Support\Audit\AuditActionId::SupportAccessDenied->value,
            \App\Support\Audit\AuditActionId::SupportAccessEnded->value,
            \App\Support\Audit\AuditActionId::SupportAccessExpired->value,
            \App\Support\Audit\AuditActionId::SupportAccessOwnerlessWaiverUsed->value,
        ];
    }
}
