<?php

namespace App\Traits;

use App\Models\AuditTrail;
use Illuminate\Support\Facades\DB;

trait Auditable
{
    /**
     * Boot the auditable trait.
     *
     * This method is called automatically when the trait is booted.
     * It sets up event listeners for create, update, and delete actions.
     */
    public static function bootAuditable()
    {
        static::created(function ($model) {
            $model->logAction('create', $model->getAuditDescriptions()['create']);
        });

        static::updated(function ($model) {
            DB::table($model->getTable())->where('id', $model->id)->update(['last_updated_by' => tenant_user()->id]);
            $model->logAction('update', $model->getAuditDescriptions()['update']);
        });

        static::deleted(function ($model) {
            DB::table($model->getTable())->where('id', $model->id)->update(['deleted_by' => tenant_user()->id]);
            $model->logAction('delete', $model->getAuditDescriptions()['delete']);
        });
    }

    /**
     * Log an action with its description.
     *
     * @param string $action The action to log (e.g., 'create', 'update', 'delete')
     * @param string $description The description of the action
     */
    protected function logAction($action, $description)
    {
        if(!$description){
            return;
        }

        $module = 'HR';
        $user_id = tenant_user()->id;
        $old_data = $this->getOriginal();
        $new_data = $this->attributes;

        AuditTrail::create([
            'module' => $module,
            'user_id' => $user_id,
            'action' => $action,
            'description' => $description,
            'model_id' => $this->getKey(),
            'model' => static::class,
            'old_data' => json_encode($old_data),
            'new_data' => json_encode($new_data),
        ]);
    }

    /**
     * Get the audit descriptions for different actions.
     *
     * This method must be implemented by the class using the Auditable trait.
     *
     * @return array An array containing descriptions for different actions (e.g., ['create' => 'Created new department'])
     */
    abstract protected function getAuditDescriptions(): array;
}
