<?php

namespace App\Observers;

use App\Models\Order;
use App\Notifications\OrderStatusChangedNotification;
use App\Services\PointsService;

class OrderObserver
{
    protected PointsService $pointsService;

    public function __construct(PointsService $pointsService)
    {
        $this->pointsService = $pointsService;
    }

    public function saving(Order $order): void
    {
        if ($order->isDirty('payment_method_id') && $order->payment_method_id) {
            $pm = \App\Models\PaymentMethod::find($order->payment_method_id);
            if ($pm) {
                $order->payment_method = $pm->slug;
            }
        }
    }

    public function updating(Order $order): void
    {
        if ($order->isDirty('extra_charges')) {
            $order->recalculateTotal();
        }

        if (! $order->isDirty('status')) {
            return;
        }

        $newStatus = $order->status;
        $oldStatus = $order->getOriginal('status');

        if ($oldStatus === $newStatus) {
            return;
        }

        if ($newStatus === Order::STATUS_DELIVERED) {
            $this->pointsService->finalizePoints($order);
        }

        if ($newStatus === Order::STATUS_RETURNED) {
            $this->pointsService->reverseEarnedPoints($order);
            $this->pointsService->reverseRedeemedPoints($order);
        }

        $notifiableStatuses = [
            Order::STATUS_PROCESSING,
            Order::STATUS_SHIPPING,
            Order::STATUS_DELIVERED,
            Order::STATUS_RETURNED,
        ];

        if (in_array($newStatus, $notifiableStatuses) && $order->user) {
            $order->user->notify(
                new OrderStatusChangedNotification($order, $oldStatus, $newStatus)
            );
        }
    }
}
