<?php

namespace App\Services\AutoGrab;

use App\Imports\AutoGrabToVehicleImport;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Mtc\MercuryDataModels\ApiNotification;
use Mtc\MercuryDataModels\Vehicle;
use Throwable;

use function tenant;

/**
 * Applies a batch of AutoGrab feed rows to stock through the shared AutoGrabToVehicleImport
 * pipeline. This is the work unit run inside ImportAutoGrabFeedBatch on the stock batch queue.
 *
 * Decoupled from GCS/DuckDB so the import behaviour can be exercised with plain row arrays in
 * tests. Each row is upserted in its own short, deadlock-retried transaction (mirroring the
 * webhook drainer). The snapshot-wide convergence (deactivating vehicles absent from the feed)
 * is handled by the provider once all batches are dispatched, not here.
 */
class AutoGrabFeedImporter
{
    public function __construct(
        private readonly AutoGrabFeedRowMapper $mapper = new AutoGrabFeedRowMapper(),
    ) {
    }

    /**
     * @param array<int, array<string, mixed>> $rows Raw feed rows (26-column schema).
     * @return array{processed: int, failed: int}
     */
    public function importBatch(array $rows): array
    {
        $import = (new AutoGrabToVehicleImport())->fromFileFeed();

        // These per-save side effects add write load + lock surface and are redundant for
        // a bulk machine import; suppress them for the run, exactly like the drainer.
        Config::set('vehicles.search-content-observer-enabled', false);
        Vehicle::disableAuditing();

        $processed = 0;
        $failed = 0;
        $syncedIds = [];

        try {
            foreach ($rows as $row) {
                $lead = $this->mapper->toLead($row);

                try {
                    DB::transaction(fn () => $import->process(['lead' => $lead]), 3);
                    $processed++;

                    if (($id = $this->mapper->id($lead)) !== null) {
                        $syncedIds[] = $id;
                    }
                } catch (Throwable $exception) {
                    $failed++;
                    $this->recordFailure($lead, $exception);
                }
            }

            // Clear the pending-sync flag the provider set before dispatching this batch, so
            // the convergence pass no longer treats these vehicles as awaiting a batch.
            if ($syncedIds !== []) {
                Vehicle::query()
                    ->where('stock_provider', 'autograb')
                    ->whereIn('uuid', $syncedIds)
                    ->update(['pending_stock_sync' => null]);
            }
        } finally {
            Vehicle::enableAuditing();
            Config::set('vehicles.search-content-observer-enabled', true);
        }

        // Summary breadcrumb: the batch runs on the queue with no console, so this is the only
        // trace of per-batch outcome when debugging a run dispatched by the import command.
        $summary = ['tenant' => tenant('id'), 'processed' => $processed, 'failed' => $failed];
        Log::info('AutoGrab feed batch processed', $summary);

        return compact('processed', 'failed');
    }

    /**
     * Record a failure-only audit row. The stored payload is deliberately trimmed to
     * non-PII identifiers (no contact_name / postcode) so debugging data does not persist
     * UK personal data beyond what already lives on the vehicle.
     */
    private function recordFailure(array $lead, Throwable $exception): void
    {
        $reference = $this->mapper->id($lead) ?? ($lead['rego'] ?? $lead['vin'] ?? null);

        Log::error('AutoGrab feed row processing failed', [
            'tenant' => tenant('id'),
            'reference' => $reference,
            'error' => $exception->getMessage(),
        ]);

        ApiNotification::query()->create([
            'provider' => 'autograb',
            'data' => [
                'error' => $exception->getMessage(),
                'lead_id' => $this->mapper->id($lead),
                'rego' => $lead['rego'] ?? null,
                'vin' => $lead['vin'] ?? null,
                'make' => $lead['make'] ?? null,
                'model' => $lead['model'] ?? null,
            ],
            'data_model' => 'autograb-feed-failure',
            'reference' => $reference,
            'processed' => false,
        ]);
    }
}
