<?php

namespace App\Models\Concerns;

use App\Models\AuditLog;
use Illuminate\Database\Eloquent\SoftDeletes;

trait Auditable
{
    public static function bootAuditable(): void
    {
        static::created(fn ($model) => $model->writeAudit('criado', [], $model->getAttributes()));

        static::updated(function ($model): void {
            $changes = $model->getChanges();
            unset($changes['updated_at']);

            if ($changes !== []) {
                $old = [];
                foreach (array_keys($changes) as $attribute) {
                    $old[$attribute] = $model->getOriginal($attribute);
                }
                $model->writeAudit('alterado', $old, $changes);
            }
        });

        static::deleted(fn ($model) => $model->writeAudit('eliminado_ou_arquivado', $model->getOriginal(), []));

        if (in_array(SoftDeletes::class, class_uses_recursive(static::class), true)) {
            static::restored(fn ($model) => $model->writeAudit('restaurado', [], $model->getAttributes()));
        }
    }

    protected function writeAudit(string $event, array $oldValues, array $newValues): void
    {
        if (! app()->bound('db') || ! \Illuminate\Support\Facades\Schema::hasTable('audit_logs')) {
            return;
        }

        foreach (['password', 'remember_token'] as $sensitiveAttribute) {
            unset($oldValues[$sensitiveAttribute], $newValues[$sensitiveAttribute]);
        }

        AuditLog::query()->create([
            'actor_id' => auth()->id(),
            'branch_id' => session('active_branch_id'),
            'event' => $event,
            'auditable_type' => static::class,
            'auditable_id' => $this->getKey(),
            'description' => class_basename(static::class).' '.$event,
            'old_values' => $oldValues ?: null,
            'new_values' => $newValues ?: null,
            'ip_address' => request()?->ip(),
            'user_agent' => request()?->userAgent(),
        ]);
    }
}
