<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

/**
 * One timeline entry (§65A).
 *
 * The technical diff is only attached for readers holding `audit.view`;
 * everyone else gets the human-readable line.
 */
class ActivityResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        $canAudit = $request->user()?->can('audit.view') ?? false;

        return [
            'id' => $this->uuid,
            'category' => $this->event_category->value,
            'category_label' => $this->event_category->label(),
            'action' => $this->event_action,
            'title' => $this->event_title,
            'description' => $this->event_description,

            'actor' => $this->actorName(),
            'actor_role' => $this->actor_role_snapshot,
            'is_system' => (bool) $this->is_system,

            'subject' => $this->whenLoaded('subject', fn () => $this->subject ? [
                'type' => class_basename($this->subject_type),
                'id' => $this->subject->uuid ?? null,
                'name' => $this->subject->full_name
                    ?? $this->subject->name
                    ?? $this->subject->company_name
                    ?? null,
                'reference' => $this->subject->reference_no ?? $this->subject->agent_code ?? null,
            ] : null),

            'metadata' => $this->metadata,
            'created_at' => $this->created_at?->toIso8601String(),

            // §65A "Before / After View" — the expandable technical detail.
            $this->mergeWhen($canAudit, fn () => [
                'changes' => $this->buildChanges(),
                'ip_address' => $this->ip_address,
                'request_id' => $this->request_id,
            ]),
        ];
    }

    /**
     * @return array<int, array{field: string, label: string, before: mixed, after: mixed}>
     */
    private function buildChanges(): array
    {
        $new = $this->new_values ?? [];
        $old = $this->old_values ?? [];

        return collect($new)
            ->map(fn ($value, $field) => [
                'field' => $field,
                'label' => ucfirst(str_replace('_', ' ', $field)),
                'before' => $old[$field] ?? null,
                'after' => $value,
            ])
            ->values()
            ->all();
    }
}
