<?php

namespace Tests\Feature;

use App\Jobs\SendOrderPlacementNotificationsJob;
use App\Models\Order;
use App\Models\Product;
use App\Models\User;
use App\Services\OrderPlacementNotificationService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Queue;
use Tests\TestCase;

class OrderPlacementNotificationJobTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();
        $this->seed();
    }

    public function test_pos_order_dispatches_placement_notification_job_after_response(): void
    {
        Queue::fake();

        $staff = User::factory()->create();
        $staff->assignRole('staff');

        $customer = User::factory()->create();

        $product = Product::factory()->create([
            'price' => 100.00,
            'purchase_price' => 60.00,
            'current_stock' => 10,
        ]);

        $this->actingAs($staff);

        $response = $this->postJson('/admin/api/pos/orders', [
            'user_id' => $customer->id,
            'items' => [
                [
                    'product_id' => $product->id,
                    'qty' => 1,
                    'price' => 100.00,
                ],
            ],
            'payment_method' => 'cash',
            'subtotal' => 100.00,
            'discount_total' => 0,
            'tax_total' => 0,
            'total_payable' => 100.00,
        ]);

        $response->assertStatus(201);

        $orderId = $response->json('data.order_id');

        Queue::assertPushed(SendOrderPlacementNotificationsJob::class, function (SendOrderPlacementNotificationsJob $job) use ($orderId, $staff) {
            return $job->orderId === $orderId
                && $job->channel === OrderPlacementNotificationService::CHANNEL_POS
                && $job->staffId === $staff->id;
        });
    }

    public function test_service_dispatches_online_channel_job_after_response(): void
    {
        Queue::fake();

        $customer = User::factory()->create();
        $order = Order::create([
            'user_id' => $customer->id,
            'source' => 'online',
            'address_snapshot' => ['name' => $customer->name, 'mobile' => $customer->mobile],
            'subtotal' => 100,
            'discount_total' => 0,
            'tax_total' => 0,
            'shipping_total' => 0,
            'total_payable' => 100,
            'payment_status' => Order::PAYMENT_PAID,
            'payment_method' => 'online',
            'status' => Order::STATUS_PLACED,
            'placed_at' => now(),
        ]);

        app(OrderPlacementNotificationService::class)->dispatchAfterPlacement(
            $order,
            OrderPlacementNotificationService::CHANNEL_ONLINE
        );

        Queue::assertPushed(SendOrderPlacementNotificationsJob::class, function (SendOrderPlacementNotificationsJob $job) use ($order) {
            return $job->orderId === $order->id
                && $job->channel === OrderPlacementNotificationService::CHANNEL_ONLINE
                && $job->staffId === null;
        });
    }
}
