<?php

namespace App\Modules\Procurement\Services;

use App\Modules\Operations\Services\OperationalSignalRecorder;
use Illuminate\Support\Facades\Log;

final class GoodsReceiptObservability
{
    public function __construct(
        private readonly OperationalSignalRecorder $recorder,
    ) {}

    private function enabled(): bool
    {
        return (bool) config('procurement.observability.enabled', true);
    }

    /** @param  array<string, mixed>  $context */
    public function orphanDetected(array $context = []): void
    {
        if ($this->enabled()) {
            Log::warning('procurement.receipt.orphan_detected', $context);
        }
        $this->persistIntegrity('integrity_orphan', 'critical', 'orphan_detected', 'Orphan receipt line detected.', $context);
    }

    /** @param  array<string, mixed>  $context */
    public function invalidReceiptLine(string $reason, array $context = []): void
    {
        if ($this->enabled()) {
            Log::warning('procurement.receipt.invalid_receipt_line '.$reason, $context);
        }
        $this->persistIntegrity('integrity_invalid_line', 'error', $reason, 'Invalid receipt line: '.$reason, $context);
    }

    /** @param  array<string, mixed>  $context */
    public function hydrationQuarantine(array $context = []): void
    {
        if ($this->enabled()) {
            Log::notice('procurement.receipt.hydration_quarantine', $context);
        }
        $this->persistIntegrity('hydration_quarantine', 'warning', 'hydration_quarantine', 'Line quarantined during hydration.', $context);
    }

    /** @param  array<string, mixed>  $context */
    public function crossPoReceiptContamination(array $context = []): void
    {
        if ($this->enabled()) {
            Log::warning('procurement.receipt.cross_po_receipt_contamination', $context);
        }
        $this->persistIntegrity('integrity_cross_po', 'critical', 'cross_po', 'Cross-PO receipt contamination.', $context);
    }

    /** @param  array<string, mixed>  $context */
    private function persistIntegrity(
        string $category,
        string $severity,
        string $eventCode,
        string $summary,
        array $context,
    ): void {
        $tenantId = (int) ($context['tenant_id'] ?? 0);
        if ($tenantId <= 0) {
            return;
        }
        $refType = null;
        $refId = null;
        if (isset($context['goods_receipt_item_id'])) {
            $refType = 'goods_receipt_item';
            $refId = (int) $context['goods_receipt_item_id'];
        } elseif (isset($context['goods_receipt_id'])) {
            $refType = 'goods_receipt';
            $refId = (int) $context['goods_receipt_id'];
        }

        $this->recorder->record(
            $tenantId,
            'procurement',
            $category,
            $severity,
            $eventCode,
            $summary,
            null,
            $refType,
            $refId,
            $context,
        );
    }
}
