<?php

declare(strict_types=1);

namespace Tests\Feature\Academy;

use App\Models\AcademyBillingEvent;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Cache;
use Laravel\Cashier\Events\WebhookHandled;
use Laravel\Cashier\Events\WebhookReceived;
use Tests\TestCase;

final class AcademyStripeWebhookTest extends TestCase
{
    use RefreshDatabase;

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

        config()->set('academy_billing.plans', [
            'creator_monthly' => [
                'label' => 'Creator Monthly',
                'tier' => 'creator',
                'interval' => 'monthly',
                'stripe_price_id' => 'price_creator_month',
                'featured' => false,
            ],
            'pro_monthly' => [
                'label' => 'Pro Monthly',
                'tier' => 'pro',
                'interval' => 'monthly',
                'stripe_price_id' => 'price_pro_month',
                'featured' => true,
            ],
        ]);
    }

    public function test_webhook_listener_stores_safe_audit_summary_and_records_handling_outcome(): void
    {
        $user = User::factory()->create([
            'stripe_id' => 'cus_webhook_test',
            'email_verified_at' => now(),
        ]);

        Cache::put('academy.billing.account.'.$user->id, 'stale', 300);

        event(new WebhookReceived([
            'id' => 'evt_academy_billing_test',
            'type' => 'customer.subscription.updated',
            'data' => [
                'object' => [
                    'id' => 'sub_webhook_test',
                    'customer' => 'cus_webhook_test',
                    'status' => 'active',
                    'items' => [
                        'data' => [[
                            'price' => [
                                'id' => 'price_creator_month',
                            ],
                        ]],
                    ],
                    'metadata' => [
                        'academy_plan' => 'creator_monthly',
                        'academy_tier' => 'creator',
                        'user_id' => (string) $user->id,
                    ],
                ],
            ],
        ]));

        $subscription = $user->subscriptions()->create([
            'type' => 'academy',
            'stripe_id' => 'sub_webhook_test',
            'stripe_status' => 'active',
            'stripe_price' => 'price_creator_month',
            'quantity' => 1,
        ]);

        $subscription->items()->create([
            'stripe_id' => 'si_webhook_test',
            'stripe_product' => 'prod_creator_month',
            'stripe_price' => 'price_creator_month',
            'quantity' => 1,
        ]);

        event(new WebhookHandled([
            'id' => 'evt_academy_billing_test',
            'type' => 'customer.subscription.updated',
            'data' => [
                'object' => [
                    'id' => 'sub_webhook_test',
                    'customer' => 'cus_webhook_test',
                    'status' => 'active',
                    'items' => [
                        'data' => [[
                            'price' => [
                                'id' => 'price_creator_month',
                                'product' => 'prod_creator_month',
                            ],
                            'quantity' => 1,
                            'id' => 'si_webhook_test',
                        ]],
                    ],
                    'metadata' => [
                        'academy_plan' => 'creator_monthly',
                        'academy_tier' => 'creator',
                        'user_id' => (string) $user->id,
                    ],
                    'subscription' => 'sub_webhook_test',
                ],
            ],
        ]));

        $billingEvent = AcademyBillingEvent::query()->where('stripe_event_id', 'evt_academy_billing_test')->first();

        $this->assertNotNull($billingEvent);
        $this->assertSame('customer.subscription.updated', $billingEvent->event_type);
        $this->assertSame('creator_monthly', $billingEvent->academy_plan);
        $this->assertSame('creator', $billingEvent->academy_tier);
        $this->assertSame('cus_webhook_test', $billingEvent->stripe_customer_id);
        $this->assertSame(['price_creator_month'], $billingEvent->payload_summary['price_ids'] ?? []);
        $this->assertTrue($billingEvent->payload_summary['received'] ?? false);
        $this->assertTrue($billingEvent->payload_summary['handled'] ?? false);
        $this->assertSame('local_subscription_synced', $billingEvent->payload_summary['outcome'] ?? null);
        $this->assertTrue($billingEvent->payload_summary['cache_cleared'] ?? false);
        $this->assertFalse(Cache::has('academy.billing.account.'.$user->id));
    }
}