<?php

use App\Livewire\Admin\CustomerDetail;
use App\Models\Customer;
use App\Models\Instance;
use App\Models\Invoice;
use App\Models\InvoiceSeries;
use App\Models\Order;
use App\Models\Subscription;
use App\Support\CompanyProfile;
use Livewire\Livewire;

/**
 * The customer page shows the customer.
 *
 * The first version was a compose box with three lists under it, and the
 * complaint was exactly right: it showed nothing ABOUT the customer. An operator
 * on the phone needs the address, the package, whether the last invoice was paid
 * and what was already said — and none of that was on the page.
 */
beforeEach(function () {
    CompanyProfile::put([
        'name' => 'CluPilot GmbH', 'address' => 'Musterstraße 1',
        'postcode' => '1010', 'city' => 'Wien', 'vat_id' => 'ATU12345678',
    ]);

    $this->customer = Customer::factory()->create([
        'name' => 'Beispiel GmbH',
        'contact_name' => 'Bea Berger',
        'phone' => '+43 1 2345678',
        'billing_address' => "Musterstraße 2\n1020 Wien",
        'vat_id' => 'ATU99999999',
        'customer_type' => Customer::TYPE_BUSINESS,
    ]);
});

it('opens on the details', function () {
    Livewire::actingAs(operator('Owner'), 'operator')
        ->test(CustomerDetail::class, ['uuid' => $this->customer->uuid])
        ->assertSet('tab', 'overview')
        // The things somebody on the phone needs first.
        ->assertSee('Bea Berger')
        ->assertSee('+43 1 2345678')
        ->assertSee('ATU99999999')
        ->assertSee('1020 Wien')
        ->assertSee(__('customer_detail.type_business'));
});

it('remembers the tab across a reload, because it is in the URL', function () {
    Livewire::withQueryParams(['tab' => 'billing'])
        ->actingAs(operator('Owner'), 'operator')
        ->test(CustomerDetail::class, ['uuid' => $this->customer->uuid])
        ->assertSet('tab', 'billing')
        ->assertSee(__('customer_detail.invoices'));
});

it('falls back to the first tab when the URL names one that does not exist', function () {
    Livewire::withQueryParams(['tab' => 'wat'])
        ->actingAs(operator('Owner'), 'operator')
        ->test(CustomerDetail::class, ['uuid' => $this->customer->uuid])
        ->assertSet('tab', 'overview');
});

it('says a customer nobody asked is treated as a consumer', function () {
    // Not cosmetic: it decides whether a withdrawal right exists at all, and the
    // page must not let "nobody asked" read as "business".
    $unknown = Customer::factory()->create(['customer_type' => null]);

    Livewire::actingAs(operator('Owner'), 'operator')
        ->test(CustomerDetail::class, ['uuid' => $unknown->uuid])
        ->assertSee(__('customer_detail.type_unknown'));
});

it('shows the contract the customer is owed, with its own frozen figures', function () {
    // The contract's own price, not today's catalogue: a price rise does not
    // reach back into what somebody already bought.
    Subscription::factory()->plan('team')->create([
        'customer_id' => $this->customer->id,
        'status' => 'active',
    ]);

    Livewire::withQueryParams(['tab' => 'package'])
        ->actingAs(operator('Owner'), 'operator')
        ->test(CustomerDetail::class, ['uuid' => $this->customer->uuid])
        ->assertSee(__('billing.plan.team'))
        ->assertSee('85 GB')           // team's quota
        ->assertSee(__('customer_detail.price'));
});

it('shows the machine, and says so plainly when there is none', function () {
    Livewire::withQueryParams(['tab' => 'package'])
        ->actingAs(operator('Owner'), 'operator')
        ->test(CustomerDetail::class, ['uuid' => $this->customer->uuid])
        ->assertSee(__('customer_detail.no_contract'));

    Subscription::factory()->plan('start')->create(['customer_id' => $this->customer->id, 'status' => 'active']);
    Instance::factory()->create([
        'customer_id' => $this->customer->id,
        'subdomain' => 'kanzlei-berger',
        'status' => 'active',
    ]);

    Livewire::withQueryParams(['tab' => 'package'])
        ->actingAs(operator('Owner'), 'operator')
        ->test(CustomerDetail::class, ['uuid' => $this->customer->uuid])
        ->assertSee('kanzlei-berger');
});

it('shows what was invoiced and what was bought, which are two questions', function () {
    // An order is a purchase; an invoice is a document about one. A customer
    // asking "was das schon verrechnet?" is asking about the second.
    InvoiceSeries::query()->firstOrCreate(
        ['kind' => 'invoice'],
        ['name' => 'Rechnungen', 'prefix' => 'RE', 'active' => true],
    );

    Order::factory()->create([
        'customer_id' => $this->customer->id,
        'plan' => 'start',
        'amount_cents' => 4900,
        'status' => 'paid',
    ]);

    Invoice::create([
        'invoice_series_id' => InvoiceSeries::query()->first()->id,
        'customer_id' => $this->customer->id,
        'number' => 'RE-2026-0007',
        'number_year' => 2026,
        'number_sequence' => 7,
        'issued_on' => now()->toDateString(),
        'due_on' => now()->addDays(14)->toDateString(),
        'snapshot' => ['meta' => ['number' => 'RE-2026-0007']],
        'net_cents' => 4900,
        'tax_cents' => 980,
        'gross_cents' => 5880,
        'currency' => 'EUR',
    ]);

    Livewire::withQueryParams(['tab' => 'billing'])
        ->actingAs(operator('Owner'), 'operator')
        ->test(CustomerDetail::class, ['uuid' => $this->customer->uuid])
        ->assertSee('RE-2026-0007')
        ->assertSee('58,80')
        ->assertSee(__('customer_detail.orders'));
});

it('offers writing last, because it is what you do after reading', function () {
    $tabs = CustomerDetail::TABS;

    expect($tabs[0])->toBe('overview')
        ->and(end($tabs))->toBe('compose');

    // Every tab has a label, or the bar reads "customer_detail.tab.x".
    foreach ($tabs as $tab) {
        expect(__('customer_detail.tab.'.$tab))->not->toBe('customer_detail.tab.'.$tab);
    }
});

it('does not print a lang key at anybody', function () {
    // The badge read "customers.status.active" once. A key with no file behind
    // it renders as itself and Laravel says nothing about it.
    $page = Livewire::actingAs(operator('Owner'), 'operator')
        ->test(CustomerDetail::class, ['uuid' => $this->customer->uuid]);

    $page->assertDontSee('customers.status.')
        ->assertDontSee('customer_detail.tab.')
        ->assertSee(__('admin.status.active'));
});
