<?php

use App\Livewire\Settings;
use App\Models\Customer;
use App\Models\User;
use App\Services\Billing\TaxTreatment;
use Livewire\Livewire;

/**
 * Consumer or business, recorded rather than guessed.
 *
 * The flag did not exist and `vat_id` was being asked to stand in for it, which
 * it cannot: a business without a VAT number is an ordinary small business, and
 * a consumer with one does not exist. Three separate things turn on the answer —
 * the fourteen-day withdrawal right, the wording of the invoice, and reverse
 * charge — and only the last of them was ever answered at all.
 */
it('treats a customer nobody has asked as a consumer, and says so out loud', function () {
    $customer = Customer::factory()->create();

    expect($customer->customer_type)->toBeNull()
        ->and($customer->hasRecordedType())->toBeFalse()
        // The protective reading. Unknown is never business.
        ->and($customer->isConsumer())->toBeTrue()
        ->and($customer->isBusiness())->toBeFalse();
});

it('does not let a recorded consumer zero their own VAT with a verified number', function () {
    // Before the recorded type existed this was reverse charge: a verified
    // number was the whole test, so anybody who got one verified stopped being
    // charged VAT. Reverse charge is a business-to-business rule.
    $customer = Customer::factory()->consumer()->create([
        'vat_id' => 'DE811907980',
        'vat_id_verified_at' => now(),
        'vat_id_verified_value' => 'DE811907980',
    ]);

    $treatment = TaxTreatment::for($customer);

    expect($treatment->reverseCharge)->toBeFalse()
        ->and($treatment->rate)->toBe(0.2);
});

it('still applies reverse charge to a recorded business in another member state', function () {
    $customer = Customer::factory()->business()->create([
        'vat_id' => 'DE811907980',
        'vat_id_verified_at' => now(),
        'vat_id_verified_value' => 'DE811907980',
    ]);

    expect(TaxTreatment::for($customer)->reverseCharge)->toBeTrue();
});

it('changes nothing for a customer whose type has never been recorded', function () {
    // Deliberately NOT the protective default used for the withdrawal right.
    // Flipping every unasked business onto the domestic rate would put our
    // invoices in disagreement with contracts that are already running, and a
    // rate is not a right — see the note on TaxTreatment.
    $customer = Customer::factory()->create([
        'vat_id' => 'DE811907980',
        'vat_id_verified_at' => now(),
        'vat_id_verified_value' => 'DE811907980',
    ]);

    expect($customer->hasRecordedType())->toBeFalse()
        ->and(TaxTreatment::for($customer)->reverseCharge)->toBeTrue();
});

it('lets a customer record the answer in the portal', function () {
    $customer = Customer::factory()->create(['name' => 'Frau Berger', 'email' => 'typ@example.test']);
    $user = User::factory()->create(['email' => $customer->email]);
    $customer->update(['user_id' => $user->id]);

    Livewire::actingAs($user)
        ->test(Settings::class)
        ->set('companyName', 'Frau Berger')
        ->set('customerType', Customer::TYPE_BUSINESS)
        ->call('saveProfile');

    expect($customer->refresh()->customer_type)->toBe(Customer::TYPE_BUSINESS);
});

it('never turns a recorded answer back into an unknown', function () {
    $customer = Customer::factory()->consumer()->create(['name' => 'Herr Weiss', 'email' => 'bleibt@example.test']);
    $user = User::factory()->create(['email' => $customer->email]);
    $customer->update(['user_id' => $user->id]);

    // Somebody saves the company block without touching this field. That must
    // not quietly demote a recorded consumer to "nobody asked" — and with it
    // the evidence that they were told about their withdrawal right.
    Livewire::actingAs($user)
        ->test(Settings::class)
        ->set('companyName', 'Herr Weiss')
        ->set('customerType', '')
        ->call('saveProfile');

    expect($customer->refresh()->customer_type)->toBe(Customer::TYPE_CONSUMER);
});

it('refuses a customer type that is neither answer', function () {
    $customer = Customer::factory()->consumer()->create(['name' => 'Herr Weiss', 'email' => 'ungueltig@example.test']);
    $user = User::factory()->create(['email' => $customer->email]);
    $customer->update(['user_id' => $user->id]);

    Livewire::actingAs($user)
        ->test(Settings::class)
        ->set('companyName', 'Herr Weiss')
        ->set('customerType', 'charity')
        ->call('saveProfile')
        ->assertHasErrors('customerType');

    expect($customer->refresh()->customer_type)->toBe(Customer::TYPE_CONSUMER);
});
