<?php

namespace Tests\Feature;

use App\Domain\Subscription\MetricsService;
use App\Models\Plan;
use App\Models\SubscriptionPayment;
use App\Models\Tenant;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class MetricsServiceTest extends TestCase
{
    use RefreshDatabase;

    protected function makeSub(string $status, int $mrr, bool $demo = false, $cancelledAt = null): Tenant
    {
        $tenant = Tenant::create(['name' => 'C', 'slug' => 'c'.rand(10000, 99999), 'is_demo' => $demo]);
        $tenant->subscription()->create([
            'plan_id' => Plan::first()->id, 'status' => $status, 'is_demo' => $demo,
            'starts_at' => now()->subMonth(), 'current_period_ends_at' => now()->addMonth(),
            'mrr_iqd' => $mrr, 'cancelled_at' => $cancelledAt,
        ]);

        return $tenant;
    }

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

    public function test_mrr_sums_active_only_excluding_demo(): void
    {
        $this->makeSub('active', 50000);
        $this->makeSub('active', 50000);
        $this->makeSub('trialing', 50000);   // not counted in MRR
        $this->makeSub('active', 999999, demo: true); // demo excluded

        $metrics = app(MetricsService::class);
        $this->assertSame(100000, $metrics->mrr());
        $this->assertSame(1200000, $metrics->arr());
    }

    public function test_counts(): void
    {
        $this->makeSub('trialing', 0);
        $this->makeSub('active', 50000);
        $this->makeSub('grace', 0);
        $this->makeSub('suspended', 0);

        $counts = app(MetricsService::class)->counts();
        $this->assertSame(1, $counts['trialing']);
        $this->assertSame(1, $counts['active']);
        $this->assertSame(1, $counts['grace']);
        $this->assertSame(1, $counts['suspended']);
    }

    public function test_churn_rate(): void
    {
        $this->makeSub('active', 50000);
        $this->makeSub('active', 50000);
        $this->makeSub('active', 50000);
        $this->makeSub('cancelled', 0, cancelledAt: now());

        // 1 cancelled / (3 active + 1 cancelled) = 25%
        $this->assertSame(25.0, app(MetricsService::class)->churnRate());
    }

    public function test_revenue_by_month_normalizes_currency(): void
    {
        $tenant = $this->makeSub('active', 50000);
        SubscriptionPayment::create([
            'tenant_id' => $tenant->id, 'plan_id' => Plan::first()->id,
            'gateway' => 'zaincash', 'amount' => 50000, 'currency' => 'IQD',
            'status' => 'approved', 'period_months' => 1,
        ]);
        SubscriptionPayment::create([
            'tenant_id' => $tenant->id, 'plan_id' => Plan::first()->id,
            'gateway' => 'paddle', 'amount' => 3500, 'currency' => 'USD', // $35
            'status' => 'approved', 'period_months' => 1,
        ]);

        $series = app(MetricsService::class)->revenueByMonth(6);
        $thisMonth = $series->last();
        // 50,000 IQD + ($35 * 1320) = 50,000 + 46,200 = 96,200
        $this->assertSame(96200, $thisMonth['total']);
    }

    public function test_mrr_by_gateway(): void
    {
        $a = $this->makeSub('active', 50000);
        $a->subscription->update(['gateway' => 'zaincash']);
        $b = $this->makeSub('active', 50000);
        $b->subscription->update(['gateway' => 'paddle']);

        $rows = app(MetricsService::class)->mrrByGateway();
        $this->assertSame(100000, (int) $rows->sum('total'));
    }
}
