<?php

namespace Tests\Feature;

use App\Jobs\SyncPackageToPaddle;
use App\Models\Package;
use App\Services\Paddle\PaddleCatalogService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Mockery;
use Tests\TestCase;

class SyncPackageToPaddleJobTest extends TestCase
{
    use RefreshDatabase;

    protected function tearDown(): void
    {
        parent::tearDown();

        Mockery::close();
    }

    public function test_job_creates_product_and_price_and_updates_package(): void
    {
        $package = Package::factory()->create([
            'paddle_product_id' => null,
            'paddle_price_id' => null,
            'price' => 15.50,
            'slug' => 'silver-plan',
        ]);

        $service = Mockery::mock(PaddleCatalogService::class);
        $service->shouldReceive('createProduct')
            ->once()
            ->withArgs(function ($pkg, $overrides) use ($package) {
                return $pkg->is($package) && $overrides === [];
            })
            ->andReturn(['id' => 'pro_123']);
        $service->shouldReceive('createPrice')
            ->once()
            ->withArgs(function ($pkg, $productId, $overrides) use ($package) {
                return $pkg->is($package) && $productId === 'pro_123' && $overrides === [];
            })
            ->andReturn(['id' => 'pri_123']);
        $service->shouldReceive('buildProductPayload')
            ->andReturn(['payload' => 'product']);
        $service->shouldReceive('buildPricePayload')
            ->andReturn(['payload' => 'price']);

        $job = new SyncPackageToPaddle($package->id);
        $job->handle($service);

        $package->refresh();

        $this->assertSame('pro_123', $package->paddle_product_id);
        $this->assertSame('pri_123', $package->paddle_price_id);
        $this->assertSame('synced', $package->paddle_sync_status);
        $this->assertNotNull($package->paddle_synced_at);
        $this->assertSame(['payload' => 'product'], $package->paddle_snapshot['payload']['product']);
        $this->assertSame(['payload' => 'price'], $package->paddle_snapshot['payload']['price']);
    }

    public function test_dry_run_stores_snapshot_without_calling_paddle(): void
    {
        $package = Package::factory()->create([
            'slug' => 'gold-plan',
        ]);

        $service = Mockery::mock(PaddleCatalogService::class);
        $service->shouldReceive('buildProductPayload')->andReturn(['payload' => 'product']);
        $service->shouldReceive('buildPricePayload')->andReturn(['payload' => 'price']);

        $job = new SyncPackageToPaddle($package->id, ['dry_run' => true]);
        $job->handle($service);

        $package->refresh();

        $this->assertSame('dry-run', $package->paddle_sync_status);
        $this->assertTrue($package->paddle_snapshot['dry_run']);
        $this->assertSame(['payload' => 'product'], $package->paddle_snapshot['payload']['product']);
        $this->assertSame(['payload' => 'price'], $package->paddle_snapshot['payload']['price']);
    }
}
