<?php

namespace App\Jobs;

use App\Models\RestoreRun;
use App\Models\Tenant;
use App\Services\AssignmentRestoreService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class RestoreAssignmentsJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public int $tries = 1;

    public int $backoff = 0;

    /**
     * Create a new job instance.
     */
    public function __construct(
        public int $restoreRunId,
        public int $tenantId,
        public string $policyType,
        public string $policyId,
        public array $assignments,
        public array $groupMapping,
        public array $foundationMapping = [],
        public ?string $actorEmail = null,
        public ?string $actorName = null,
    ) {}

    /**
     * Execute the job.
     */
    public function handle(AssignmentRestoreService $assignmentRestoreService): array
    {
        $restoreRun = RestoreRun::find($this->restoreRunId);
        $tenant = Tenant::find($this->tenantId);

        if (! $restoreRun || ! $tenant) {
            Log::warning('RestoreAssignmentsJob missing context', [
                'restore_run_id' => $this->restoreRunId,
                'tenant_id' => $this->tenantId,
            ]);

            return [
                'outcomes' => [],
                'summary' => ['success' => 0, 'failed' => 0, 'skipped' => 0],
            ];
        }

        try {
            return $assignmentRestoreService->restore(
                tenant: $tenant,
                policyType: $this->policyType,
                policyId: $this->policyId,
                assignments: $this->assignments,
                groupMapping: $this->groupMapping,
                foundationMapping: $this->foundationMapping,
                restoreRun: $restoreRun,
                actorEmail: $this->actorEmail,
                actorName: $this->actorName,
            );
        } catch (\Throwable $e) {
            Log::error('RestoreAssignmentsJob failed', [
                'restore_run_id' => $this->restoreRunId,
                'policy_id' => $this->policyId,
                'error' => $e->getMessage(),
            ]);

            return [
                'outcomes' => [[
                    'status' => 'failed',
                    'reason' => $e->getMessage(),
                ]],
                'summary' => ['success' => 0, 'failed' => 1, 'skipped' => 0],
            ];
        }
    }
}
