<?php

namespace Tests\Feature\Api;

use App\Models\User;
use App\Modules\Subscription\Models\Plan;
use App\Modules\Tenant\Models\Company;
use Database\Seeders\SaasCoreSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;

class SubscriptionSwitchApiTest extends TestCase
{
    use RefreshDatabase;

    public function test_owner_can_switch_company_plan(): void
    {
        $this->seed(SaasCoreSeeder::class);
        [$user, $company] = $this->createCompanyMember();
        $starter = Plan::query()->where('slug', 'starter')->firstOrFail();
        $business = Plan::query()->where('slug', 'business')->firstOrFail();

        $company->subscriptions()->create([
            'plan_id' => $starter->id,
            'billing_cycle' => 'monthly',
            'status' => 'trialing',
            'starts_at' => now(),
        ]);

        Sanctum::actingAs($user);

        $this->withHeader('X-Company-ID', (string) $company->id)
            ->postJson('/api/v1/tenant/subscription/switch-plan', [
                'plan_id' => $business->id,
                'billing_cycle' => 'yearly',
            ])
            ->assertOk()
            ->assertJsonPath('data.subscription.status', 'active')
            ->assertJsonPath('data.subscription.billing_cycle', 'yearly')
            ->assertJsonPath('data.subscription.plan.slug', 'business')
            ->assertJsonPath('data.subscription.plan.features.1.slug', 'pos');

        $this->assertDatabaseHas('subscriptions', [
            'company_id' => $company->id,
            'plan_id' => $starter->id,
            'status' => 'cancelled',
        ]);

        $this->assertDatabaseHas('subscriptions', [
            'company_id' => $company->id,
            'plan_id' => $business->id,
            'status' => 'active',
            'billing_cycle' => 'yearly',
        ]);
    }

    public function test_member_cannot_switch_company_plan(): void
    {
        $this->seed(SaasCoreSeeder::class);
        [$user, $company] = $this->createCompanyMember(role: 'member');
        $business = Plan::query()->where('slug', 'business')->firstOrFail();

        Sanctum::actingAs($user);

        $this->withHeader('X-Company-ID', (string) $company->id)
            ->postJson('/api/v1/tenant/subscription/switch-plan', [
                'plan_id' => $business->id,
            ])
            ->assertForbidden();
    }

    public function test_inactive_plan_cannot_be_selected(): void
    {
        $this->seed(SaasCoreSeeder::class);
        [$user, $company] = $this->createCompanyMember();
        $plan = Plan::query()->create([
            'name' => 'Hidden',
            'slug' => 'hidden',
            'monthly_price' => 100,
            'yearly_price' => 1000,
            'trial_days' => 0,
            'is_active' => false,
        ]);

        Sanctum::actingAs($user);

        $this->withHeader('X-Company-ID', (string) $company->id)
            ->postJson('/api/v1/tenant/subscription/switch-plan', [
                'plan_id' => $plan->id,
            ])
            ->assertNotFound();
    }

    /**
     * @return array{0: User, 1: Company}
     */
    private function createCompanyMember(string $role = 'owner'): array
    {
        $user = User::factory()->create();
        $company = Company::query()->create([
            'name' => 'ABC Grocery',
            'slug' => 'abc-grocery',
            'status' => 'active',
        ]);

        $company->users()->attach($user->id, [
            'role' => $role,
            'joined_at' => now(),
        ]);

        return [$user, $company];
    }
}
