<?php

namespace Tests\Feature;

use App\Models\Branch;
use App\Models\Category;
use App\Models\Customer;
use App\Models\CustomerNotification;
use App\Models\Product;
use App\Models\User;
use App\Services\OrderService;
use App\Services\ProgressService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Hash;
use Tests\TestCase;

class CustomerNotificationTest extends TestCase
{
    use RefreshDatabase;

    public function test_progress_update_creates_portal_notification_and_customer_can_read_it(): void
    {
        [$staff, $customer, $order] = $this->fixtures();

        app(ProgressService::class)->updateProgress($order, 'siap_diambil_atau_dikirim', $staff, 'Barang sudah siap.');

        $notification = CustomerNotification::query()
            ->where('customer_id', $customer->id)
            ->where('order_id', $order->id)
            ->where('title', 'Barang siap diambil/dikirim')
            ->firstOrFail();

        $this->assertSame('Barang siap diambil/dikirim', $notification->title);

        $this->withSession(['customer_id' => $customer->id])
            ->get(route('portal.dashboard'))
            ->assertOk()
            ->assertSee('Aktifkan Notifikasi')
            ->assertSee('Install PWA');

        $this->withSession(['customer_id' => $customer->id])
            ->get(route('portal.notifications'))
            ->assertOk()
            ->assertSee('Barang siap diambil');

        $this->withSession(['customer_id' => $customer->id])
            ->post(route('portal.notifications.read', $notification))
            ->assertRedirect();

        $this->assertNotNull($notification->refresh()->read_at);
    }

    public function test_customer_can_store_push_subscription(): void
    {
        [$staff, $customer] = $this->fixtures();

        $this->withSession(['customer_id' => $customer->id])
            ->postJson(route('portal.push-subscriptions.store'), [
                'endpoint' => 'https://push.example.test/subscription/'.$staff->id,
                'keys' => [
                    'p256dh' => 'public-key',
                    'auth' => 'auth-token',
                ],
            ])
            ->assertOk()
            ->assertJson(['ok' => true]);

        $this->assertDatabaseHas('customer_push_subscriptions', [
            'customer_id' => $customer->id,
            'endpoint' => 'https://push.example.test/subscription/'.$staff->id,
        ]);
    }

    private function fixtures(): array
    {
        $branch = Branch::query()->create(['name' => 'Cabang Notifikasi', 'code' => 'NTF']);
        $staff = User::query()->create([
            'branch_id' => $branch->id,
            'name' => 'Staff Notifikasi',
            'email' => 'staff-notifikasi@example.test',
            'role' => 'kasir',
            'password' => Hash::make('password'),
        ]);
        $customer = Customer::query()->create([
            'branch_id' => $branch->id,
            'name' => 'Customer Notifikasi',
            'phone' => '62817778888',
            'pin' => Hash::make('000000'),
        ]);
        $category = Category::query()->create(['name' => 'Service', 'type' => 'service']);
        $service = Product::query()->create([
            'category_id' => $category->id,
            'name' => 'Cuci Notifikasi',
            'sku' => 'SRV-NTF',
            'type' => 'service',
            'unit' => 'kg',
            'price' => 10000,
            'is_active' => true,
        ]);
        $order = app(OrderService::class)->checkout([
            'branch_id' => $branch->id,
            'customer_id' => $customer->id,
            'items' => [['product_id' => $service->id, 'quantity' => 1, 'staff_id' => $staff->id]],
            'paid_amount' => 10000,
        ], $staff);

        return [$staff, $customer, $order];
    }
}
