<?php

namespace App\Observers;

use App\Models\Listing;
use App\Services\AuditLogService;
use Illuminate\Support\Arr;

class ListingObserver
{
    private const AUDITABLE_FIELDS = [
        'consultant_profile_id',
        'category_id',
        'title',
        'slug',
        'short_description',
        'description',
        'price',
        'currency',
        'country',
        'city',
        'district',
        'neighborhood',
        'address',
        'latitude',
        'longitude',
        'gross_area',
        'net_area',
        'status',
        'rejection_reason',
        'is_featured',
        'published_at',
        'rejection_reason'
    ];

    public function __construct(private readonly AuditLogService $auditLog) {}







    public function created(Listing $listing): void
    {
        $this->auditLog->record(
            action: 'listing.create',
            subject: $listing,
            company_id: $this->companyId($listing),
            newvalues: Arr::only(
                $listing->getAttributes(),
                self::AUDITABLE_FIELDS
            ),
            metadata: $this->metadata($listing),

        );
    }


    public function updated(Listing $listing): void
    {
        $changes = Arr::only(
            $listing->getChanges(),
            self::AUDITABLE_FIELDS
        );

        if ($changes === []) {
            return;
        }

        $oldValues = [];

        foreach (array_keys($changes) as $field) {
            $oldValues[$field] = $listing->getOriginal($field);
        }



        $this->auditLog->record(

            action: $this->resolveUpdateAction($listing, $changes),

            subject: $listing,
            company_id: $this->companyId($listing),
            oldvalues: $oldValues,
            newvalues: $changes,
            metadata: $this->metadata($listing)
        );
    }


    public function deleted(Listing $listing): void
    {
        $this->auditLog->record(
            action: 'listing.delete',
            subject: $listing,
            company_id: $this->companyId($listing),
            oldvalues: Arr::only(
                $listing->getAttributes(),
                self::AUDITABLE_FIELDS
            ),
            metadata: $this->metadata($listing)


        );
    }


    public function restored(Listing $listing): void
    {
        $this->auditLog->record(
            action: 'listing.restored',
            subject: $listing,
            company_id: $this->companyId($listing),
            newvalues: [
                'restored_at' => now()->toISOString(),
            ],
            metadata: $this->metadata($listing),
        );
    }


    public function forceDeleted(Listing $listing): void
    {
        //
    }


    private function companyId(Listing $listing): ?int
    {
        // consultantProfile() relation objesi döndürür; modelin kendisi property ile okunur.
        // Bağımsız danışmanda company_id null'dır.
        return $listing->consultantProfile?->company_id;
    }

    private function metadata(Listing $listing): array
    {
        return [
            'listing_title' =>
            $listing->getTranslations('title'),

            'listing_slug' => $listing->slug,

            'consultant_profile_id' =>
            $listing->consultant_profile_id,
        ];
    }

    private function resolveUpdateAction(
        Listing $listing,
        array $changes
    ): string {
        if (! array_key_exists('status', $changes)) {
            return 'listing.updated';
        }

        return match ($listing->status) {
            'agency_approved' => 'listing.agency_approved',
            'published' => 'listing.published',
            'rejected' => 'listing.rejected',
            'pending' => 'listing.submitted',
            default => 'listing.status_changed',
        };
    }
}
