<?php

namespace Maestro\Core\DataTables\Resources;

use Maestro\Core\DataTables\DataTableResource;
use App\Services\Access\PermissionResolver;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Spatie\Activitylog\Models\Activity;

/**
 * DataTable resource for the global activity log (audit log).
 * Backed by Spatie\Activitylog\Models\Activity.
 */
class ActivityLogTable implements DataTableResource
{
    public function key(): string
    {
        return 'activity-log';
    }

    /**
     * Require authenticated user with module access to activity log (resolver global or Spatie).
     */
    public function authorize(Request $request): void
    {
        if (! $request->user()) {
            throw new AuthorizationException('You are not authorized to access this DataTable resource.');
        }

        $resolver = app(PermissionResolver::class);
        if (! $resolver->userHasModuleAccess($request->user(), 'activitylog.view')) {
            throw new AuthorizationException('You do not have permission to view the activity log.');
        }
    }

    /**
     * Base query: all activities, newest first. Causer eager loaded for labels.
     */
    public function baseQuery(Request $request): Builder
    {
        return Activity::query()
            ->with(['causer']);
    }

    public function columns(): array
    {
        return [
            [
                'key' => 'id',
                'expr' => 'activity_log.id',
                'type' => 'number',
                'sortable' => true,
                'searchable' => false,
                'filterable' => false,
                'filterMode' => 'equals',
                'label' => __('datatable.columns.activity-log.id'),
                'defaultVisible' => false,
            ],
            [
                'key' => 'created_at',
                'expr' => 'activity_log.created_at',
                'type' => 'date',
                'sortable' => true,
                'searchable' => false,
                'filterable' => false,
                'filterMode' => 'date_equals',
                'label' => __('datatable.columns.activity-log.created_at'),
                'defaultVisible' => true,
            ],
            [
                'key' => 'event',
                'expr' => 'activity_log.event',
                'type' => 'text',
                'sortable' => true,
                'searchable' => true,
                'filterable' => true,
                'filterMode' => 'equals',
                'label' => __('datatable.columns.activity-log.event'),
                'defaultVisible' => true,
            ],
            [
                'key' => 'description',
                'expr' => 'activity_log.description',
                'type' => 'text',
                'sortable' => false,
                'searchable' => true,
                'filterable' => true,
                'filterMode' => 'contains',
                'label' => __('datatable.columns.activity-log.description'),
                'defaultVisible' => true,
            ],
            [
                'key' => 'user_label',
                'expr' => 'activity_log.causer_id',
                'type' => 'text',
                'sortable' => false,
                'searchable' => true,
                'filterable' => true,
                'filterMode' => 'contains',
                'label' => __('datatable.columns.activity-log.user_label'),
                'defaultVisible' => true,
            ],
            [
                'key' => 'subject_label',
                'expr' => 'activity_log.subject_id',
                'type' => 'text',
                'sortable' => false,
                'searchable' => false,
                'filterable' => true,
                'filterMode' => 'contains',
                'label' => __('datatable.columns.activity-log.subject_label'),
                'defaultVisible' => true,
            ],
        ];
    }

    /**
     * @param  object  $model  Activity instance (with causer loaded)
     * @return array<string, mixed>
     */
    public function transformRow(object $model): array
    {
        $createdAt = $model->created_at ?? null;

        $causer = $model->causer;
        $userLabel = null;
        if ($causer) {
            $userLabel = $causer->name ?? $causer->email ?? (string) $causer->getKey();
        }

        $subjectLabel = null;
        $subjectType = $model->subject_type;
        $subjectId = $model->subject_id;
        if (! $subjectType && $subjectId === null) {
            $subjectLabel = null;
        } else {
            $short = $subjectType ? preg_replace('/^App\\\\Models\\\\/', '', (string) $subjectType) : '';
            $subjectLabel = $subjectId !== null ? sprintf('%s #%s', $short, $subjectId) : ($short ?: null);
            if ($subjectLabel !== null && $subjectLabel !== '') {
                $subjectLabel = mb_strtoupper(mb_substr($subjectLabel, 0, 1)) . mb_substr($subjectLabel, 1);
            }
        }

        return [
            'id' => $model->id,
            'created_at' => $createdAt instanceof \DateTimeInterface ? $createdAt->format('c') : (string) $createdAt,
            'event' => $model->event ?? 'action',
            'description' => $model->description,
            'user_label' => $userLabel,
            'subject_label' => $subjectLabel,
        ];
    }
}

