<?php

namespace WPSN\Modules\Bulk;

use WPSN\Core\Logger;

defined('ABSPATH') || exit;

final class BulkQueueSessionTracker
{
    private BulkQueueSessionRepository $sessions;

    public function __construct(Logger $logger)
    {
        $this->sessions = new BulkQueueSessionRepository($logger);
    }

    public function register(): void
    {
        add_action('wpsn/queue/enqueued', [$this, 'handleEnqueued'], 10, 4);
        add_action('wpsn/queue/job_failed', [$this, 'handleFailed'], 10, 5);
    }

    /**
     * @param array<string,mixed> $payload
     */
    public function handleEnqueued(int $jobId, string $jobType, array $payload, int $runAtTimestamp): void
    {
        $sessionId = isset($payload['bulk_session_id']) ? sanitize_key((string) $payload['bulk_session_id']) : '';
        if ($sessionId === '' || $jobId <= 0) {
            return;
        }

        $this->sessions->addJob($sessionId, $jobId, $jobType, $payload);
    }

    /**
     * @param array<string,mixed> $payload
     * @param array<string,mixed> $job
     */
    public function handleFailed(int $jobId, string $jobType, array $payload, array $job, string $error): void
    {
        $sessionId = isset($payload['bulk_session_id']) ? sanitize_key((string) $payload['bulk_session_id']) : '';
        if ($sessionId === '') {
            return;
        }

        $objectType = isset($payload['object_type']) ? sanitize_key((string) $payload['object_type']) : 'post';
        $objectId = isset($payload['object_id']) ? (int) $payload['object_id'] : 0;
        if ($objectId <= 0 && isset($payload['post_id'])) {
            $objectType = 'post';
            $objectId = (int) $payload['post_id'];
        }
        if ($objectId <= 0 || !in_array($objectType, ['post', 'term'], true)) {
            return;
        }

        $objectSubtype = isset($payload['object_subtype']) ? sanitize_key((string) $payload['object_subtype']) : '';
        $message = $error !== ''
            ? sprintf(__('Queue job failed: %s', 'wp-seo-next'), $error)
            : __('Queue job failed.', 'wp-seo-next');

        $report = new BulkSessionReportRepository();
        if ($jobType === 'bulk_generate') {
            $report->recordGenerate($sessionId, [
                'object_type' => $objectType,
                'object_id' => $objectId,
                'object_subtype' => $objectSubtype,
                'generate_status' => 'failed',
                'generate_note' => $message,
            ]);
            return;
        }

        if ($jobType === 'bulk_apply') {
            $report->recordApply($sessionId, [
                'object_type' => $objectType,
                'object_id' => $objectId,
                'object_subtype' => $objectSubtype,
                'apply_status' => 'failed',
                'apply_note' => $message,
            ]);
            return;
        }

        if ($jobType === 'audit_bulk_fix') {
            $report->recordFix($sessionId, [
                'object_type' => $objectType,
                'object_id' => $objectId,
                'object_subtype' => $objectSubtype,
                'fix_status' => 'failed',
                'fix_note' => $message,
            ]);
        }
    }

}
