<?php

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;
use Illuminate\Support\Arr;

class OperationRun extends Model
{
    use HasFactory;

    protected $guarded = [];

    protected $casts = [
        'summary_counts' => 'array',
        'failure_summary' => 'array',
        'context' => 'array',
        'started_at' => 'datetime',
        'completed_at' => 'datetime',
    ];

    protected static function booted(): void
    {
        static::creating(function (self $operationRun): void {
            if ($operationRun->workspace_id !== null) {
                return;
            }

            if ($operationRun->tenant_id === null) {
                return;
            }

            $tenant = Tenant::query()->whereKey((int) $operationRun->tenant_id)->first();

            if (! $tenant instanceof Tenant) {
                return;
            }

            if ($tenant->workspace_id === null) {
                return;
            }

            $operationRun->workspace_id = (int) $tenant->workspace_id;
        });
    }

    public function tenant(): BelongsTo
    {
        return $this->belongsTo(Tenant::class);
    }

    public function workspace(): BelongsTo
    {
        return $this->belongsTo(Workspace::class);
    }

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    public function scopeActive(Builder $query): Builder
    {
        return $query->whereIn('status', ['queued', 'running']);
    }

    public function getSelectionHashAttribute(): ?string
    {
        $context = is_array($this->context) ? $this->context : [];

        return isset($context['selection_hash']) && is_string($context['selection_hash'])
            ? $context['selection_hash']
            : null;
    }

    public function setSelectionHashAttribute(?string $value): void
    {
        $context = is_array($this->context) ? $this->context : [];
        $context['selection_hash'] = $value;

        $this->context = $context;
    }

    /**
     * @return array<string, mixed>
     */
    public function getSelectionPayloadAttribute(): array
    {
        $context = is_array($this->context) ? $this->context : [];

        return Arr::only($context, [
            'policy_types',
            'categories',
            'include_foundations',
            'include_dependencies',
        ]);
    }

    /**
     * @param  array<string, mixed>|null  $value
     */
    public function setSelectionPayloadAttribute(?array $value): void
    {
        $context = is_array($this->context) ? $this->context : [];

        if (is_array($value)) {
            $context = array_merge($context, Arr::only($value, [
                'policy_types',
                'categories',
                'include_foundations',
                'include_dependencies',
            ]));
        }

        $this->context = $context;
    }

    public function getFinishedAtAttribute(): mixed
    {
        return $this->completed_at;
    }

    public function setFinishedAtAttribute(mixed $value): void
    {
        $this->completed_at = $value;
    }
}
