<?php

namespace App\Observers;

use App\Services\Stats\StatEventService;
use Illuminate\Database\Eloquent\Model;

class StatEventObserver
{
    private static array $domainMap = [
        'App\Models\Tenants\Order' => 'sales',
        'App\Models\Tenants\Sale' => 'sales',
        'App\Models\Tenants\Deposit' => 'finance',
        'App\Models\Tenants\Withdrawal' => 'finance',
        'App\Models\Tenants\Purchase' => 'finance',
        'App\Models\Production\WorkOrder' => 'production',
        'App\Models\Tenants\Approval' => 'system',
    ];

    public function created(Model $model): void
    {
        $this->recordEvent($model, 'created');
    }

    public function updated(Model $model): void
    {
        $this->recordEvent($model, 'updated');
    }

    public function deleted(Model $model): void
    {
        $this->recordEvent($model, 'deleted');
    }

    private function recordEvent(Model $model, string $action): void
    {
        $tenantId = $model->getAttribute('tenant_id');
        if (! $tenantId) {
            return;
        }

        $className = get_class($model);
        $domain = self::$domainMap[$className] ?? 'other';
        $entityType = class_basename($model);
        $eventType = strtolower($entityType).'_'.$action;

        $payload = match ($action) {
            'created' => $this->getCreatedPayload($model),
            'updated' => $this->getUpdatedPayload($model),
            'deleted' => ['id' => $model->getKey()],
            default => null,
        };

        app(StatEventService::class)->recordEvent(
            $tenantId,
            $domain,
            $eventType,
            $entityType,
            $model->getKey(),
            $payload
        );
    }

    private function getCreatedPayload(Model $model): array
    {
        $payload = ['id' => $model->getKey()];

        if ($model->getAttribute('total_amount') !== null) {
            $payload['amount'] = $model->getAttribute('total_amount');
        }
        if ($model->getAttribute('amount') !== null) {
            $payload['amount'] = $model->getAttribute('amount');
        }
        if ($model->getAttribute('status') !== null) {
            $payload['status'] = $model->getAttribute('status');
        }

        return $payload;
    }

    private function getUpdatedPayload(Model $model): array
    {
        $changed = $model->getChanges();
        $payload = ['id' => $model->getKey()];

        if (isset($changed['status'])) {
            $payload['old_status'] = $model->getOriginal('status');
            $payload['new_status'] = $changed['status'];
        }
        if (isset($changed['total_amount']) || isset($changed['amount'])) {
            $payload['amount'] = $changed['total_amount'] ?? $changed['amount'];
        }

        return $payload;
    }
}
