<?php

namespace Tests\Feature;

use App\Domain\Subscription\MetricsService;
use App\Domain\Subscription\PaymentApprovalService;
use App\Domain\Subscription\SubscriptionService;
use App\Models\ActivityLog;
use App\Models\Plan;
use App\Models\SubscriptionPayment;
use App\Models\Tenant;
use App\Models\User;
use App\Support\Tenancy;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class BillingActivityLogTest extends TestCase
{
    use RefreshDatabase;

    protected function setUp(): void
    {
        parent::setUp();
        $this->seed();
    }

    protected function gracedTenant(): Tenant
    {
        $tenant = Tenant::create(['name' => 'C', 'slug' => 'c', 'status' => 'grace']);
        $tenant->subscription()->create([
            'plan_id' => Plan::first()->id, 'status' => 'grace',
            'starts_at' => now()->subMonth(), 'current_period_ends_at' => now()->subDay(),
            'grace_ends_at' => now()->addDays(5),
        ]);

        return $tenant;
    }

    public function test_approval_writes_activity_and_conversion_events(): void
    {
        $tenant = $this->gracedTenant();
        $plan = Plan::first();
        app(Tenancy::class)->set($tenant);
        $payment = SubscriptionPayment::create([
            'tenant_id' => $tenant->id, 'plan_id' => $plan->id,
            'gateway' => 'zaincash', 'amount' => $plan->price_monthly_iqd,
            'currency' => 'IQD', 'status' => 'pending', 'period_months' => 1,
        ]);

        $reviewer = User::withoutEvents(fn () => User::create([
            'tenant_id' => null, 'name' => 'Admin', 'email' => 'a@medibookai.com', 'password' => 'password123',
        ]));
        $reviewer->assignRole('super_admin');

        app(PaymentApprovalService::class)->approve($payment, $reviewer->id, 'ok', '1.1.1.1');

        $this->assertDatabaseHas('activity_logs', ['event' => 'payment.approved', 'tenant_id' => $tenant->id]);
        $this->assertDatabaseHas('activity_logs', ['event' => 'subscription.activated', 'tenant_id' => $tenant->id]);
        $this->assertDatabaseHas('activity_logs', ['event' => 'trial.converted', 'tenant_id' => $tenant->id]);
        $this->assertNotNull($tenant->fresh()->subscription_converted_at);
    }

    public function test_lifecycle_logs_grace_and_expiry(): void
    {
        $tenant = Tenant::create(['name' => 'D', 'slug' => 'd', 'status' => 'active']);
        $tenant->subscription()->create([
            'plan_id' => Plan::first()->id, 'status' => 'active',
            'starts_at' => now()->subMonth(), 'current_period_ends_at' => now()->subDay(),
        ]);

        app(SubscriptionService::class)->runLifecycle();
        $this->assertDatabaseHas('activity_logs', ['event' => 'subscription.grace']);

        $tenant->subscription->update(['grace_ends_at' => now()->subDay()]);
        app(SubscriptionService::class)->runLifecycle();
        $this->assertDatabaseHas('activity_logs', ['event' => 'trial.expired']);
    }

    public function test_trial_funnel_counts(): void
    {
        // started (3), one converted
        foreach (range(1, 3) as $i) {
            $t = Tenant::create(['name' => "T$i", 'slug' => "t$i"]);
            $t->subscription()->create([
                'plan_id' => Plan::first()->id, 'status' => $i === 1 ? 'active' : 'trialing',
                'starts_at' => now(), 'current_period_ends_at' => now()->addDays(10),
            ]);
            if ($i === 1) {
                $t->update(['subscription_converted_at' => now()]);
            }
        }

        $funnel = app(MetricsService::class)->trialFunnel();
        $this->assertSame(3, $funnel['started']);
        $this->assertSame(1, $funnel['converted']);
    }

    public function test_revenue_by_method_groups_gateways(): void
    {
        $tenant = $this->gracedTenant();
        $plan = Plan::first();
        foreach (['zaincash', 'superqi', 'zaincash'] as $g) {
            SubscriptionPayment::create([
                'tenant_id' => $tenant->id, 'plan_id' => $plan->id,
                'gateway' => $g, 'amount' => 50000, 'currency' => 'IQD',
                'status' => 'approved', 'period_months' => 1,
            ]);
        }

        $rev = app(MetricsService::class)->revenueByMethod();
        $zain = $rev->firstWhere('gateway', 'zaincash');
        $this->assertSame(2, $zain['count']);
        $this->assertSame(100000, $zain['total_iqd']);
    }
}
