<?php

namespace App\Livewire\Portal;

use App\Domain\Financial\Models\Invoice;
use App\Domain\Participant\Models\Participant;
use App\Livewire\Portal\Concerns\PortalScreen;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Locked;
use Livewire\Attributes\Title;
use Livewire\Component;

/**
 * One invoice, with the line items frozen as they were issued.
 *
 * The invoice arrives by route-model binding on its uuid and is re-authorised
 * against the account's own participants — a route parameter is a browser input
 * like any other. The id is `#[Locked]` on top of that: in Livewire v4 a plain
 * public property is settable from the page, so a check in mount() that is not
 * repeated in render() is decoration.
 */
#[Layout('layouts.portal')]
#[Title('الفاتورة')]
class PortalInvoice extends Component
{
    use PortalScreen;

    #[Locked]
    public int $invoiceId;

    public function mount(string $invoice): void
    {
        $this->authorizePortal();

        $found = Invoice::where('uuid', $invoice)->firstOrFail();

        $this->assertOwned($found);

        $this->invoiceId = $found->id;
    }

    public function render()
    {
        $invoice = Invoice::with(['items', 'payments'])->findOrFail($this->invoiceId);

        // Re-checked here, not only in mount(): ownership can change between
        // requests, and this is the query the page actually renders from.
        $this->assertOwned($invoice);

        return view('livewire.portal.portal-invoice', [
            'invoice' => $invoice,
            'canPay' => $invoice->billable_type === Participant::class
                && $this->portal()->mayPayFor((int) $invoice->billable_id),
        ]);
    }

    private function assertOwned(Invoice $invoice): void
    {
        abort_unless(
            $invoice->billable_type === Participant::class
            && in_array((int) $invoice->billable_id, $this->familyParticipantIds(), true),
            403
        );
    }
}
