<?php

namespace App\Support;

use Illuminate\Support\Facades\Log;

/**
 * Logging estructurado para auditoría TIBU (sin PII: no folios completos, nombres ni QR en claro).
 */
class LaundryAuditLogger
{
    public static function channel(): \Psr\Log\LoggerInterface
    {
        return Log::channel('laundry');
    }

    /**
     * Correlación opcional sin exponer folio (8 hex del hash SHA-256).
     */
    public static function folioFingerprint(?string $folio): ?string
    {
        if ($folio === null || $folio === '') {
            return null;
        }

        return substr(hash('sha256', $folio), 0, 8);
    }

    /**
     * Escaneo denegado (permiso, área inexistente, orden cerrada, bloqueo, etc.).
     *
     * @param  array<string, mixed>  $context
     */
    public static function scanDenied(string $reason, array $context = []): void
    {
        self::channel()->warning('laundry.scan_denied', array_merge([
            'reason' => $reason,
        ], self::sanitize($context)));
    }

    /**
     * Secuencia de escaneo inválida (1/2) o error de registro de evento.
     *
     * @param  array<string, mixed>  $context
     */
    public static function invalidScanSequence(string $message, array $context = []): void
    {
        self::channel()->notice('laundry.invalid_scan_sequence', array_merge([
            'message' => $message,
        ], self::sanitize($context)));
    }

    /**
     * Intento de avanzar etapa cuando no aplica (p. ej. ya terminado/entregado).
     *
     * @param  array<string, mixed>  $context
     */
    public static function invalidStepTransition(int $ordenId, string $stepAnterior, string $stepIntentado, array $context = []): void
    {
        self::channel()->notice('laundry.invalid_step_transition', array_merge([
            'orden_id' => $ordenId,
            'step_anterior' => $stepAnterior,
            'step_intentado' => $stepIntentado,
        ], self::sanitize($context)));
    }

    /**
     * Cambio en catálogo de áreas o flags de area_settings.
     *
     * @param  array<string, mixed>  $context
     */
    public static function areaConfigChanged(string $event, array $context = []): void
    {
        self::channel()->info('laundry.area_config', array_merge([
            'event' => $event,
        ], self::sanitize($context)));
    }

    /**
     * @param  array<string, mixed>  $context
     * @return array<string, mixed>
     */
    private static function sanitize(array $context): array
    {
        $blocked = ['cliente_nombre', 'cliente_email', 'detalles_ropa', 'instrucciones', 'codigo_qr', 'folio_unico', 'password', 'delivery_address'];

        foreach ($blocked as $key) {
            unset($context[$key]);
        }

        return $context;
    }
}
