<?php

declare(strict_types=1);

namespace App\Exports;

use App\Models\AuditLog;
use Illuminate\Database\Eloquent\Builder;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;

/**
 * The audit trail as a spreadsheet, honouring the same filters as
 * `audit.index` — "export" always means "export what I am looking at".
 */
class AuditLogExport implements FromQuery, ShouldAutoSize, WithHeadings, WithMapping
{
    /**
     * @param  array<string, string>  $filters
     */
    public function __construct(
        private readonly array $filters = [],
    ) {}

    public function query(): Builder
    {
        return AuditLog::query()
            ->with('user')
            ->when(($this->filters['search'] ?? '') !== '', fn (Builder $q) => $q->where('description', 'like', '%'.$this->filters['search'].'%'))
            ->when(($this->filters['user_id'] ?? '') !== '', fn (Builder $q) => $q->byUser((int) $this->filters['user_id']))
            ->when(($this->filters['module'] ?? '') !== '', fn (Builder $q) => $q->where('auditable_type', $this->filters['module']))
            ->when(($this->filters['event'] ?? '') !== '', fn (Builder $q) => $q->byEvent($this->filters['event']))
            ->betweenDates(
                ($this->filters['date_from'] ?? '') !== '' ? $this->filters['date_from'] : null,
                ($this->filters['date_to'] ?? '') !== '' ? $this->filters['date_to'] : null,
            )
            ->latest();
    }

    /**
     * @return array<int, string>
     */
    public function headings(): array
    {
        return ['Timestamp', 'User', 'Event', 'Module', 'Record ID', 'Description', 'IP Address'];
    }

    /**
     * @param  AuditLog  $log
     * @return array<int, mixed>
     */
    public function map($log): array
    {
        return [
            $log->created_at->format('Y-m-d H:i:s'),
            $log->user->name ?? 'System',
            $log->event->label(),
            $log->auditable_type ? class_basename($log->auditable_type) : null,
            $log->auditable_id,
            $log->description,
            $log->ip_address,
        ];
    }
}
