<?php

namespace App\Livewire\Audit;

use App\Models\AuditEvent;
use App\Models\Setting;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Livewire\Attributes\Layout;
use Livewire\Component;

#[Layout('layouts.app')]
class Index extends Component
{
    /** Freitext-Filter über Akteur / Aktion / Ziel / Server. */
    public string $q = '';

    /**
     * Aufbewahrungsdauer in Tagen (Formularfeld). Leer/0 = unbegrenzt; ein
     * positiver Wert N löscht beim täglichen Prune Einträge älter als N Tage.
     */
    public ?string $retentionDays = null;

    public function mount(): void
    {
        // Empty/0 means "keep forever" — surface that as a blank field, not "0".
        $stored = (int) Setting::get('audit_retention_days', '0');
        $this->retentionDays = $stored > 0 ? (string) $stored : null;
    }

    /** Persist the retention policy, audit the change and notify the operator. */
    public function saveRetention(): void
    {
        $validated = $this->validate([
            'retentionDays' => ['nullable', 'integer', 'min:1', 'max:3650'],
        ]);

        $days = $validated['retentionDays'] !== null && $validated['retentionDays'] !== ''
            ? (int) $validated['retentionDays']
            : 0;

        Setting::put('audit_retention_days', $days > 0 ? (string) $days : null);
        $this->retentionDays = $days > 0 ? (string) $days : null;

        AuditEvent::create([
            'user_id' => Auth::id(),
            'actor' => Auth::user()?->name ?? 'system',
            'action' => 'audit.retention_set',
            'target' => 'audit_retention_days='.$days,
            'ip' => request()->ip(),
        ]);

        $this->dispatch('notify', message: __('audit.retention_saved_notify'));
    }

    /** Effective retention in days (0 = unlimited) for the policy summary. */
    protected function retentionPolicy(): int
    {
        return $this->retentionDays !== null && $this->retentionDays !== ''
            ? (int) $this->retentionDays
            : 0;
    }

    /**
     * Letzte Audit-Ereignisse, optional gefiltert. Echte Daten aus der DB;
     * die Filterung läuft im Speicher über die geladenen 50 Einträge.
     */
    protected function events(): Collection
    {
        $events = AuditEvent::with('server')->latest()->limit(50)->get();

        $needle = trim($this->q);

        if ($needle === '') {
            return $events;
        }

        $needle = mb_strtolower($needle);

        return $events->filter(function (AuditEvent $e) use ($needle): bool {
            $haystack = mb_strtolower(implode(' ', array_filter([
                $e->actor,
                $e->action,
                $e->target,
                $e->server?->name,
            ])));

            return str_contains($haystack, $needle);
        })->values();
    }

    public function render()
    {
        return view('livewire.audit.index', [
            'events' => $this->events(),
            'retentionPolicy' => $this->retentionPolicy(),
        ])->title(__('audit.title'));
    }
}
