<?php

namespace App\Models;

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

class BulkOperationRun extends Model
{
    use HasFactory;

    protected $fillable = [
        'tenant_id',
        'user_id',
        'resource',
        'action',
        'idempotency_key',
        'status',
        'total_items',
        'processed_items',
        'succeeded',
        'failed',
        'skipped',
        'item_ids',
        'failures',
        'audit_log_id',
    ];

    protected $casts = [
        'item_ids' => 'array',
        'failures' => 'array',
        'processed_items' => 'integer',
        'total_items' => 'integer',
        'succeeded' => 'integer',
        'failed' => 'integer',
        'skipped' => 'integer',
    ];

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

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

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

    public function runType(): string
    {
        return "{$this->resource}.{$this->action}";
    }

    public function statusBucket(): string
    {
        $status = $this->status;

        if ($status === 'pending') {
            return 'queued';
        }

        if ($status === 'running') {
            return 'running';
        }

        $succeededCount = (int) ($this->succeeded ?? 0);
        $failedCount = (int) ($this->failed ?? 0);
        $failureEntries = $this->failures ?? [];
        $hasNonSkippedFailure = false;

        foreach ($failureEntries as $entry) {
            if (! is_array($entry)) {
                continue;
            }

            if (($entry['type'] ?? 'failed') !== 'skipped') {
                $hasNonSkippedFailure = true;
                break;
            }
        }

        $hasFailures = $failedCount > 0 || $hasNonSkippedFailure;

        if ($succeededCount > 0 && $hasFailures) {
            return 'partially succeeded';
        }

        if ($succeededCount === 0 && $hasFailures) {
            return 'failed';
        }

        return match ($status) {
            'completed', 'completed_with_errors' => 'succeeded',
            'failed', 'aborted' => 'failed',
            default => 'failed',
        };
    }
}
