<?php

declare(strict_types=1);

namespace App\Support\References\Resolvers;

use App\Models\OperationRun;
use App\Models\User;
use App\Support\Navigation\CanonicalNavigationContext;
use App\Support\OperationCatalog;
use App\Support\OperationRunLinks;
use App\Support\References\ReferenceClass;
use App\Support\References\ReferenceDescriptor;
use App\Support\References\ReferenceLinkTarget;
use App\Support\References\ResolvedReference;

final class OperationRunReferenceResolver extends BaseReferenceResolver
{
    public function __construct(
        \App\Support\References\ReferenceTypeLabelCatalog $typeLabels,
    ) {
        parent::__construct($typeLabels);
    }

    public function referenceClass(): ReferenceClass
    {
        return ReferenceClass::OperationRun;
    }

    public function resolve(ReferenceDescriptor $descriptor): ResolvedReference
    {
        $runId = $this->linkedModelId($descriptor);
        $workspaceId = $descriptor->workspaceId;

        if ($runId === null || $workspaceId === null || $workspaceId <= 0) {
            return $this->unresolved($descriptor);
        }

        $run = OperationRun::query()
            ->whereKey($runId)
            ->where('workspace_id', $workspaceId)
            ->first();

        if (! $run instanceof OperationRun) {
            return $this->missing($descriptor);
        }

        if (! $this->canOpenOperationRun($run)) {
            return $this->inaccessible($descriptor);
        }

        $context = $descriptor->contextValue('navigation_context');
        $navigationContext = $context instanceof CanonicalNavigationContext ? $context : null;

        return $this->resolved(
            descriptor: $descriptor,
            primaryLabel: OperationCatalog::label((string) $run->type),
            secondaryLabel: OperationRunLinks::identifier($run),
            linkTarget: new ReferenceLinkTarget(
                targetKind: ReferenceClass::OperationRun->value,
                url: OperationRunLinks::tenantlessView($run, $navigationContext),
                actionLabel: OperationRunLinks::openLabel(),
                contextBadge: $run->managed_environment_id ? 'ManagedEnvironment context' : 'Workspace',
            ),
        );
    }

    private function canOpenOperationRun(OperationRun $run): bool
    {
        $user = auth()->user();

        return $user instanceof User && $user->can('view', $run);
    }
}
