<?php

namespace Tests\Feature;

use App\Models\Coupon;
use App\Models\Package;
use App\Models\Tenant;
use App\Models\User;
use App\Services\Coupons\CouponService;
use App\Services\Paddle\PaddleCheckoutService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Mockery;
use Tests\TestCase;

class PaddleCheckoutControllerTest extends TestCase
{
    use RefreshDatabase;

    protected function tearDown(): void
    {
        Mockery::close();

        parent::tearDown();
    }

    public function test_authenticated_user_can_create_checkout_with_coupon(): void
    {
        $tenant = Tenant::factory()->create([
            'paddle_customer_id' => 'cus_123',
        ]);

        $user = User::factory()->for($tenant)->create();

        $package = Package::factory()->create([
            'paddle_price_id' => 'pri_123',
            'paddle_product_id' => 'pro_123',
            'price' => 120,
        ]);

        $coupon = Coupon::factory()->create([
            'code' => 'SAVE15',
            'paddle_discount_id' => 'dsc_123',
        ]);
        $coupon->packages()->attach($package);

        $couponServiceMock = Mockery::mock(CouponService::class);
        $couponServiceMock->shouldReceive('preview')
            ->once()
            ->andReturn([
                'coupon' => $coupon,
                'pricing' => [
                    'currency' => 'EUR',
                    'subtotal' => 120.0,
                    'discount' => 18.0,
                    'tax' => 0,
                    'total' => 102.0,
                    'formatted' => [
                        'subtotal' => '€120.00',
                        'discount' => '-€18.00',
                        'tax' => '€0.00',
                        'total' => '€102.00',
                    ],
                    'breakdown' => [],
                ],
                'source' => 'manual',
            ]);
        $this->instance(CouponService::class, $couponServiceMock);

        $paddleServiceMock = Mockery::mock(PaddleCheckoutService::class);
        $paddleServiceMock->shouldReceive('createCheckout')
            ->once()
            ->andReturn([
                'checkout_url' => 'https://example.com/checkout/test',
                'id' => 'chk_123',
            ]);
        $this->instance(PaddleCheckoutService::class, $paddleServiceMock);

        $this->be($user);

        $response = $this->postJson(route('paddle.checkout.create'), [
            'package_id' => $package->id,
            'coupon_code' => 'SAVE15',
            'accepted_terms' => true,
        ]);

        $response->assertOk()
            ->assertJsonPath('checkout_url', 'https://example.com/checkout/test')
            ->assertJsonStructure([
                'checkout_session_id',
            ]);

        $this->assertDatabaseHas('checkout_sessions', [
            'package_id' => $package->id,
            'coupon_code' => 'SAVE15',
        ]);
    }
}
