<?php

namespace Tests\Unit;

use App\Filament\Widgets\RevenueTrendWidget;
use App\Models\PurchaseHistory;
use App\Models\Tenant;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Carbon;
use ReflectionClass;
use Tests\TestCase;

class AdminDashboardWidgetsTest extends TestCase
{
    use RefreshDatabase;

    protected function tearDown(): void
    {
        parent::tearDown();
        Carbon::setTestNow();
    }

    public function test_revenue_trend_widget_compiles_monthly_totals(): void
    {
        Carbon::setTestNow(Carbon::create(2025, 10, 20, 12));

        $tenant = Tenant::factory()->create();
        $packagePro = \App\Models\Package::factory()->create(['name' => 'Pro Pack']);
        $packageStarter = \App\Models\Package::factory()->create(['name' => 'Starter Pack']);

        PurchaseHistory::create([
            'tenant_id' => $tenant->id,
            'package_id' => $packagePro->id,
            'price' => 299.99,
            'currency' => 'EUR',
            'platform' => 'web',
            'transaction_id' => 'txn-cur',
            'purchased_at' => now()->copy()->startOfMonth()->addDays(2),
            'created_at' => now(),
        ]);

        PurchaseHistory::create([
            'tenant_id' => $tenant->id,
            'package_id' => $packageStarter->id,
            'price' => 149.90,
            'currency' => 'EUR',
            'platform' => 'web',
            'transaction_id' => 'txn-prev',
            'purchased_at' => now()->copy()->subMonth()->startOfMonth()->addDays(4),
            'created_at' => now()->subMonth(),
        ]);

        $widget = new RevenueTrendWidget();
        $data = $this->invokeProtectedMethod($widget, 'getData');

        $this->assertArrayHasKey('datasets', $data);
        $this->assertArrayHasKey('labels', $data);
        $this->assertCount(12, $data['labels']);
        $this->assertSame(12, count($data['datasets'][0]['data']));

        $lastValue = end($data['datasets'][0]['data']);
        $prevValue = $data['datasets'][0]['data'][count($data['datasets'][0]['data']) - 2];

        $this->assertEquals(299.99, $lastValue);
        $this->assertEquals(149.90, $prevValue);
    }

    /**
     * @template T
     *
     * @param  object  $object
     * @param  string  $method
     * @return mixed
     */
    private function invokeProtectedMethod(object $object, string $method)
    {
        $reflection = new ReflectionClass($object);
        $reflectedMethod = $reflection->getMethod($method);
        $reflectedMethod->setAccessible(true);

        return $reflectedMethod->invoke($object);
    }
}
