<?php

namespace Tests\Feature;

use App\Models\Customer;
use App\Models\Tenant;
use App\Models\User;
use App\Services\Billing\BillingProfileService;
use App\Services\Billing\InvoiceService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class BillingWorkflowTest extends TestCase
{
    use RefreshDatabase;

    public function test_invoice_moves_from_running_to_overdue_and_paid(): void
    {
        $tenant = Tenant::create(['tenant_code' => 'BILL-A', 'tenant_name' => 'Billing Tenant']);
        $owner = User::factory()->create(['access_level' => 'tenant_owner']);
        $owner->userTenants()->create(['tenant_id' => $tenant->id, 'is_default' => true]);
        $profile = app(BillingProfileService::class)->create([
            'name' => 'Bulanan Reguler',
            'invoice_day' => 1,
            'send_day' => 2,
            'warning_day' => 10,
            'isolation_day' => 15,
            'tax_type' => 'exclusive',
            'tax_rate' => 11,
        ], $owner, $tenant->id);
        $customer = Customer::create([
            'tenant_id' => $tenant->id,
            'customer_code' => 'CUST-BILL',
            'name' => 'Customer Billing',
            'status' => 'active',
            'billing_profile_id' => $profile->id,
        ]);
        $service = app(InvoiceService::class);
        $invoice = $service->create([
            'customer_id' => $customer->id,
            'period_start' => now()->startOfMonth()->toDateString(),
            'period_end' => now()->endOfMonth()->toDateString(),
            'issue_date' => now()->subDays(20)->toDateString(),
            'send_date' => now()->subDays(18)->toDateString(),
            'warning_date' => now()->subDays(10)->toDateString(),
            'isolation_date' => now()->subDay()->toDateString(),
            'subtotal' => 100000,
        ], $owner, $tenant->id);

        $this->assertSame('overdue', $invoice->status);
        $this->assertSame('111000.00', $invoice->total);
        $this->assertCount(1, $service->list('overdue', ['per_page' => 10], $owner, $tenant->id));

        $paid = $service->pay($invoice, ['amount' => 111000, 'payment_method' => 'cash'], $owner);

        $this->assertSame('paid', $paid->status);
        $this->assertSame('paid', $paid->payment_status);
        $this->assertSame('0.00', $paid->balance);
        $this->assertCount(1, $service->list('paid', ['per_page' => 10], $owner, $tenant->id));
    }

    public function test_profile_and_invoice_lists_are_tenant_scoped(): void
    {
        $tenantA = Tenant::create(['tenant_code' => 'BILL-LA', 'tenant_name' => 'Billing A']);
        $tenantB = Tenant::create(['tenant_code' => 'BILL-LB', 'tenant_name' => 'Billing B']);
        $owner = User::factory()->create(['access_level' => 'tenant_owner']);
        $owner->userTenants()->create(['tenant_id' => $tenantA->id, 'is_default' => true]);
        $master = User::factory()->create(['is_master' => true, 'access_level' => 'master_admin']);
        $service = app(BillingProfileService::class);
        $base = ['invoice_day' => 1, 'send_day' => 2, 'warning_day' => 10, 'isolation_day' => 15, 'tax_type' => 'non_tax'];
        $service->create([...$base, 'name' => 'Profile A'], $owner, $tenantA->id);
        $service->create([...$base, 'name' => 'Profile B', 'tenant_id' => $tenantB->id], $master, null);

        $result = $service->list(['per_page' => 100], $owner, $tenantA->id);

        $this->assertSame(['Profile A'], $result->getCollection()->pluck('name')->all());
    }
}
